专栏首页AI算法与图像处理构建神经网络的一些实战经验和建议

构建神经网络的一些实战经验和建议

作者:Matt H and Daniel R 编译:ronghuaiyang

导读

从成千上万小时的模型训练中累计的经验和教训。

在我们的机器学习实验室,我们在许多高性能的机器已经积累了成千上万个小时的训练。然而,并不是只有计算机在这个过程中学到了很多东西:我们自己也犯了很多错误,修复了很多错误。

在这里,我们根据我们的经验(主要基于 TensorFlow)提出了一些训练深度神经网络的实用技巧。有些建议对你来说可能是显而易见的,但对我们中的某个人来说却不是。其他的建议可能不适用,甚至对你的特定任务来说是不好的建议:谨慎使用!

我们承认这些都是众所周知的方法。我们也站在巨人的肩膀上!我们这篇文章的目的仅仅是对它们进行高层次的总结,以便在实践中使用。

通用 Tips

  • 使用 ADAM 优化器。它真的很好用。比起传统的优化方法,如原始的梯度下降,我更喜欢它。注意:如果要保存和恢复权重,记得在设置好AdamOptimizer之后设置Saver ,因为 ADAM 也有需要恢复的状态(即每个权重的学习率)。
  • ReLU 是最好的非线性(激活函数)。这有点像说 Sublime 是最好的文本编辑器。但实际上,ReLUs 是快速的、简单的,而且令人惊讶的是,它们能够工作,并且没有梯度衰减的问题。虽然 sigmoid 是一种常见的教科书式激活函数,但它不能很好地通过 DNNs 传播梯度。
  • 不要在输出层使用激活函数。这应该是显而易见的,但这是一个很容易犯的错误,如果你用一个共享函数构建每个层:一定要在输出处关闭激活函数。
  • 一定要在每一层添加一个偏差。这是 ML 101:偏差本质上是将飞机转换成最佳位置。在y=mx+b中,b 是偏差,允许直线向上或向下移动到“最合适”的位置。
  • 使用 variance-scaled 初始化。在 Tensorflow 中,就像tf.contrib.layers.variance_scaling_initializer()。在我们的经验中,这比常规的高斯分布、截断的正太分布和 Xavier 更能泛化/缩放。粗略地说, variance scaling 初始化根据每一层的输入或输出的数量来调整初始随机权重的方差(TensorFlow 中的默认值是输入的数量),从而帮助信号更深入地传播到网络中,而不需要额外的“技巧”,比如 clipping 或 batch normalization。Xavier 是很相似的方法,但是 Xavier 的所有层的方差几乎相同,在那些层的形状变化很大的网络(通常是卷积网络)中,可能不能很好地处理每一层相同的变化。
  • 白化(归一化)你的输入数据。训练时,减去数据集的均值,然后除以其标准差。你需要向各个方向拉伸和拉伸的幅度越少,你的网络学习就会越快、越容易。保持输入数据的均值以不变的方差为中心有助于解决这个问题。你还必须对每个测试输入执行相同的标准化,因此要确保你的训练集与真实数据相似。
  • 以合理保留其动态范围的方式缩放输入数据。这与归一化有关,但应该在归一化之前进行。例如,实际范围为[0,140000000]的数据“x”通常可以用tanh(x)tanh(x/C)来处理,其中 C是某个常数,它拉伸曲线以适应 tanh 函数动态的、倾斜的部分中的更多输入范围。特别是在输入数据的一端或两端可能是无界的情况下,神经网络在(0,1)之间可以更好地学习。
  • 不要费心降低学习速度(通常)。学习率下降在 SGD 中更为常见,但 ADAM 自然地处理了这个问题。如果你绝对想要榨干每一盎司的表现:在训练结束后短时间内降低学习速度,你可能会看到一个突然的,非常小的误差下降,然后它会再次变平。
  • 如果你的卷积层有 64 或 128 个滤波器,那可能就足够了。特别是对于深度网络。实际上,128 已经很多了。如果你已经有了大量的滤波器,那么添加更多的滤波器可能不会改善性能。
  • 池化用于转换不变性。池化本质上是让网络学习图像“那部分”的“大意”。例如,最大池可以帮助卷积网络对图像中特征的平移、旋转和缩放变得健壮。

调试神经网络

如果你的网络没有学习(意思是:在训练过程中,损失没有收敛,或者你没有得到你期望的结果),试试下面的建议:

  • 过拟合 !如果你的网络没有在学习,首先要做的就是在单个数据样本上让网络过拟合。这样的话,准确度应该是 100%或 99.99%,或者接近于 0 的误差。如果你的神经网络不能对单个数据点进行过拟合,那么可能是体系结构出现严重问题,但问题可能很微妙。如果你可以过拟合一个数据点,但是在更大的集合上的训练仍然不收敛,请尝试以下建议。
  • 降低学习率。你的网络学习速度会变慢,但它可能会进入一个以前无法进入的最小值,因为之前它的步长太大了。(直觉上,当你真正想进入沟底时,你的错误是最低的,想象一下跨过路边的水沟。)
  • 提高学习率。这将加快训练,帮助收紧反馈回路,这意味着你会更早知道你的网络是否在工作。虽然网络应该更快地收敛,但它的结果可能不会很好,而且“收敛”的过程实际上可能会跳来跳去。(使用 ADAM 的时候,我们发现~0.001 是一个非常好的值,在许多实验中都是这样。)
  • 减小 minibatch 大小。将 minibatch 大小减少到 1 可以提供与权重更新相关的更细粒度的反馈,你可以使用 TensorBoard(或其他调试/可视化工具)报告这些更新。
  • 去掉 batch normalization。随着批大小减少到 1,这样做可以梯度消失或梯度爆炸。几个星期以来,我们的网络都没有收敛,当我们删除了 batch normalization 之后,我们意识到在第二次迭代时输出都是 NaN。Batch norm 的作用是给需要止血带的东西贴上创可贴。它有它用的位置,但只有在你网络是没有 bug 的情况下才可以用。
  • 增加 minibatch 大小。更大的 minibatch — 如果可以的话,使用整个训练集 — 减少梯度更新中的方差,使每次迭代更精确。换句话说,让权重更新的方向是正确的。但是!它的有用性有一个有效的上限,物理内存的限制。通常,我们发现这不如前两个建议那么有用,这两个建议将 minibatch 大小减少到 1 并删除 batch normalization。
  • 检查一下 reshaping。剧烈的 reshaping(比如改变图像的 X、Y 维度)会破坏空间的局部性,使得网络更难学习,因为它也必须学习 reshaping。(自然景观变得支离破碎。自然特征在空间上是局部的,这就是为什么 conv 网如此有效的原因。如果使用多个图像/通道进行 reshape,要特别小心,使用numpy.stack()进行适当的对齐。
  • 仔细检查你的损失函数。如果使用复合函数,尝试将其简化为 L1 或 L2。我们发现 L1 对异常值的敏感度较低,当遇到有噪声的批处理或训练点时,L1 的调整幅度较小。
  • 仔细检查你的可视化效果,如果适用的话。你的可视化库(matplotlib, OpenCV 等)是调整数值的比例,还是剪切它们?还可以考虑使用一种感觉上一致的配色方案。

用一个例子来学习一下

为了使上面描述的过程更接近实际,这里有一些损失图(通过 TensorBoard 画出来的),用于我们构建的卷积神经网络的一些实际回归实验。

起初,这个网络根本没有学习:

我们尝试对值进行 clipping,以防止它们超出界限:

嗯。看看这些没做平滑的值有多疯狂。学习率太高?我们试着降低学习速度,只对一个输入进行训练:

你可以看到学习率的最初几个变化发生在什么地方(大约在第 300 步和第 3000 步)。显然,我们衰减得太快了。所以,在衰减之前给它更多的时间,它可以做得更好:

你可以看到我们在 2000 步和 5000 步时衰减。这个更好,但仍然不是很好,因为它没有趋近于 0。

然后,我们禁用了学习率衰减,并尝试将值移动到一个更窄的范围内,不过不是通过输入 tanh。虽然这明显使错误值低于 1,但我们仍然不能过拟合训练集:

通过删除 batch normalization,我们发现,在经过一两次迭代之后,网络可以快速输出 NaN。我们禁用了 batch normalization,并将初始化更改为 variance scaling。这些改变了一切!我们能够过拟合我们的测试集,只是一个或两个输入。虽然底部的图表盖住了 Y 轴,但初始误差值远远高于 5,表明误差减少了近 4 个数量级:

上面的图表非常平滑,但是你可以看到它与测试输入过拟合的速度非常快,随着时间的推移,整个训练集的损失降到了 0.01 以下。这并没有降低学习率。在学习率下降一个数量级后,我们继续训练,得到了更好的结果:

这些结果好多了!但是如果我们以几何的方式衰减学习率而不是把训练分成两部分呢?

将每一步的学习率乘以 0.9995,结果并不好:

大概是因为衰减太快了,乘数为 0.999995 的情况要好一些,但结果几乎等于完全不衰减。我们从这个特殊的实验序列中得出结论,batch normalization 隐藏了糟糕的初始化所导致的急剧变化的梯度,降低学习率对 ADAM 优化器并没有特别的帮助,除了在最后可能会故意降低。与 batch normalization 一起,clipping 只是掩盖了真正的问题。我们还通过将高方差输入值放入 tanh 来处理它们。

我们希望随着你对构建深度神经网络越来越熟悉,你会发现这些基本技巧非常有用。通常,只是一些简单的事情就能改变一切。

—END—

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

本文分享自微信公众号 - AI算法与图像处理(AI_study)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-11-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 几行代码轻松实现,Tensorlayer 2.0推出深度强化学习基准库

    近日,为了让工业界能更好地使用前沿强化学习算法,Tensorlayer 强化学习团队发布了专门面向工业界的整套强化学习基线算法库---RLzoo。(Tensor...

    机器之心
  • 20+移动端硬件,Int8极速推理,端侧推理引擎Paddle Lite 2.0 正式发布

    https://github.com/PaddlePaddle/Paddle-Lite

    机器之心
  • ELECTRA:超越BERT,19年最佳NLP预训练模型

    BERT推出这一年来,除了XLNet,其他的改进都没带来太多惊喜,无非是越堆越大的模型和数据,以及动辄1024块TPU,让工程师们不知道如何落地。

    大数据文摘
  • Python爬取拉钩招聘网

    我们发现网页内容是通过post请求得到的,返回数据是json格式,那我们直接拿到json数据即可。

    python学习教程
  • 骑上我心爱的小摩托,再挂上AI摄像头,去认识一下全城的垃圾!

    垃圾管理是现代城市一个非常有挑战性的任务,每个地区都有其独特的垃圾产生模式,但无论产生垃圾的种类和数量如何变化,优化垃圾的收集方式是降低成本、保持城市清洁的重要...

    大数据文摘
  • 带你了解关系网络在反欺诈领域的常见应用

    近年来搞金融诈骗的越来越厉害啦,除了团伙化、组织化的趋势,有的居然每个月还有固定的推广费呢。那么,如何从数据的角度去鉴别诈骗团伙呢?以下这篇文章,介绍了如何利用...

    Sam Gor
  • 机器学习的「反噬」:当 ML 用于密码破解,成功率竟然这么高!

    因此,一位好奇的学者 Tikeswar Naik,通过简单的实验和我们讨论了这项技术的某一潜在滥用情况——使用 ML 来破解密码,希望通过这一介绍能够让更多人保...

    AI研习社
  • 2019最佳预训练模型:非暴力美学,1/4算力超越RoBERTa

    BERT 推出这一年来,除了 XLNet,其他的改进都没带来太多惊喜,无非是越堆越大的模型和数据,以及动辄 1024 块 TPU,让工程师们不知道如何落地。

    机器之心
  • 从起源到未来:能自己编程和改进的超人工智能会出现吗?

    在计算机科学领域中,人工智能是一种机器表现的行为,这种行为能以与人类智能相似的方式对环境做出反应并尽可能提高自己达成目的的概率。

    华章科技
  • 巴菲特+西蒙斯:完美!

    基本面投资:根据财务报表中概述的收益来衡量公司的额内在价值,识别出市场不确定的证券。如果某一证券的公允价值高于市价,则该股票被低估,并且给出卖出意见。反之。

    量化投资与机器学习微信公众号

扫码关注云+社区

领取腾讯云代金券