2019-11-28 16:18:36 u011501388 阅读数 53
  • 深度学习框架Tensorflow案例实战视频课程

    深度学习框架Tensorflow案例实战视频培训课程概况: Tensorflow是谷歌开源的深度学习(包括机器学习)框架,伴随着人工智能业的兴盛其大名早已响彻云霄。本课程从Tensorflow安装开始讲起,从基本计算结构到深度学习各大神经网络,全程案例代码实战,一步步带大家入门如何使用深度学习框架Tensorflow,玩转Tensorflow模型训练、等所有知识点。

    30275 人正在学习 去看看 唐宇迪

PyTorch深度学习框架可以利用GPU加速网络训练,网络太深,参数太多的话,很可能在利用GPU训练网络的时候导致GPU显存不够,无法继续训练。GPU的显存大小几乎与其价格成正比,显存越大,也就越贵。但是为了利用GPU训练深度学习网络模型,可能需要大显存的显卡,比如直接买一个1080ti,显存为11G,但是也可以退而求其次,买两个1070ti,总显存为16G,似乎更划算。那么,单机多卡(一台机器配置多个GPU)情况下,在PyTorch框架下怎样训练模型呢?在PyTorch 1.0之后,可以利用多GPU进行网络模型训练。

1. 第一种情况,利用单机多卡对模型进行并行GPU处理(本人当时的需求为一个gtx 1070ti显存为8G,训练模型时出现超出显存的错误,所以又加装了一个gtx 1070ti显卡,这样总显存为16G,够用啦)。

model = torch.nn.DataParallel(model, device_ids=[0, 1]).cuda()
output = model(input)

class torch.nn.DataParallel(module, device_ids=None, output_device=None, dim=0),通过device_ids参数可以指定在哪些GPU上进行优化,output_device指定输出到哪个GPU上。

DataParallel并行的方式,是将输入一个batch的数据均分成多份,分别送到对应的GPU进行计算,各个GPU得到的梯度累加。与Module相关的所有数据也都会以浅复制的方式复制多份,在此需要注意,在module中属性应该是只读的。

if torch.cuda.device_count() > 1:
  model = nn.DataParallel(model)
 
if torch.cuda.is_available():
   model.cuda()

2,。 第二种情况,利用多机多卡进行分布式训练。torch.nn.parallel.DistributedDataParallel可以实现单机多卡和多机多卡的分布式训练。对于单机多卡,利用torch.nn.parallel.DistributedDataParallel对模型进行训练,每个GPU独立执行一个BatchSize的数据,如果单卡显存太小,仍然会出现显存不够的错误,导致模型无法继续训练。启动方式如下:

torch.distributed.init_process_group(backend='nccl', world_size=4, rank=, init_method='...') 
model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[i], output_device=i)

下面是关于torch.nn.DataParallel与torch.nn.parallel.DistributedDataParallel的启动对比:

    if args.distributed:
        # For multiprocessing distributed, DistributedDataParallel constructor
        # should always set the single device scope, otherwise,
        # DistributedDataParallel will use all available devices.
        if args.gpu is not None:
            torch.cuda.set_device(args.gpu)
            model.cuda(args.gpu)
            # When using a single GPU per process and per
            # DistributedDataParallel, we need to divide the batch size
            # ourselves based on the total number of GPUs we have
            args.batch_size = int(args.batch_size / ngpus_per_node)
            model = torch.nn.parallel.DistributedDataParallel(model, device_ids=[args.gpu])
        else:
            model.cuda()
            # DistributedDataParallel will divide and allocate batch_size to all
            # available GPUs if device_ids are not set
            model = torch.nn.parallel.DistributedDataParallel(model)
    elif args.gpu is not None:
        torch.cuda.set_device(args.gpu)
        model = model.cuda(args.gpu)
    else:
        # DataParallel will divide and allocate batch_size to all available GPUs
        if args.arch.startswith('alexnet') or args.arch.startswith('vgg'):
            model.features = torch.nn.DataParallel(model.features)
            model.cuda()
        else:
            model = torch.nn.DataParallel(model).cuda()

 

参考:

1. pytorch 多GPU训练总结(DataParallel的使用)

2. PyTorch使用并行GPU处理数据

3. Pytorch中多GPU训练指北

4. [深度学习] 分布式Pytorch 1.0介绍(三)

5. PyTorch分布式训练简介

 

 

2017-12-23 06:41:49 Uwr44UOuQcNsUQb60zk2 阅读数 3172
  • 深度学习框架Tensorflow案例实战视频课程

    深度学习框架Tensorflow案例实战视频培训课程概况: Tensorflow是谷歌开源的深度学习(包括机器学习)框架,伴随着人工智能业的兴盛其大名早已响彻云霄。本课程从Tensorflow安装开始讲起,从基本计算结构到深度学习各大神经网络,全程案例代码实战,一步步带大家入门如何使用深度学习框架Tensorflow,玩转Tensorflow模型训练、等所有知识点。

    30275 人正在学习 去看看 唐宇迪
在深度学习领域,对于具有上百万个连接的多层深度神经网络(DNN),现在往往通过随机梯度下降(SGD)算法进行常规训练。许多人认为,SGD 算法有效计算梯度的能力对于这种训练能力而言至关重要。但是,Uber 近日发布的五篇论文表明,神经进化(neuroevolution)这种利用遗传算法的神经网络优化策略,也是训练深度神经网络解决强化学习(RL)问题的有效方法。




Uber 涉及领域广泛,其中许多领域都可以利用机器学习改进其运作。开发包括神经进化在内的各种有力的学习方法将帮助 Uber 发展更安全、更可靠的运输方案。


遗传算法——训练深度学习网络的有力竞争者


我们惊讶地发现,通过使用我们发明的一种新技术来高效演化 DNN,一个极其简单的遗传算法(GA)可以训练含有超过 400 万参数的深度卷积网络,从而可以在像素级别上玩 Atari 游戏;而且,它能在许多游戏中比现代深度强化学习(RL)算法(例如 DQN 和 A3C)或进化策略(ES)表现得更好,同时由于更好的并行化能达到更快的速度。这个结果非常出乎意料:遗传算法并非基于梯度进行计算,没人能预料遗传算法能扩展到如此大的参数空间;而且,使用遗传算法却能与最先进的强化学习算法媲美、甚至超过强化学习,这在以前看来是根本不可能的。我们进一步表明,现代遗传算法的增强功能提高了遗传算法的能力,例如新颖性搜索(novelty research),它同样在 DNN 规模上发挥作用,且能够促进对于欺骗性问题(存在挑战性局部最优的问题)的探索。要知道,这些欺骗性问题通常对奖励最优化算法形成障碍,例如 Q 学习(DQN)、策略梯度算法(A3C)、进化策略(ES)以及遗传算法。



左:遗传算法在 Frostbite 中得分 10500。DQN、AC3 和 ES 的得分均未超过 1000;右:遗传算法在 Asteroids 也表现得很好。它的平均表现超越了 DQN 和 ES,但没有超过 A3C。


通过梯度计算的安全突变


在论文「Safe Mutations for Deep and Recurrent Neural Networks through Output Gradients」中,我们展示了如何将神经进化和梯度相结合,以提高循环神经网络和深度神经网络的进化能力。这种方法可以使上百层的深度神经网络成功进化,远远超过了以前的神经进化方法所展示的可能性。我们通过计算网络输出关于权重的梯度(即,和在传统深度学习中使用误差梯度不同)来实现这一点,使得在随机突变的校准过程中,对最敏感的变量(相比其他变量而言)进行更加精细的处理,从而解决大型网络中随机变量的一个主要问题。



这两个动画展示了用于解决迷宫问题的单个网络的一批突变(左下角是起点,左上角是终点)。一般的突变大多不能解决这个问题,但是安全突变很大程度地在产生多样性的同时保留了解决问题的能力,表明了安全突变的显著优势。


ES 如何与 SGD 联系起来?


我们的论文对 A Visual Guide to Evolution Strategies(参见「从遗传算法到 OpenAI 新方向:进化策略工作机制全解」)进行了补充和完善。这是由 OpenAI 团队首先提出的想法(https://blog.openai.com/evolution-strategies/),即 ES 的变型——神经进化——可以在深度强化学习任务中竞争性地优化深度神经网络。但是,迄今为止,这个结果有没有更广泛的应用仍然只是猜想。通过进一步创新 ES,我们通过一个综合研究「On the Relationship Between the OpenAI Evolution Strategy and Stochastic Gradient Descent」深入了解 ES 和 SGD 的关联,探索 ES 梯度近似实际上和在 MNIST 中通过 SGD 在每个 mini-batch 上计算的的最优梯度的联系有多紧密,以及这种近似如何导致了优越的性能。我们发现,如果提供足够的计算来改善梯度近似,ES 能在 MNIST 上实现 99% 的准确率,这暗示着 ES 何以愈发成为深度强化学习的有力竞争者——因为在并行计算增加时,还没有方法能获得完美的梯度信息。


ES 不只是传统的有限差分


为了增加理解,一个伴随性研究「ES Is More Than Just a Traditional Finite-Difference Approximator」经验地证实,ES(具有足够大的扰动尺寸参数)的行为与 SGD 表现得有差别。这是因为 ES 优化的是一代策略群体(由概率分布描述,即搜索空间中的「云」)的预期回报,但 SGD 仅为单一的策略(搜索空间中的「点」)优化回报。这种变化使得 ES 可以访问搜索空间的不同区域,无论是好是坏(这两种情况都被示出)。对每代的参数扰动进行优化的另一个结果是,ES 获得了鲁棒性,这是 SGD 不能做到的。强调 ES 优化每代的参数这一做法,同样强调了 ES 和贝叶斯算法中的有趣联系。



对步行者进行重量的随机扰动,TRPO 训练的步行者会产生明显的不稳定步态,而 ES 进化的步行者步态显得更加稳定。初始的训练步行者位于每个 9 帧合成的中心(绿框)。



传统的有限差分(梯度下降)不能跨越低适合度(fitness)的窄缝,但 ES 能容易地穿过并寻找另一侧的更高适合度。



ES 会在高适合度的窄缝中慢慢停止,但传统的有限差分(梯度下降)会毫无停顿地通过相同的路径。这与前面的动画一起说明了两种不同方法的区别和权衡。


加强对 ES 的探索


深度神经进化有一个令人兴奋的结果:之前为神经进化开发的工具集,现在成为了加强深度神经网络训练的候选者。我们通过引入新的算法「Improving Exploration in Evolution Strategies for Deep Reinforcement Learning via a Population of Novelty-Seeking Agents」进行探索,这种算法将 ES 的优化能力和可扩展性与神经进化所独有的、通过群体激励将不同智能体区别开的促进强化学习领域的探索结合起来。这种基于群体的探索有别于强化学习中单一智能体传统,包括最近在深度强化学习领域的探究工作。我们的实验表明,通过增加这种新的探索方式,能够提高 ES 在许多需要探索的领域(包括一些 Atari 游戏和 Mujoco 模拟器中的类人动作任务)的性能,从而避免欺骗性的局部最优。



通过使用我们的超参数,ES 迅速收敛到局部最优,即不需要再次吸入氧气,因为吸入氧气暂时不能获得奖励。但是,通过探索,它学会了如何吸入氧气,从而在未来获得更高的奖励。请注意,Salimans et al. 2017 并没有报道 ES,根据他们的超参数,他们能够实现特定的局部最优。但是,就像我们所展示的,没有 ES,它很容易无限期地困在某些局部最优处(而那个探索能够帮助它跳出局部最优)。



智能体需要学着跑得尽可能远。ES 从未学过避免欺骗性的陷阱。但是,通过添加一个探索压力,其中一个学会了绕过陷阱。


结论


对有志于转向深度神经网络的神经进化研究人员,有几个重要因素值得考虑:首先,这种类型的实验需要的计算量比以前更多;对于这些新论文中的实验,我们经常需要运行成百上千个同步 CPU。但是,对 GPU 或 CPU 的需求不应该被视为一个负担;从长远来看,面对即将到来的世界,向大规模并行计算中心的规模变化也许意味着神经进化最能利用未来的优势。


新的结果与之前在低维神经进化中观察到的结果有显著差异。它们有效推翻了多年来的直觉,特别是对高维度探索的潜力的启发。正如在深度学习中发现的那样,在复杂性的某些阈值之上,在高维度的搜索似乎变得更加容易,因为它不易受到局部最优的影响。虽然深度学习已经对这种思维方式非常熟悉,但它的含义最近才在神经进化当中开始被理解。


神经进化的再度兴起,是旧算法与当代计算量相结合产生惊人成果的另一个例子。神经进化的可行性非常有趣,因为在神经进化社区中开发的许多技术可以立即在 DNN 规模上变得可行,它们每个都提供了不同工具以解决具有挑战性的问题。此外,正如我们的论文所展示的,神经进化搜索与 SGD 不同,因此为机器学习工具箱提供了有趣的替代方法。我们想知道,深度神经进化是否会像深度学习一样经历复兴。如果是这样,2017 年可能标志着这个时代的开始,我们也非常期待未来会发生什么!


下面是我们今天发布的 5 篇论文及关键发现的总结:


Deep Neuroevolution: Genetic Algorithms are a Competitive Alternative for Training Deep Neural Networks for Reinforcement Learning
  • 用简单、传统、基于群体的遗传算法演化 DNN,在困难的深度强化学习问题上表现良好。在 Atari 游戏中,遗传算法表现良好,与 ES 以及基于 Q 学习(DQN)和政策梯度算法(A3C)的深度强化学习算法表现相当。
  • 「深度遗传算法(Deep GA)」成功演化了有着 400 万自由参数的网络,这是通过一个传统的进化算法演化的最大的神经网络。
  • 表明了一个有趣的事实:在某些情况下,根据梯度更新不是优化性能的最佳选择。
  • 将 DNN 和新颖性搜索(Novelty Search)相结合,这种探索算法被设计用于欺骗性任务和稀疏奖励函数,以解决欺骗性的高维问题。其中,奖励最大化算法(例如 GA 和 ES)都在这类问题中失败了。
  • 表明 Deep GA 的并行度优于 DQN、A3C 和 ES,因此运行比它们都快。可实现当前最先进的紧凑编码技术,只用几千字节就可以表示百万量级参数的 DNN。
  • 包含在 Atari 中随机搜索的结果。令人惊讶的是,在一些游戏中,随机搜索大大优于 DQN、A3C 和 ES,不过它从没有超过 GA。



令人惊讶的是,在一个 DNN 中,随机搜索能比 DQN、A3C 和 ES 在 Frostbite 游戏中表现得更好,但是还是不能超过 GA。


Safe Mutations for Deep and Recurrent Neural Networks through Output Gradients
  • 通过测量网络敏感性改变特定连接权重,基于梯度的安全突变(SM-G)极大提高了大型深度循环网络突变的效率。
  • 计算关于权重的「输出」梯度,而非如常规深度学习中误差或损失函数的梯度,以允许随机但安全的搜索步骤。
  • 这两种安全突变都不需要在领域当中的额外实验或展示。
  • 结果:深层神经网络(超过 100 层)和大型循环网络现在只能通过 SM-G 的各种变形有效演化。

On the Relationship Between the OpenAI Evolution Strategy and Stochastic Gradient Descent
  • 通过比较不同情况下由 ES 计算的近似梯度和由 SGD 在 MNIST 中计算的准确梯度探究 ES 和 SGD 的关系。
  • 开发快速代理,预测不同群体规模的 ES 预期表现。
  • 介绍并演示不同加速和改善 ES 性能的方法。
  • 有限扰动 ES(Limited perturbation ES)显著加快了在并行基础设施上的执行速度。
  • 「No-mini-batch ES」把针对 SGD 设计 mini-batch 传统替换为适用于 ES 的不同方法,从而改进梯度估计:这是这样一种算法,它在算法的每次迭代中,将整个训练批的一个随机子集分配给 ES 群体当中的每个成员。这种专用于 ES 的方法在等效计算的情况下提供了更好的准确度,且学习曲线甚至比 SGD 更加平滑。
  • 「No-mini-batch ES」在测试运行中达到了 99% 的准确率,这是在本次监督学习任务中,进化方法的最佳报告性能。
  • 总体上有助于说明为什么 ES 能在强化学习中成为有力竞争者。通过搜索域的实验获得的梯度信息与监督学习的性能目标相比,信息量更少。

ES Is More Than Just a Traditional Finite Difference Approximator

  • 强调 ES 和传统有限差分方法之间的重要区别,即 ES 优化的是最佳解决方案的分布函数(而非单个最佳的解决方案)。
  • 一个有趣的结果:由 ES 发现的解决方案倾向于在参数扰动上保持鲁棒性。例如,我们表明 ES 的仿人类行走解决方案比 GA 和 TRPO 实现的类似解决方案对参数扰动的鲁棒性更强。
  • 另一个重要结果:ES 可能可以解决传统方法困扰的一些问题,反之亦然。通过简单的例子说明 ES 和传统梯度跟随之间的不同动力学。

Improving Exploration in Evolution Strategies for Deep Reinforcement Learning via a Population of Novelty-Seeking Agents

  • 增加在 ES 中鼓励深度探索的能力。
  • 表明通过探究不同代的智能体群体并用于促进小规模进化神经网络中的探索性算法——特别是新颖性搜索(NS)和质量多样性(QD)算法——能与 ES 结合,从而改善在稀疏或欺骗性深度强化学习任务当中的表现。
  • 证实由此产生的新算法——NS-ES 和一个称为 NSR-ES 的 QD-ES 版本——能够避免 ES 所遭遇的局部最优问题,从而在某些任务中达到高性能。这些任务包括,模拟机器人学习绕过欺骗性陷阱达到高性能,以及 Atari 游戏当中的高维像素任务。
  • 将这个基于群体的搜索算法系列添加到深度强化学习工具箱中。 


原文链接:https://eng.uber.com/deep-neuroevolution/


2019-05-21 14:02:37 supe_king 阅读数 249
  • 深度学习框架Tensorflow案例实战视频课程

    深度学习框架Tensorflow案例实战视频培训课程概况: Tensorflow是谷歌开源的深度学习(包括机器学习)框架,伴随着人工智能业的兴盛其大名早已响彻云霄。本课程从Tensorflow安装开始讲起,从基本计算结构到深度学习各大神经网络,全程案例代码实战,一步步带大家入门如何使用深度学习框架Tensorflow,玩转Tensorflow模型训练、等所有知识点。

    30275 人正在学习 去看看 唐宇迪

2019-3-20 20:17

问题:在训练YOLO-V2的目标检测模型时,使用resnet18的主网络架构,并利用其预训练权重,在训练的一段时间后,网络出现NAN值?

解决:经各方面验证发现,网络经过几次迭代之后,发生梯度爆炸,导致梯度更新之后,出现NAN值。网上查询了几种梯度爆炸的解决方式,例如什么减小学习率,残差网络,relu激活,bn层等。显然,这些方式,本模型中已经具备。还有一种方式就是利用tf.clip_by_value函数进行截断。截断分两种,一种是模型计算种出现除0的这种情况,对0值进行截断,另一种就是直接对梯度进行截断。我采用的是对梯度进行截断,因为本模型种没有除0的情况。实验表明,这种方式确实能够解决梯度爆炸的问题,但是对模型收敛的速度似乎有点影响。

  后来,收到其他博客的启发,想到冻结训练的方式。我冻结了预训练部分的权重,只训练初始化部分的权重,效果很明显,模型收敛很快,也没有出现NAN值。待模型的loss下降稳定之后,我再开启全局训练,不知道后期的情况如何......待更。。。

2019-3-20 22:35

接着上一个问题,当loss值稳定之后,我进行全局训练并没有出现NAN值,哈哈哈哈,问题解决!!!!!

2019-4-11 01:44

重点:第一,在训练一个回归任务的网络时,发现预测结果趋向于标签的均值,主要问题样本不均衡。第二,输入数据没有去中心化(输入数据全部大于零或小于零)时,模型的收敛速度明显小于输入已经去中心化数据(输入数据有大于零的值,也有小于零的值)。

2017-05-05 12:53:27 zchang81 阅读数 3769
  • 深度学习框架Tensorflow案例实战视频课程

    深度学习框架Tensorflow案例实战视频培训课程概况: Tensorflow是谷歌开源的深度学习(包括机器学习)框架,伴随着人工智能业的兴盛其大名早已响彻云霄。本课程从Tensorflow安装开始讲起,从基本计算结构到深度学习各大神经网络,全程案例代码实战,一步步带大家入门如何使用深度学习框架Tensorflow,玩转Tensorflow模型训练、等所有知识点。

    30275 人正在学习 去看看 唐宇迪

作者:wjmishuai

出处:http://blog.csdn.net/wjmishuai/article/details/50854162


一:下载训练集和测试集

测试集的下载地址:http://vis-www.cs.umass.edu/lfw/


二:利用linux脚本生成训练集

#!/bin/bash


#-----------------------------------------------------------------------------------------


#生成训练集和验证集
#made by 郭开


#-----------------------------------------------------------------------------------------


#保存图片的路径  
PATH=/media/gk/9ec75485-26b1-471f-9b7b-d18554ca3fdd/aa
echo "start..."
#遍历文件夹
for name in $PATH/webface_img/*;do
        var=0
#遍历文件夹中的图片
        for file_name in $name/*;do  
            var=$(($var+1));  
            str=$file_name  
            #保存图片路径
            str=${str#*img}  
            #保存图片lable  
            lable=${str#*/}  
            lable=${lable%%/*}  
            if [ "$var" = "1" ] || [ "$var" = "3" ] || [ "$var" = "5" ]; then  
            #验证集  
            echo $str" "$lable>>/home/gk/val.txt  
            else  
            #测试集  
            echo $str" "$lable>>/home/gk/train.txt  
            fi  
done  
done  
echo "Done."

生成的文件如下图:




三:将图片转换成LMDB格式

#!/usr/bin/env sh  


#-----------------------------------------------------------------------------------------  
  
  
# 将图片批量生成lmbd格式的数据存储
#made by 郭开  
  
  
#-----------------------------------------------------------------------------------------  
  
#保存生成的lmdb的目录  
EXAMPLE=/media/gk/9ec75485-26b1-471f-9b7b-d18554ca3fdd/aa/lmdb_webface
  
#train.txt和val.txt所在的目录
DATA=/home/gk
  
#转换图片的工具所在的目录  
TOOLS=/home/gk/caffe-master/build/tools  
  
#图片所在的目录
TRAIN_DATA_ROOT=/media/gk/9ec75485-26b1-471f-9b7b-d18554ca3fdd/aa/webface_img

VAL_DATA_ROOT=/media/gk/9ec75485-26b1-471f-9b7b-d18554ca3fdd/aa/webface_img
  
# 设置 RESIZE=true 可以把图片resize成想要的尺寸。
RESIZE=true
if $RESIZE; then
  RESIZE_HEIGHT=227
  RESIZE_WIDTH=227
else
  RESIZE_HEIGHT=0
  RESIZE_WIDTH=0
fi


if [ ! -d "$TRAIN_DATA_ROOT" ]; then
  echo "Error: TRAIN_DATA_ROOT is not a path to a directory: $TRAIN_DATA_ROOT"
  echo "Set the TRAIN_DATA_ROOT variable in create_imagenet.sh to the path" \
       "where the ImageNet training data is stored."
  exit 1
fi


if [ ! -d "$VAL_DATA_ROOT" ]; then
  echo "Error: VAL_DATA_ROOT is not a path to a directory: $VAL_DATA_ROOT"
  echo "Set the VAL_DATA_ROOT variable in create_imagenet.sh to the path" \
       "where the ImageNet validation data is stored."
  exit 1
fi


echo "Creating train lmdb..."


GLOG_logtostderr=1 $TOOLS/convert_imageset \
    --resize_height=$RESIZE_HEIGHT \
    --resize_width=$RESIZE_WIDTH \
    --shuffle \
    $TRAIN_DATA_ROOT \
    $DATA/train.txt \
    $EXAMPLE/train_lmdb


echo "Creating val lmdb..."


GLOG_logtostderr=1 $TOOLS/convert_imageset \
    --resize_height=$RESIZE_HEIGHT \
    --resize_width=$RESIZE_WIDTH \
    --shuffle \
    $VAL_DATA_ROOT \
    $DATA/val.txt \
    $EXAMPLE/val_lmdb


echo "Done."



四:计算图片的mean或者设置scale:0.00390625

#!/usr/bin/env sh  


#-----------------------------------------------------------------------------------------    
    
    
# 计算图像均值
#made by 郭开    
    
    
#-----------------------------------------------------------------------------------------    
#lmdb格式的文件所在的路径
EXAMPLE=/media/gk/9ec75485-26b1-471f-9b7b-d18554ca3fdd/aa/lmdb_webface
#均值文件保存的路径
DATA=/media/gk/44CA719BCA718A46  
#转换图片的工具所在的目录 
TOOLS=/home/gk/caffe-master/build/tools  
  
$TOOLS/compute_image_mean $EXAMPLE/train_lmdb \  
  $DATA/mean.binaryproto  
  
echo "Done."  



五:训练模型
./build/tools/caffe train --solver=models/bvlc_reference_caffenet/solver.prototxt

slover.prototxt
net: "/home/gk/caffe-master/examples/vgg/train.prototxt"
test_iter: 100
test_interval: 1000


base_lr: 0.001
lr_policy: "step"
gamma: 0.95
stepsize:  100000
momentum: 0.9
weight_decay: 0.0005
display: 100
max_iter:  5000000
snapshot:  50000
snapshot_prefix: "/home/gk/caffe-master/examples/DeepID/snapshot"
solver_mode: GPU
device_id:0
#debug_info: true

tarin.prototxt

name: "VGG_FACE_16_layers"
layer {
  top: "data_1"
  top: "label_1"
  name: "data_1"
  type: "Data"
  data_param {
    source: "/media/gk/9ec75485-26b1-471f-9b7b-d18554ca3fdd/aa/webface_lmdb/train"
    backend:LMDB
    batch_size: 128
  }
  transform_param {
     mean_file: "/media/gk/9ec75485-26b1-471f-9b7b-d18554ca3fdd/aa/webface_lmdb/mean.binaryproto"
     mirror: true
  }
  include: { phase: TRAIN }
}


layer {
  top: "data_1"
  top: "label_1"
  name: "data_1"
  type: "Data"
  data_param {
    source: "/media/gk/9ec75485-26b1-471f-9b7b-d18554ca3fdd/aa/webface_lmdb/val"
    backend:LMDB
    batch_size: 128
  }
  transform_param {
    mean_file: "/media/gk/9ec75485-26b1-471f-9b7b-d18554ca3fdd/aa/webface_lmdb/mean.binaryproto"
    mirror: true
  }
  include: { 
    phase: TEST 
  }
}


layers {
  bottom: "data"
  top: "conv1_1"
  name: "conv1_1"
  type: CONVOLUTION
  convolution_param {
    num_output: 64
    pad: 1
    kernel_size: 3
  }
}
layers {
  bottom: "conv1_1"
  top: "conv1_1"
  name: "relu1_1"
  type: RELU
}
layers {
  bottom: "conv1_1"
  top: "conv1_2"
  name: "conv1_2"
  type: CONVOLUTION
  convolution_param {
    num_output: 64
    pad: 1
    kernel_size: 3
  }
}
layers {
  bottom: "conv1_2"
  top: "conv1_2"
  name: "relu1_2"
  type: RELU
}
layers {
  bottom: "conv1_2"
  top: "pool1"
  name: "pool1"
  type: POOLING
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layers {
  bottom: "pool1"
  top: "conv2_1"
  name: "conv2_1"
  type: CONVOLUTION
  convolution_param {
    num_output: 128
    pad: 1
    kernel_size: 3
  }
}
layers {
  bottom: "conv2_1"
  top: "conv2_1"
  name: "relu2_1"
  type: RELU
}
layers {
  bottom: "conv2_1"
  top: "conv2_2"
  name: "conv2_2"
  type: CONVOLUTION
  convolution_param {
    num_output: 128
    pad: 1
    kernel_size: 3
  }
}
layers {
  bottom: "conv2_2"
  top: "conv2_2"
  name: "relu2_2"
  type: RELU
}
layers {
  bottom: "conv2_2"
  top: "pool2"
  name: "pool2"
  type: POOLING
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layers {
  bottom: "pool2"
  top: "conv3_1"
  name: "conv3_1"
  type: CONVOLUTION
  convolution_param {
    num_output: 256
    pad: 1
    kernel_size: 3
  }
}
layers {
  bottom: "conv3_1"
  top: "conv3_1"
  name: "relu3_1"
  type: RELU
}
layers {
  bottom: "conv3_1"
  top: "conv3_2"
  name: "conv3_2"
  type: CONVOLUTION
  convolution_param {
    num_output: 256
    pad: 1
    kernel_size: 3
  }
}
layers {
  bottom: "conv3_2"
  top: "conv3_2"
  name: "relu3_2"
  type: RELU
}
layers {
  bottom: "conv3_2"
  top: "conv3_3"
  name: "conv3_3"
  type: CONVOLUTION
  convolution_param {
    num_output: 256
    pad: 1
    kernel_size: 3
  }
}
layers {
  bottom: "conv3_3"
  top: "conv3_3"
  name: "relu3_3"
  type: RELU
}
layers {
  bottom: "conv3_3"
  top: "pool3"
  name: "pool3"
  type: POOLING
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layers {
  bottom: "pool3"
  top: "conv4_1"
  name: "conv4_1"
  type: CONVOLUTION
  convolution_param {
    num_output: 512
    pad: 1
    kernel_size: 3
  }
}
layers {
  bottom: "conv4_1"
  top: "conv4_1"
  name: "relu4_1"
  type: RELU
}
layers {
  bottom: "conv4_1"
  top: "conv4_2"
  name: "conv4_2"
  type: CONVOLUTION
  convolution_param {
    num_output: 512
    pad: 1
    kernel_size: 3
  }
}
layers {
  bottom: "conv4_2"
  top: "conv4_2"
  name: "relu4_2"
  type: RELU
}
layers {
  bottom: "conv4_2"
  top: "conv4_3"
  name: "conv4_3"
  type: CONVOLUTION
  convolution_param {
    num_output: 512
    pad: 1
    kernel_size: 3
  }
}
layers {
  bottom: "conv4_3"
  top: "conv4_3"
  name: "relu4_3"
  type: RELU
}
layers {
  bottom: "conv4_3"
  top: "pool4"
  name: "pool4"
  type: POOLING
  pooling_param {
    pool: MAX
    kernel_size: 2
    stride: 2
  }
}
layers {
  bottom: "pool4"
  top: "conv5_1"
  name: "conv5_1"
  type: CONVOLUTION
  convolution_param {
    num_output: 512
    pad: 1
    kernel_size: 3
  }
}
layers {
  bottom: "conv5_1"
  top: "conv5_1"
  name: "relu5_1"
  type: RELU
}
layers {
  bottom: "conv5_1"
  top: "conv5_2"
  name: "conv5_2"
  type: CONVOLUTION
  convolution_param {
    num_output: 512
    pad: 1
    kernel_size: 3
  }
}
layers {
  bottom: "conv5_2"
  top: "conv5_2"
  name: "relu5_2"
  type: RELU
}
layers {
  bottom: "conv5_2"
  top: "conv5_3"
  name: "conv5_3"
  type: CONVOLUTION
  convolution_param {
    num_output: 512
    pad: 1
    kernel_size: 3
  }
}

2017-03-03 14:21:52 qq_20259459 阅读数 4584
  • 深度学习框架Tensorflow案例实战视频课程

    深度学习框架Tensorflow案例实战视频培训课程概况: Tensorflow是谷歌开源的深度学习(包括机器学习)框架,伴随着人工智能业的兴盛其大名早已响彻云霄。本课程从Tensorflow安装开始讲起,从基本计算结构到深度学习各大神经网络,全程案例代码实战,一步步带大家入门如何使用深度学习框架Tensorflow,玩转Tensorflow模型训练、等所有知识点。

    30275 人正在学习 去看看 唐宇迪

本文为原创文章转载必须注明本文出处以及附上 本文地址超链接  以及 博主博客地址http://blog.csdn.net/qq_20259459  和 作者邮箱( jinweizhi93@gmai.com )。

(如果喜欢本文,欢迎大家关注我的博客或者动手点个赞,有需要可以邮件联系我)



接上一篇文章(阅读上一篇文章:http://blog.csdn.net/qq_20259459/article/details/54602056 



在介绍完MatConvNet相关的Code之后,现在开始介绍如何使用这个toolbox来训练自己的data。


首先我想介绍如何利用mnist的模型来训练自己的data。在网上我看到有很多人在用imagenet的模型来训练自己的数据,写的都很好,但是好像很少有人写mnist的模型所以我想写一下。当然后面也会更新imagenet相关的介绍。


在我自己学习使用的过程中我发现mnist的模型似乎并不可以使用长方形的input。否则在训练多类误差的过程中会出现维度的错误,当然我也认为是可以修改的,不过与其修改不如直接使用imagenet模型更为便捷。


训练自己的数据的时候,有一些问题需要注意,否则没法运行。

一、input不一定要为正方形,但是在softmax层的INPUT需要为1*1的数据。

二、根据input的大小需要增加layers以确保最后的softmax的数据size为1*1。

三、所需要训练的数据必须有完整的test和train的部分,可自己分配一般比例为3比7。

四、每次训练结束之后如需改变input需要手动删除以创建的train的结构体。

五、在创建label的时候一定要注意test和train的需要分开以免调用的时候出现错位影响结果。

六、当运行可以的时候要做的就是调整,需要通过改变相关的变数和网络的层数以得到最佳的结果。



今天我先写一下通过改变mnist的大小作为自己的新的数据来尝试第一次训练,以证明程序可行性。

主要Code(尝试扩大2倍):

function cnn_mnist_NNclass(varargin)

warning off

% CNN_MNIST  Demonstrated MatConNet on MNIST

%% 运行初始化CNN网络
% run( fullfile(fileparts(mfilename('fullpath')), '../matlab/vl_setupnn.m') ) ;
run('C:\Users\Desktop\matconvnet-1.0-beta23\matconvnet-1.0-beta23\matlab/vl_setupnn.m') ;


%% 初始化网络相关数据
opts.dataDir = 'data/mnist' ;                               %   data的标签的路径
opts.expDir = 'data/mnist-baseline' ;                       %   data的路径
opts.imdbPath = fullfile(opts.expDir, 'imdb.mat');          %   data的fullfile=data/mnist-baseline/imdb.mat
opts.train.batchSize = 100 ;                                %   选择batch大小
opts.train.numEpochs = 100 ;                                %   选择epoch个数
opts.train.continue = true ;                                %   选择判断条件
% opts.train.useGpu = true ; 
opts.train.gpus = []; 
% opts.train.gpus = 1;                                        %   选择是否使用GPU
opts.train.learningRate = 0.001 ;                           %   选择CNN学习率
opts.train.expDir = opts.expDir ;                           %   训练数据的保存位置
opts = vl_argparse(opts, varargin);                         %   调用vl_argparse函数
opts.train.subsetSize = 1e4;                                %   statsogk 子图的大小


%% 准备数据
% --------------------------------------------------------------------
%                                                         Prepare data
% --------------------------------------------------------------------

if exist(opts.imdbPath)                                     %   如果存在imdb.mat
  imdb = load(opts.imdbPath) ;                              %       载入数据
else                                                        %   如果不存在
  imdb = getMnistImdb(opts) ;                               %       获得数据
  mkdir(opts.expDir) ;                                      %       调用mkdir
  save(opts.imdbPath, '-struct', 'imdb') ;                  %       保存在路径下
end

% Use a subset of the images for faster training. 
if opts.train.subsetSize > 0                                %   如果子图大小大于0
    imdb = getSubset(imdb,opts);                            %       调用getSubset
end


%% 定义CNN网络
% Define a network similar to LeNet
f=1/100 ;                                                                   %   初始化一个f
net.layers = {} ;                                                           %      初始化一个空layer
net.layers{end+1} = struct('type', 'conv', ...                              %%   定义C1层
                           'filters', f*randn(5,5,1,20, 'single'), ...      %      filter大小(5*5*1)*20
                           'biases', zeros(1, 20, 'single'), ...            %   
                           'stride', 1, ...                                 %      移动为1
                           'pad', 0) ;                                      %      没有pad
net.layers{end+1} = struct('type', 'pool', ...                              %%   定义pooling层
                           'method', 'max', ...                             %       pooling类型为max
                           'pool', [2 2], ...                               %       filter大小为2*2
                           'stride', 2, ...                                 %       移动为2
                           'pad', 0) ;                                      %       没有pad
net.layers{end+1} = struct('type', 'conv', ...                              %%   定义C2层
                           'filters', f*randn(5,5,20,50, 'single'),...
                           'biases', zeros(1,50,'single'), ...
                           'stride', 1, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'pool', ...                              %%   定义pooling层
                           'method', 'max', ...
                           'pool', [2 2], ...
                           'stride', 2, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'conv', ...                              %%   定义C3层
                           'filters', f*randn(4,4,50,100, 'single'),...
                           'biases', zeros(1,100,'single'), ...
                           'stride', 1, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'pool', ...                              %%   定义pooling层
                           'method', 'max', ...
                           'pool', [2 2], ...
                           'stride', 2, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'conv', ...                              %%   定义C2层
                           'filters', f*randn(3,3,100,500, 'single'),...
                           'biases', zeros(1,500,'single'), ...
                           'stride', 1, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'pool', ...                              %%   定义pooling层
                           'method', 'max', ...
                           'pool', [2 2], ...
                           'stride', 2, ...
                           'pad', 0) ;
% % % % net.layers{end+1} = struct('type', 'conv', ...                              %%   定义C2层
% % % %                            'filters', f*randn(3,3,500,1000, 'single'),...
% % % %                            'biases', zeros(1,1000,'single'), ...
% % % %                            'stride', 1, ...
% % % %                            'pad', 0) ;
% % % % net.layers{end+1} = struct('type', 'pool', ...                              %%   定义pooling层
% % % %                            'method', 'max', ...
% % % %                            'pool', [2 2], ...
% % % %                            'stride', 2, ...
% % % %                            'pad', 0) ;
net.layers{end+1} = struct('type', 'relu') ;                                %%  定义relu层

net.layers{end+1} = struct('type', 'conv', ...                              %%  定义FC层
                           'filters', f*randn(1,1,500,10, 'single'),...     %       大小为1*1的全连接,厚度为500,10次
                           'biases', zeros(1,10,'single'), ...              %       
                           'stride', 1, ...                                 %       移动为1
                           'pad', 0) ;                                      %       没有pad
net.layers{end+1} = struct('type', 'softmaxloss') ;                         %   定义SMFC


%% Train 部分
% --------------------------------------------------------------------
%                                                                Train
% --------------------------------------------------------------------

% Take the mean out and make GPU if needed
imdb.images.data = bsxfun(@minus, imdb.images.data, mean(imdb.images.data,4)) ;     %   减去mean值
% if opts.train.useGpu
if opts.train.gpus                                                                  %   如果使用GPU
    imdb.images.data = gpuArray(imdb.images.data) ;                                 %   读取data
end

%% 调用CNN_Train
[ net, info ] = cnn_train(net, imdb, @getBatch, opts.train, 'val', find(imdb.images.set == 3)) ;


%% 得到data和相应的label。
% --------------------------------------------------------------------
function [im, labels] = getBatch(imdb, batch)
% --------------------------------------------------------------------
im = imdb.images.data(:,:,:,batch) ;
labels = imdb.images.labels(1,batch) ;


%% 打开data文件
% --------------------------------------------------------------------
function imdb = getMnistImdb(opts)
% --------------------------------------------------------------------
files = {'train-images-idx3-ubyte', ...
         'train-labels-idx1-ubyte', ...
         't10k-images-idx3-ubyte', ...
         't10k-labels-idx1-ubyte'} ;

     
%% 获得data
mkdir(opts.dataDir) ;
for i=1:4
  if ~exist(fullfile(opts.dataDir, files{i}), 'file')
    url = sprintf('http://yann.lecun.com/exdb/mnist/%s.gz',files{i}) ;
    fprintf('downloading %s\n', url) ;
    gunzip(url, opts.dataDir) ;
  end
end

f=fopen(fullfile(opts.dataDir, 'train-images-idx3-ubyte'),'r') ;
x1=fread(f,inf,'uint8');
% x1=zscore(x1);
fclose(f) ;
x1=permute(reshape(x1(17:end),28,28,60e3),[2 1 3]) ;
x11 = x1(:,:,1);
x12 = x1(:,:,2);
x13 = x1(:,:,3);
x11 = imresize(x11,2);
x12 = imresize(x12,2);
x1 = cat(3,x11,x12,x13);

f=fopen(fullfile(opts.dataDir, 't10k-images-idx3-ubyte'),'r') ;
x2=fread(f,inf,'uint8');
% x2=zscore(x2);
fclose(f) ;
x2=permute(reshape(x2(17:end),28,28,10e3),[2 1 3]) ;
x21 = x2(:,:,1);
x22 = x2(:,:,2);
x23 = x2(:,:,3);
x21 = imresize(x21,2);
x22 = imresize(x22,2);
x2 = cat(3,x21,x22,x23);

f=fopen(fullfile(opts.dataDir, 'train-labels-idx1-ubyte'),'r') ;
y1=fread(f,inf,'uint8');
fclose(f) ;
y1=double(y1(9:end)')+1 ;

f=fopen(fullfile(opts.dataDir, 't10k-labels-idx1-ubyte'),'r') ;
y2=fread(f,inf,'uint8');
fclose(f) ;
y2=double(y2(9:end)')+1 ;


imdb.images.data = single(reshape(cat(3, x1, x2),56,56,1,[])) ;
imdb.images.labels = cat(2, y1, y2) ;                                       % 得到[ y1 y2 ]
imdb.images.set = [ones(1,numel(y1)) 3*ones(1,numel(y2))] ;
imdb.meta.sets = {'train', 'val', 'test'} ;
imdb.meta.classes = arrayfun(@(x)sprintf('%d',x),0:9,'uniformoutput',false) ;

% ------------------------------------------------------------------------------
function imdb = getSubset(imdb,opts)
% ------------------------------------------------------------------------------
assert(opts.train.subsetSize <= nnz(imdb.images.set == 1),...
        'Subset size is bigger than the total train set size')
inds = find(imdb.images.set == 1);   % indices  must be from the train set
inds = randsample(inds, length(inds)-opts.train.subsetSize );
imdb.images.labels(inds) = [];
imdb.images.set(inds) = [];
imdb.images.data(:,:,:,inds) = [];


结果:




虽然并没有训练结束,大家可以看到至少我们得到了正确的结果。

先写到这里,大家可以根据上面的code理解一下。

后面会持续更新。


本文为原创文章转载必须注明本文出处以及附上 本文地址超链接  以及 博主博客地址http://blog.csdn.net/qq_20259459  和 作者邮箱( jinweizhi93@gmai.com )。

(如果喜欢本文,欢迎大家关注我的博客或者动手点个赞,有需要可以邮件联系我)

没有更多推荐了,返回首页