深度 | 你的神经网络不work? 这37个原因总有一款适合你!

大数据文摘作品,转载要求见文末

作者 | Slav Ivanov (企业家/黑客)

编译 | 朱璇、霍静、笪洁琼、崔云柯

彼时,我手头的神经网络训练已持续了12个小时,各项指标显示运转良好。没有一点点防备,就在刚才,突然提示:全部预测为零,一点有用的信息都没有!

“到底哪里出问题了?” ——我自言自语,很是郁闷。“该如何检查神经网络模型输出的信息是否有用(例如,预测所有输出的平均值,还是看看准确度是不是很糟糕)”?

其实,影响神经网络训练正常运转的影响因素很多! 在经历了多次调试后,我总结出了一些通用的经验,特此整理成文,希望能够给和我有一样困惑的朋友们一点启发:

目录

0. 如何使用本指南?(https://blog.slavv.com/37-reasons-why-your-neural-network-is-not-working-4020854bd607#b6fb)

I. 数据集问题(https://blog.slavv.com/37-reasons-why-your-neural-network-is-not-working-4020854bd607#678a)

II. 数据归一化/扩增问题(https://blog.slavv.com/37-reasons-why-your-neural-network-is-not-working-4020854bd607#86fe)

III. 执行问题(https://blog.slavv.com/37-reasons-why-your-neural-network-is-not-working-4020854bd607#95eb)

IV. 训练问题(https://blog.slavv.com/37-reasons-why-your-neural-network-is-not-working-4020854bd607#74de)

0. 如何使用本指南?

其实,可能导致错误的影响因素有很多, 不过总有一些“出镜率”比较高。如果出现问题,我通常从下面的列表开始:

1. 从一种可用于此类型数据的已知简单模型开始试验(比如用于图像识别的VGG模型)。 如果可能,使用标准损失。

2. 关闭所有“铃声和口哨”(译者注:即使用最基础的模型),比如不再使用正则化和数据扩增。

3. 调模型时,请仔细检查预处理,确保使用和我们训练原始模型一样的预处理。

4. 验证输入数据是否正确。

5. 从一个非常小的数据集(2-20个样本)开始,先让模型过度拟合,再逐渐增加更多的数据。

6. 逐渐添加之前被省略的部分:数据扩增/正则化,自定义损失函数,尝试更复杂的模型。

如果上述内容还不能解决问题,那接下来,请继续阅读,我们之后会还有一份大型影响因素清单,建议逐一验证。

I. 数据集问题

资料来源: http : //dilbert.com/strip/2014-05-07

1. 检查输入数据

检查一下你输入训练模型的数据是否正确。之前,曾经好多次我都搞混了图像的宽度和高度,还有的时候,我手误输入一堆多余的零,还有,曾经发生过多次重复输入同一批次数据的情况……

总之,记得仔细检查一开始几个批次输入和输出情况,尽可能保证看起来正常。

2. 随机输入验证

尝试往训练项目中输入一些随机数据,然后看看模型报错,和之前的报错情况是否一致。 如果一致,那肯定是在模型的某个阶段出了问题,将数据转换成了垃圾。 之后,逐层调试,找到出错的地方就好。

3. 检查数据加载器

有时候,数据本身可能没问题,出问题的可能是将数据输入到网络的代码。 因此,在任何操作之前,请打印第一层的输入检查检查。

4. 确保输入连接到输出

检查几个输入样品是否有正确的标签。 同时还要确保输入样本与输出标签的重新排序方式相同。

5. 输入与输出之间的随机比例问题

如果模型中,输入输出之间的非随机部分,相比随机部分比例过小,那么我们可以确定,输入和输出无关的可能性比较大。 因为这往往取决于数据的性质,目前,针对这个情况,我还没找到更简便的方式来检测,毕竟这与数据本身的特质息息相关。

6. 数据集中是否有太多噪音?

之前有一次,我打算从食品站点上整理一组图像数据集,放到我的神经网络模型,结果就碰到了这个问题。里面很多数据都显示损坏标签,才影响到模型结果。建议手动检查一些输入样本,看看它们显示的标签。

对于多少噪音才是神经网络训练的临界点目前仍有争议,比如,这篇文章(https://arxiv.org/pdf/1412.6596.pdf) 显示,在一定条件下,在使用了50%损坏标签的MNIST数据集中,准确率仍可以达到50%以上。

7. 对数据集重新排序

如果数据集没有重新排序,并且有特定的顺序(按照标签排序),这可能会对学习产生负面影响。 记得给数据集随机重新排序,也别忘了将输入和标签用同样的方式重新排序。

8. 减少标签不平衡

图像种类B和图像种类A是1:1000吗? 如果这样,我们可能需要平衡损失功能或尝试其他标签不平衡数据的应对方法 (http://machinelearningmastery.com/tactics-to-combat-imbalanced-classes-in-your-machine-learning-dataset/)。

9. 你的训练数据够多吗?

从头开始训练一个神经网络,是需要大量数据的。 在图像分类方面, 有人建议每个类别需要约1000张图片或更多。(https://stats.stackexchange.com/a/226693/30773)。

10. 确保批次数据不为单一标签

这可能发生在有序数据集中(即前一万个样本拥有同一个标签)。 通过将数据集重新排序可轻松修复这个问题。

11.减少每个批次的容量

这篇文章(https://arxiv.org/abs/1609.04836)指出,拥有非常大的批次可以降低模型的泛化能力。

添加 1.使用标准数据集(例如mnist,cifar10)

感谢@ hengcherkeng提出这一点:

当测试新的网络架构或编写新的代码片段时,首先使用标准数据集,而不是自己的数据。 这样,我们就可以参考前人的数据集总结,这样做的好处是,不存在标签噪音、训练/测试分配差异、数据集难度过大等问题。

II. 数据归一化/增强

12. 特征标准化

你有没有标准化你的输入数据,它们是否具有零均值和单位标准差?

13. 你是否做了太多的数据扩增?

数据扩增具有正则化效果。 太多的数据扩增,再加上其他形式的正则化(比如weight L2, dropout等等),都可能导致网络拟合不足。

14. 检查预训练模型的预处理

如果您使用预先训练好的模型,请确保您正在使用与该模型训练时相同的规范化和预处理。 例如,图像像素是在[0,1]、[-1,1]还是[0,255]的范围内?

15. 检查训练集/验证集/测试集的预处理

CS231n指出了一个常见的陷阱(http://cs231n.github.io/neural-networks-2/#datapre) :

“......任何预处理统计值(如数据均值)只能在训练数据上计算,然后应用于验证/测试数据。 例如,计算平均值并从整个数据集中的每个图像中减去它,然后将数据分割成训练集/验证集/测试集将是一个错误。 “

另外,请检查每个样品或批次中是否使用了不同的预处理。

III.执行问题

资料来源: https://xkcd.com/1838/

16. 尝试简化问题

简化问题能够帮助你发现异常。如果目前你的模型输出了对象的分类和坐标,那就尝试只输出对象的分类。

17. “随机”寻找正常范围的损失

源自卓越的cs231n课程:用少量的参数来初始化,不加正则化。比如,如果我们有十个类,“随机”意思是10%的时候我们会得到正确结果,softmax损失是负对数概率:-ln(0.1) = 2.302。

然后,再试着增加正则化的强度,从而增加损失。

18. 检查你的损失函数

如果你自己实现了损失函数,那检查bugs,再加上单位测试。之前,我的损失函数稍微有些偏差,降低了网络的性能。

19. 验证损失的输入

如果你正在使用“已有框架”提供的损失函数,那你一定要按照指定方法输入指定数据。 在PyTorch里,我会弄混NLLLoss和CrossEntropyLoss,前者需要softmax输入,但后者不需要。

20. 调整损失的权重

如果你的损失是由几个小的损失函数组成的,确保他们的相关权重是合适的。这也许包括了测试几种不同的权重组合。

21. 监测其他度量标准

有时候损失并不是最好的测量标准来衡量你的网络是否训练良好。如果可以,可以使用其他的,比如准确率。

22. 测试每一个自定制网络层

你自己完成了网络里的层吗?检查,再检查,确保这些层运行正确。

23. 检查“冻结”的网络层或者变量

检查你是不是无意间限制了可更新层与变量的更新。

24. 增加网络大小

也许你网络的指数级力度不足以描述目标函数。尝试增加更多的层,或者全链接的隐藏单元数。

25. 检查隐藏维错误

如果你的输入是(k, H, W) = (64, 64, 64),那很容易错过关于错误维度的错误。使用奇怪的数字设置输入维度(比如,对不同的维度使用不同的素数),来检查它们是怎么在网络传播。

26. 进行梯度检查

如果你自己手动实现了梯度下降法,检查梯度,以确保你的后向传播运行良好。

IV.训练问题

资料来源: http://carlvondrick.com/ihog/

27. 解决一个小的数据集

过拟合一个很小的数据子集,确保它可行。比如,用1到2个例子进行训练,看看是否你的网络能分类正确。然后再每个类添加更多的例子。

28. 检查权重的初始化

如果不确定,就使用Xavier或者He来初始化。初始化可能会把你引向一个有问题的最小局部,所以,你可以尝试不同的初始化,看是否有帮助。

29.改变超参数

也许你使用的超参数集有问题。如果可以,可以尝试http://scikit-learn.org/stable/modules/grid_search.html。

30.减少正则化

过度的正则化会让网络拟合不足。尝试减少过度的正则化,诸如,dropout,batch norm,权重/偏差 L2正则化,等等。在“实用深度学习程序员必读”这门课中,Jeremy Howard建议先排查拟合不足。这意味着你先使训练集过拟合,而且只有过拟合。

31. 给你的训练网络多一点的时间

有时候并不是网络出现了问题,也有可能你太心急了。请在作出有价值的预测之前,给你的网络再多一些的训练时间。如果这个过程中,如果你观察到损失在稳定减少,那放轻松,给它再多一些的训练时间吧。

32. 训练模式与测试模式的转换

某些框架的网络层,类似batch norm,dropout,它们的效果在训练和测试模式是不一样的。请选择合适的模式,以确保你的网络预测更好。

33. 可视化训练的过程

  • 监控每层的激活函数,权重和更新情况。确保它们的值是对得上的。比如,参数(权重和偏差)的更新值应该是1-e3。
  • 考虑诸如Tensorboard和Crayon的可视化库。你还可以打印出来,检查权重/偏差/激活函数值。
  • 注意查找网络层的激活函数值,均值远远大于0的那些。尝试Batch Norm或者ELUs。
  • Deeplearning4j (https://deeplearning4j.org/visualization#usingui)描述了,理想状态的权重和偏差柱状图:

拿权重来说,柱状图应该呈现近似高斯分布的特征。而偏差,在柱状图中应该从0开始,最后也近似高斯分布(LSTM是个例外)。注意观察那些趋于正负无穷大的参数,以及那些变的特别大的偏差值。有时候会发生在分类的输出层,如果类的分布很不平衡的话。”

  • 检查一下层更新,它们也应该是高斯分布。

34. 尝试不同的优化器

优化器的选择上,要注意,不要选对你的训练可能造成很大影响的那些。好的优化器可以让你在最短的时间达到最好的效果。许多描述算法的论文都有说明相关的优化器,如果没找到,我一般使用Adam或者带势的SGD。

可以查看这篇很好的文章(http://ruder.io/optimizing-gradient-descent/),作者是Sebastian Ruder,里面你会知道很多关于梯度下降优化器。

35. 逐一检查那些爆炸性增长/消失不见的梯度

  • 检查层的更新,如果出现很大的值,那可能预示着爆炸性增长的梯度值。梯度剪切会有帮助。检查层的激活函数值。Deeplearning4j一文中(https://deeplearning4j.org/visualization#usingui),给出了不错的建议:“激活函数值好的标准偏差范围大致在0.5 到2.0,如果超出这个范围过多,则可能会出现激活函数值消失不见、或爆炸性增长的情况。“

36. 增加/减少学习率

学习率过低,可能会导致你的模型收敛的很慢。而学习率过高,也会有一些不良影响————起初损失快速减少,但是最后却不易找到良好解决办法。建议改变你的学习率,可以尝试乘以0.1或10。

37. 解决非数值数

如果训练RNNs,出现非数值数可能是个需要关注的问题。建议你尝试下列方式改进这个情况:

  • 减少学习率,尤其是在开始的100个回合里有非数值数时候。
  • 非数值数来自于除以0,或者0与负数的自然对数。
  • Russell Steward也给出了很多参考片方法,来应对非数值数(http://russellsstewart.com/notes/0.html)。
  • 尝试逐层评估你的网络,找出产生非数值数的确切位置。

原文链接:https://blog.slavv.com/37-reasons-why-your-neural-network-is-not-working-4020854bd607

关于转载如需转载,请在开篇显著位置注明作者和出处(转自:大数据文摘 | bigdatadigest),并在文章结尾放置大数据文摘醒目二维码。无原创标识文章请按照转载要求编辑,可直接转载,转载后请将转载链接发送给我们;有原创标识文章,请发送【文章名称-待授权公众号名称及ID】给我们申请白名单授权。未经许可的转载以及改编者,我们将依法追究其法律责任。联系邮箱:zz@bigdatadigest.cn。

原文发布于微信公众号 - 大数据文摘(BigDataDigest)

原文发表时间:2017-08-16

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏CSDN技术头条

使用GPU和Theano加速深度学习

【编者按】GPU因其浮点计算和矩阵运算能力有助于加速深度学习是业界的共识,Theano是主流的深度学习Python库之一,亦支持GPU,然而Theano入门较难...

2255

深入学习Apache Spark和TensorFlow

神经网络在过去的几年中取得了惊人的进展,现在它们已经成为图像识别和自动翻译领域的领先技术。TensorFlow是Google发布的用于数值计算和神经网络的新框架...

3037
来自专栏大数据文摘

资源 | 给卷积神经网络“修理工”的一份“说明书”

这篇文章的主要内容来自作者的自身经验和一些在线资源(如最出名的斯坦福大学的CS231n课程讲义),是关于如何调试卷积神经网络从而提升其性能的。

951
来自专栏机器之心

资源 | 用PyTorch搞定GluonCV预训练模型,这个计算机视觉库真的很好用

项目地址:https://github.com/zhanghang1989/gluoncv-torch

1165
来自专栏腾讯Bugly的专栏

基于 TensorFlow 在手机端实现文档检测

手机端运行卷积神经网络的一次实践 — 基于 TensorFlow 和 OpenCV 实现文档检测功能 1. 前言 本文不是神经网络或机器学习的入门教学,而是通过...

5744
来自专栏IT技术精选文摘

机器学习在启动耗时测试中的应用及模型调优(一)

启动耗时自动化方案在关键帧识别时,常规的图像对比准确率很低。本文详细介绍了采用scikit-learn图片分类算法在启动耗时应用下的模型调优过程。在之后的续篇中...

1694
来自专栏机器之心

学界 | 深度神经网络的分布式训练概述:常用方法和技巧全面总结

深度学习已经为人工智能领域带来了巨大的发展进步。但是,必须说明训练深度学习模型需要显著大量的计算。在一台具有一个现代 GPU 的单台机器上完成一次基于 Imag...

1912
来自专栏机器之心

学界 | Ian Goodfellow等人提出对抗重编程,让神经网络执行其他任务

作者:Gamaleldin F. Elsayed、Ian Goodfellow、Jascha Sohl-Dickstein

1233
来自专栏AI科技大本营的专栏

AI 技术讲座精选:「Python」LSTM时序预测状态种子初始化

长短期记忆网络(LSTM)是一种强大的递归神经网络,能够学习长观察值序列。 LSTM的一大优势是它们能有效地预测时间序列,但是作这种用途时配置和使用起来却较为...

3685
来自专栏AI科技大本营的专栏

AI 技术讲座精选:如何在时序预测问题中在训练期间更新LSTM网络

使用神经网络解决时间序列预测问题的好处是网络可以在获得新数据时对权重进行更新。 在本教程中,你将学习如何使用新数据更新长短期记忆(LTCM)递归神经网络。 在...

3446

扫码关注云+社区

领取腾讯云代金券