你的神经网络已经跑了12个小时演习,看上去统统都很完美:梯度运转良好,丢失也在降落。
但是做预测的时候却一团糟:所有都是0,什么也监测不到。
“我哪一步做错了呢?”你迷茫地问你的电脑,而电脑却笑而不语。

如果你的模型输出来的都是辣鸡——例如你想预测所有输出的均匀值,或者模型的精度很低——该从哪儿开始检讨

干货  模型表现不好怎么办37条妙计助你扭转局势 汽车知识

可能出错的地方多了去了。
经由很多次的调试,我常常做此类检讨。
我根据自己的履历以及很多好的想法,写了以下这个指引。
希望对你们也有用。

目录

0、如何利用本指引

一、数据库问题

二、数据归一化/增强问题

三、实行问题

四、演习问题

0. 如何利用本指引

很多问题可能会出错。
不过有一些问题相对随意马虎办理。
常日我先从这个急救列表开始:

1. 先从一个大略的模型入手,找一个对此类数据证明可行的模型,例如针对图像就用VGG。
如果可能的话就选一个标准的丢失函数。

2. 把花哨的小玩意都卸了,例如归一化和数据增强。

3. 微调模型的时候,仔细检讨数据预处理,由于它必须跟原始模型的演习数据同等。

4. 确认输入数据精确。

5. 从一个很小的数据库入手(2-20个样本)。
用这个调试好了,再逐步增加更多数据。

6. 逐步把省略的每一个部件都加回来:增强、归一化、定制的丢失函数、更繁芜的模型。

如果以上的步骤不管用,再根据下面这个更长的列表来一项项确认。

一、数据库问题

- 老板:你给我的数据对吗?

- 程序猿:这么多年来我给你的数据都是错的。
怎么本日想到找茬了。

- 老板:你说啥?

程序猿:我说数据完备准确。

1. 检讨输入数据

检讨你输入网络的数据是否精确。
举个例子,我好几次把图像的长和宽搞混了。
有时候,我一欠妥心全部输入的都是0。
有时候,我把同一个批次的数据用了一遍又一遍。
以是,打印显示你想要的输入和输出,确保数据精确。

2. 试试随机输入

试试输入随机数据而非真实数据,看看是不是会得到一样的缺点。
如果是的话,那你的网络肯定是某一个点出错了,可以试试一层层、一个指令一个指令地调试,看看是哪个点出了错。

3. 检讨数据导入

可能你的数据是对的,但是用来导入数据到网络的代码可能有问题。
在任何动作之前,把第一层的数据打印出来看看。

4. 确保输入和输出相连

检讨一下是不是输入样本都有精确的标签。
再把输入数据打乱,看看输出标签是不是也会打乱。

5. 输入和输出之间的关系是不是太随机

可能输入和输出之间的非随机部分,与随机部分比较太少了,例如股票便是这样。
换句话说,输入和输出之间的关联不足。
对付这一点没有万全的办法,由于这得看数据的情形。

6. 数据库中的噪音是否过多

我发生过这样的缺点,把一个食品网站的图像弄坏了。
缺点的标签太多,网络没法进行学习。
手动检讨一些输入样本,看看标签有没有问题。

业界没有统一的分水线,一篇论文曾在50%标签缺点的情形下,实现了高于50%的精度。

7. 打乱数据库

如果数据库没有打乱,而是用标签进行了排序,有可能会影响到网络的学习。
打乱数据库的顺序,防止这个问题。
确保输入和标签一起打乱。

8. 减少类偏斜问题

A类图像是不是比B类多出了一千倍?那你得平衡你的丢失函数,或者考试测验其他类偏斜问题的办理方法。

9. 你有足够的演习例子吗?

如果你从零演习一个神经网络,也便是说,没有经由调试,你可能须要很多的数据。
对付数据分类问题,很多人说每一类都须要一千个、乃至更多的图像。

10. 确保一个批次的数据里不包含单一标签

在经由排序的数据库中可能涌现这个问题,例如,一万个样本包含同一个种别。
这个很好办理,只要打乱排序就好了。

11. 减少mini-batch大小

一篇论文指出,一个非常大的mini-batch会减少模型泛化的能力。

弥补1:利用标准数据库(例如mnist和cifar10)

感谢 @hengcherkeng 网友的贴士:

测试新的神经网络架构或者写新代码的时候,首先利用标准数据库,而非你自己的数据。
这是由于这些数据库有很多参考绩果,都是可以办理的。
这样就防止了以下的问题:标签噪音、演习/测试分布差别、数据库比较困难等等。

二、数据归一化/增强

12、把特色归一化

你把输入归一化了为均匀值为0且方差为1了吗?

13、数据增强是否过度

增强带有归一化的效果。
过度增强会带来其他形式的归一化(weight L2、Dropout 等等),可能导致网络调试不敷。

14、检讨预演习模型的预调试

如果你利用的是预演习模型,演习的时候一定要利用跟模型相同的归一化和预处理。
例如,图像像素该当在哪个范围内,[0,1]、[-1,1]还是[0,255]?

15、检讨演习/验证/测试数据库

CS231n 指出了一个常见漏洞:

“...任何预处理数据,例如数据均匀值,都必须只在演习数据中计算,然后运用到验证/测试数据上。
举个例子,打算均匀数,然后从数据库的每一个图像中减掉均匀值,再将数据库分割为演习/验证/测试数据,这样就错了。

其余,还须要在每一个样本或者批次中检讨不同的预处理。

三、实行问题

- 这一大坨便是你的机器学习系统。

- 把数据输入这一大坨线性代数,然后等着答案吐出来。

- 如果答案错了怎么办?

- 那就把这一大坨搅和搅和,直到答案对了为止。

16. 把大问题变成小问题

这有助于定位问题出在哪儿。
举个例子,如果目标输出是一个目标种别或者坐标,可以将预测仅限于目标种别。

17. “随机”探求精确的丢失

还是来自于精彩的 CS231n:以小参数开始,不用归一化。
例如,如果我们有10个种别,随机意味着我们只有十分之一的时候能得到精确种别,而且 Softmax 丢失是精确类别的负对数概率:-ln(0.1) = 2.302。

然后,试试增加归一化的强度,该当能增加丢失函数。

18. 查一查你的丢失函数

如果你实行自己的丢失函数,检讨一下有没有问题,增加单元测试。
我的丢失函数常常有些眇小的缺点,导致神经网络的运行涌现细微的偏差。

19. 确认丢失输入

如果你利用自己框架下的丢失函数,一定要把稳,输入给它的数据得符合其预期。
例如,在 PyTorch 里我会稠浊 NLLLoss 和 CrossEntropyLoss,这就犯了错,由于前者须要 softmax 输入,而后者则不须要。

20. 调度丢失权重

如果你的丢失函数由多少个较小的丢失函数构成,它们之间的相对大小必须精确。
这可能须要测试不同丢失权重的组合。

21. 监测其他度量

有时候,丢失函数没法最好地预测神经网络的演习是否良好。
如果可以的话,利用精度等其他度量。

22. 测试任何定制层

神经网络里,你有没有自己实行任何的层?重复检讨,确保它们运行正常。

23. 检讨“冻结”层或者变量

检讨一下是否不经意间,你解除了一些层或者变量的梯度更新,没能及时得到信息。

24. 增加网络大小

可能你的神经网络的表达力太小,不能描述目标函数。
试试在完备联接的层中,增加更多的层或者隐蔽单元。

25. 检讨隐蔽维度缺点

如果你的输入类似(k, H, W) = (64, 64, 64),很随意马虎忽略跟缺点维度有关的漏洞。
在输入维度利用特殊的数字(例如在每一个维度都利用质数),检讨它们如何在网络中传播。

26. 考试测验梯度检讨

如果你手动实行梯度低落,梯度检讨能确保反向传播运行正常。

四、演习问题

图像中可以识别出来一辆汽车。

27. 用很小很小的数据库

用一个很小的数据库子集用于调试,确保运行正常。
例如,只用一两个例子进行演习,看你的神经网络能否学会区分这些例子。
然后再在每一个类型增加例子。

28. 检讨权重初始化

如果不愿定的话,初始化就用 Xavier 或者 He。
其余,初始化有可能导致一个缺点的区域最小值,以是要考试测验几个不同的初始化方法,看看有没有用。

29. 改变超参数

可能你用的超参数组有问题。
如果可能的话,试试网格搜索。

30. 减少归一化

过度归一化可能让网络无法调试。
减少一些归一化,例如 dropout、批次常规、weight / bias L2 归一化,等等。
Jeremy Howard 在其精彩的课程“程序员深度学习实操”中,建议首先打消欠拟合。
这意味着你必须充足地优化演习数据,然后再去处理过度优化的问题。

31. 交给韶光

可能你的神经网络须要更多韶光来演习,才能做出故意义的预测。
如果你的丢失在稳健降落,那就再让它多演习一段韶光。

32. 从演习模式转化为测试模式

一些带有 Batch Norm、Dropout 等其他层的框架,在演习和测试的时候表现不同。
转换到得当的模式有助于神经网络有效地预测。

33. 将演习视觉化

- 监测每一层的初始化、权重和更新。
确保它们的强度相互匹配。
例如,参数更新的强度该当为1-e3。

- 考虑 Tensorboard 和 Crayon 等视觉化库。
大略来说,你还可以打印输出权重、偏压或者初始化。

- 把稳层初始化的均匀值有没有大大超过0. 可以试试 Batch Norm 或者 ELU。

- 对付权重和偏压的柱状图,网友 Deeplearning4j 这样说道:

“关于权重,柱状图一段韶光往后该当大致是一个高斯(正态)分布。
关于偏压,柱状图基本上是从0开始,常日末了也会靠近高斯分布(是非期影象网络则是一个例外)。
要把稳趋近于正/负无穷的参数。
要把稳变得非常大的偏压。
如果种别分布非常不平衡,这有时候就会发生在分类中的输出层。

- 检讨层更新,它们该当是高斯分布。

34. 试试不同的优化器

你选的优化器该当不会妨碍神经网络的演习,除非你选的超参数特殊有问题。
但是,适宜某一任务的优化器有助于在最短的韶光内完成最多的演习。
看看先容算法的论文,里面该当说名该利用什么优化器。
如果没有说的话,我方向于利用 Adam 或者就用带有 momentum 的 SGD。

35. 梯度消逝与梯度爆炸

- 检讨层更新,由于很大的值意味着梯度爆炸。
梯度剪裁可能有用。

- 检讨层初始化。
网友 Deeplearning4j 供应了很好的指引:“对付初始化,好的标准方差是在0.5到2.0的范围内。
如果远远超出了这个范围,可能便是消逝或者爆炸初始化。

36. 增加或减少学习率

如果学习率低,模型的收敛会非常地慢。

如果学习率高,开始的丢失会很快减少,但是可能很难找到一个满意的答案。

可以拿你现在的学习率做一些小改动试试,乘以0.1或乘以10。

37. 肃清NaN

演习循环神经网络时,如果看到NaN就问题大了。
办理办法包括:

- 减少学习率,尤其是如果前一百次迭代就涌现NaN的话。

- 如果打算中包含除以0、求0或负数的自然对数,就会涌现NaN。

- 一层层地检讨神经网络,看看NaN是从哪儿出来的。

如果各位读者还有什么好办法,欢迎在留言区分享,大家以开源共享的精神帮更多的人办理更多的问题。

via Slavv Blog,雷锋网 AI 科技评论编译