在很多机器学习的实验室中,机器已经进行了上万小时的训练。在这个过程中,研究者们往往会走很多弯路,也会修复很多bug,但可以肯定的是,在机器学习的研究过程中,学到经验和知识的并不仅仅是机器,我们人类也积累了丰富的经验,本文就将给你几条最实用的研究建议。

接下来本文将介绍一些训练深度神经网络时的经验(主要基于TensorFlow平台)。有些建议可能对你来说很显而易见,但对其他人来说可能很重要。有些建议可能对某些特定任务并不适用,请谨慎使用!

一般性建议

使用 ADAM优化器。和批量梯度下降等传统优化器相比,Adam优化器效果更好。

TensorFlow使用建议:保存和恢复权重时,记得在创建Adam优化器后创建Saver,因为Adam也有state(也叫学习速率的单位权重)需要恢复。

Relu是最好的非线性映射(激活函数)。就像 Sublime是最好的文本编辑器, ReLU快速、简单,神奇的地方在于它在训练过程中不会逐渐减少梯度。虽然教科书中常用sigmoid作为激活函数,但是它在DNN中不能很好地传递梯度。

不要在输出层用激活函数。这一点应该很明显,但是如果你在构建网络的每一层都使用了一个共享的函数,那这个错误就很常见了。请确保你在输出层没有使用激活函数。

在每一层中增加一个偏差值。这是机器学习入门知识:偏差本质上的作用是把一个平面转化到最佳拟合位置。在y=mx+b函数中, b就是一个偏差值,可以把直线移动到最佳拟合的位置。

使用方差缩放初始化(variance-scaled initialization)。在Tensorflow中,使用类似于tf.contrib.layers.variance_scaling_initializer()这样的方法初始化。

根据我们的经验,这个方法比常规的高斯分布初始化,截断正态分布初始化和Xavier初始化方法效果更好。

总体上讲,方差缩放初始化可以根据每一层输入和输出的数量(TensorFlow中默认使用输入的数量),来调整初始随机权重的方差,从而帮助信号在不需要通过截断或者批量规范化等额外的方法来在网络中传递得更深。

Xavier初始化方法和它类似,只是Xavier初始化在所有层中基本一样,如果网络的层与层之间的取值范围差异很大(常见于卷积网络),每一层使用同一个方差可能就不适用了。

输入数据归一化。在训练时,减去数据集的均值,然后除以标准差。这样可以减少权重在每个方向上的拉伸,帮助神经网络更快更好地学习。保持输入的数据以方差为均值中心可以很好的实现这点。你也要保证每次测试输入采取一致的归一化方法,从而保证你的训练集能够模拟真实数据环境。

合理地缩放数据。这与归一化处理相关,但应该在归一化之前进行。比如,数据x在现实生活中的范围是[0, 140000000],可能服从tanh(x)或者 tanh(x/C)分布,其中 C为常量,用于调整曲线帮助输入数据更好的符合tanh函数的坡度部分。尤其当你输入数据地在一端或者两端无界的情况下,神经网络在 (0,1)范围里可以学习的更好。

通常情况下,不要费力去降低学习速率。SGD中学习速率衰减更常见,但是 ADAM可以更自然地处理它。如果你一定要计较细微的性能差别:在训练结束时短暂地降低学习速率,你可能会看到一个误差突然降低一点,然后再次趋于平稳。

如果你的卷积层有64或128个滤波器,这可能就有些多余了,尤其对于深度网络来说,128个滤波器真的有些多了。如果你已经有了大量的滤波器,再添加可能毫无意义。

池化(pooling)是为了最大程度保持变换的不变性。pooling本质上是使神经网络学习图像中一部分的整体特征。比如,max pooling可以使图像在卷积网络中经过位移、旋转和缩放等变换之后,仍然保持特征的不变性。

调试神经网络

如果你的神经网络不能够学习,也就是说训练时损失或者精确度不收敛,或者不能得到预期的结果。尝试以下的建议:

  • 过拟合!如果你的网络不收敛,第一件要做的事是去过拟合一个训练点,精度应该达到 100%或99.99%,或者误差接近0。如果你的神经网络不能过拟合单个数据点,那么你的架构存在严重但可能很细微的问题。如果你可以过拟合一个数据点但训练更大的数据集时不能收敛,那么可以尝试如下建议。

  • 降低学习速率。你的网络会学习的慢一些,但是它可以下降到最小值,之前无法达到是因为步长设置的太大。(想象一下寻找最小值就相当于你想抵达沟渠最低点,而步长太大导致你直接跨过了沟渠。)

  • 提高学习率。较大的学习率有助于缩短训练时间,减少反馈环路,这就意味着可以较快地预判网络模型是不是可行。不过虽然网络模型能够更快的收敛,但是结果可能不会特别理想,甚至会有较大的振荡。(我们发现对于ADAM优化器,0.001的学习率在许多实验中收效不错。)

  • 减小批处理的样本数。使用样本数为1的批处理能够获取更细粒度的权重以更新反馈,你可以使用TensorBoard查看(或者其他调试/可视化的工具。)

  • 去掉批处理规范化。在批理样本数减少到1的同时,去掉批处理规范化,可以暴露梯度消失或者梯度爆炸的问题。我们曾有一个神经网络模型在几个星期后仍旧不能收敛。直到去掉了批处理规范化,我们才意识到在第二轮迭代后所有的输出都是NaN。批处理规范化的作用如同止血时的创口贴,但是只有在你的网络模型没有错误的情况下才管用。

  • 增加批处理的样本数。较大样本的批处理,比如使用整个数据集,减少了梯度更新的方差,可以使得每轮迭代的结果更精确。换句话说,权重迭代将朝着正确的方向进行。但是,这个方法受到物理内存大小限制。通常,前面两个使用样本数为1 的批处理和除去批处理规范化的技巧比这个技巧要更有用。

  • 检查矩阵变形。较大的矩阵变形(例如改变图像的横纵轴)会破坏空间的局部性特征,给模型的学习增添了难度,因为矩阵变形也是需要学习的一部分。(自然的特征变得四分五裂。事实上自然特征的空间局部特征也是卷积神经网络之所以有效的原因。)要特别注意多图形/通道的矩阵变形;用numpy.stack()进行适当的调整。

  • 检查损失函数。如果使用的是复杂的损失函数,就先试一下简单的例如L1或者L2损失函数。我们发现L1对于异常值没那么敏感,因此受噪音数据影响较小。

  • 检查可视化。检查你的可视化工具包(matplotlib,OpenCV,等)是否调整了数值的数量级,或者有值域限制?也可以考虑使用统一的配色方案。

案例解析

为了使上述的步骤更容易理解,这里我们展示几张(通过TensorBoard)卷积神经网络做的回归实验的损失图。

首先,这个神经网络根本没有收敛:

我们尝试剪裁数值值域,以防止他们超出范围:

哎呀,看这个没有光滑处理过的线是多么的杂乱。是学习率太大了吗?我们试着衰减了学习率并只用一个样本点进行训练:

你可以看到学习率发生了变化(大概在300到3000步间)。显然,学习率降的太快了。所以,我们放缓了迭代速率,效果就好些了:

你可以看我们在2000到5000步间进行了衰减。结果好些了,但是还不够,因为损失还没有降到0。

然后我们停止了学习率的衰减并且尝试了将数值压缩到更小的值域并取代了tanh函数。虽然这样损失降到了1,我们仍然不能达到过拟合。

我们就是在这一步发现,去掉批处理规范化后,网络输出很快在一到两次迭代后变成NaN。于是,我们停止了批处理规范化并且把初始化改为方差标准化。这样一下就解决了问题,用一两个输入样本训练就能达到过拟合。虽然图下方的Y轴的值被剪切了,但是初始的误差在5以上,表明误差几乎下降了4个数量级。

上图的上半部分是经过光滑处理的,但是你仍可看到对测试数据很快达到了过拟合,整个训练集的损失也降到了0.01以下。而这时我们还没有衰减学习率。我们将学习率降低了一个数量级后继续训练神经网络,得到了更加好的结果:

这些结果好太多了!但是如果我们将学习率成几何级衰减而不是将训练分成两部分会怎么样呢?

如果将学习率在每一步迭代都乘以0.9995,这个结果就不那么妙了:

原因估计是因为学习率衰减的太快。用0.999995会稍微好一些,但是结果几乎跟没有衰减一样。我们从这一系列的实验中总结出,批处理规范化掩盖了由初始化不当导致的梯度爆炸,而除了最后阶段学习率的衰减,衰减的学习率对于ADAM优化器也不是很有用。伴随着批处理正规化,剪裁值域只是掩盖了真实的问题。我们还通过使用tanh激活函数对我们高方差的输入数据进行了转化。

我希望这些基本的技巧可以对你学习深度神经网络有所帮助。事情往往就是这样,简单的细节可以产生重大的影响。

相关报道:

https://pcc.cs.byu.edu/2017/10/02/practical-advice-for-building-deep-neural-networks/

机器都会学习了,你的神经网络还跑不动?来看看这些建议相关推荐

  1. 揭示世界本质的「机器科学家」,比深度神经网络还强?

    我们正处于"GoPro 物理学"的风口浪尖.无论摄像机聚焦于什么事件,算法都可以识别其中潜在的物理方程. 作者 | Charlie Wood 编译 |  王玥.刘冰一 编辑 | 陈 ...

  2. Java还欠缺什么才能真正支持机器/深度学习?

    如何让团队开始使用ML以及如何最好地将ML与我们运行的现有系统集成? 实际上没有用Java构建的ML框架(有DL4J,但我真的不知道有谁使用它,MXNet有一个Scala API而不是Java,而且它 ...

  3. 机器不学习:浅析深度学习在实体识别和关系抽取中的应用

    机器不学习 jqbxx.com -机器学习好网站 命名实体识别(Named Entity Recognition,NER)就是从一段自然语言文本中找出相关实体,并标注出其位置以及类型,如下图.命名实体 ...

  4. 2021 年了,机器/深度学习还有哪些坑比较好挖?

    作者丨张趔趄.微调.金雪锋 来源丨知乎问答 编辑丨极市平台 导读 深度学习以及机器学习发展至今,涌入了大量的人才和资源,有很多方向已经达到了一个瓶颈,短时间内有非常大的突破有些难以实现.那么对于有学术 ...

  5. 送你一份机器/深度学习自学指南(附视频amp;速成方案)

    本文经AI新媒体量子位(公众号ID:qbitai )授权转载,转载请联系出处. 本文约3052字,建议阅读6分钟. 本文详细讲解了机器/深度学习的学习方法,一共为分三个部分,做出了详细的指南. 怎么入 ...

  6. 深度学习如何入门?怎么入门机器/深度学习?

    链接:https://www.zhihu.com/question/26006703/answer/536169538 怎么入门机器/深度学习? 回答这个问题,最先要考虑的问题是:你有多少时间? 准备 ...

  7. 深度学习入门之PyTorch学习笔记:卷积神经网络

    深度学习入门之PyTorch学习笔记 绪论 1 深度学习介绍 2 深度学习框架 3 多层全连接网络 4 卷积神经网络 4.1 主要任务及起源 4.2 卷积神经网络的原理和结构 4.2.1 卷积层 1. ...

  8. 纯新手入门机器/深度学习自学指南(附一个月速成方案)

    原作:Masum Hasan 问耕 编译整理 量子位 出品 | 公众号 QbitAI 怎么入门机器/深度学习? 回答这个问题,最先要考虑的问题是:你有多少时间? 准备用三个月入门,和想要一个月速成,肯 ...

  9. Human vs AI,人类和机器的学习究竟谁更胜一筹?

    在各种任务中人类的学习能力和机器的学习能力究竟哪个更胜一筹? 随着 AI 的不断研究和发展,各类 AI 算法在不同场景中的应用层出不穷,关于 AI 及其在日常任务中支持甚至取代人类工作的能力的讨论无处 ...

最新文章

  1. 判断是否十六进制格式字符串
  2. html台风路径,常用气象网站功能简介
  3. Angular新建组件以及组件之间的调用
  4. RabbitMQ 交换器、持久化
  5. .net core 获取binary 文件_Linux操作系统文件目录
  6. [转载] python mongodb update
  7. ArcMAP TIN与栅格DEM的坡度坡向对比分析
  8. C语言之二维数组定义、初始化、赋值、求最大最小、求和
  9. .bss段和.data段引起的文件大小增加
  10. 线段树--暴力修改专题浅谈
  11. 在linux下用c语言编程软件下载,在Linux下进行C语言编程
  12. 第二章 进程管理(3)——进程同步
  13. hive问题-return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
  14. 智云通CRM:销售人员说太多,对吗?
  15. win7系统如何设置远程桌面连接【系统天地】
  16. 好用的wordpress企业主题,Benevolent
  17. no-cache,max-age=0,nostore区别及304原理
  18. 知识图谱在计算机安全的应用,基于知识图谱的计算机领域胜任力研究与应用
  19. 交叉验证(CrossValidation)方法思想简介
  20. 两相步进电机和五相步进电机

热门文章

  1. 使用 alpine 打包镜像注意事项
  2. idea内Maven的全局配置
  3. 用BRAT进行中文情感分析语料标注
  4. 基于javaGUI的文档识别工具制作
  5. LeetCode中等题之两两交换链表中的节点
  6. 合肥工业大学—SQL Server数据库实验五:创建和删除索引
  7. 传统编译器与神经网络编译器
  8. gst-crypto GStreamer插件
  9. 基于TensorRT的BERT实时自然语言理解(上)
  10. 对抗性鲁棒性与模型压缩:ICCV2019论文解析