原文:
www.kdnuggets.com/2017/08/37-reasons-neural-network-not-working.html
评论
由 Slav Ivanov,企业家与机器学习从业者。
网络已经训练了过去 12 个小时。一切看起来都很好:梯度在流动,损失在减少。但随后预测出来的结果是:全是零,全是背景,什么也没检测到。“我哪里做错了?”——我问我的电脑,但它没有回答。
如果你的模型输出垃圾(例如预测所有输出的均值,或准确率非常差),你应该从哪里开始检查?
1. Google 网络安全证书 - 快速进入网络安全职业道路。
2. Google 数据分析专业证书 - 提升你的数据分析技能
3. Google IT 支持专业证书 - 支持你的组织的 IT
网络可能因为多种原因而无法训练。在多次调试过程中,我经常发现自己进行相同的检查。我将我的经验以及周围的最佳建议编成了这份实用的清单。希望对你也有帮助。
-
0. 如何使用本指南?
-
I. 数据集问题
-
II. 数据规范化/增强问题
-
III. 实施问题
-
IV. 训练问题
许多事情可能会出错。但其中一些比其他的更容易出问题。我通常会从这个紧急响应的短名单开始:
-
从一个已知对这种数据类型有效的简单模型开始(例如,VGG 用于图像)。如果可能,使用标准损失函数。
-
关闭所有的附加功能,例如正则化和数据增强。
-
如果对模型进行微调,务必再次检查预处理步骤,确保它与原始模型的训练一致。
-
验证输入数据是否正确。
-
从一个非常小的数据集(2–20 个样本)开始。在其上进行过拟合,并逐渐增加更多的数据。
-
逐渐添加所有被省略的部分:增强/正则化、自定义损失函数,尝试更复杂的模型。
如果上述步骤不起作用,开始逐项检查以下大清单。
检查你提供给网络的输入数据是否合理。例如,我曾多次混淆图像的宽度和高度。有时,我会错误地输入全零的数据。或者我会一遍又一遍地使用同一批数据。因此,打印/显示几批输入和目标输出,确保它们是正确的。
尝试传递随机数字而不是实际数据,看看错误是否表现得一样。如果是,那就说明你的网络在某个点上把数据变成了垃圾。尝试逐层/逐操作调试,看看问题出在哪里。
你的数据可能没问题,但将输入传递给网络的代码可能有问题。在任何操作之前,打印第一层的输入并检查它。
检查一些输入样本是否有正确的标签。还要确保打乱输入样本的方式对于输出标签也一样有效。
也许输入和输出之间的非随机关系相比于随机部分太小(可以说股票价格就是这样)。即输入与输出之间的关系不够紧密。没有通用的方法来检测这个问题,因为这取决于数据的性质。
我曾经在从一个食品网站抓取图像数据集时遇到过这种情况。标签错误太多,以至于网络无法学习。手动检查一批输入样本,看看标签是否有问题。
这一点尚有争议,因为这篇论文在使用 50%标签被破坏的情况下在 MNIST 上达到了超过 50%的准确率。
如果你的数据集没有被打乱,并且有特定的顺序(按标签排序),这可能会对学习产生负面影响。打乱你的数据集以避免这种情况。确保你同时打乱输入和标签。
是否每个类别 B 图像都有 1000 张类别 A 图像?那么你可能需要平衡你的损失函数或尝试其他类别不平衡的方法。
如果你从头开始训练一个网络(即不是微调),你可能需要大量数据。对于图像分类,有人说你每个类别需要 1000 张图像或更多。
在排序的数据集中(即前 10k 个样本包含相同的类别)可能会发生这种情况。通过打乱数据集可以轻松解决。
这篇论文指出,拥有非常大的批次可能会降低模型的泛化能力。
感谢@hengcherkeng的分享:
在测试新的网络架构或编写新代码时,首先使用标准数据集,而不是你自己的数据。这是因为这些数据集有许多参考结果,并且被证明是“可解决的”。不会有标签噪声、训练/测试分布差异、数据集难度过大等问题。
你是否将输入标准化为零均值和单位方差?
数据增强具有正则化效果。过多的增强与其他形式的正则化(如权重 L2、dropout 等)结合使用,可能导致模型欠拟合。
如果你使用了预训练模型,确保你使用的归一化和预处理与训练时的模型一致。例如,图像像素应该在[0, 1]、[-1, 1]还是[0, 255]范围内?
CS231n 指出一个 常见的陷阱:
“… 任何预处理统计(例如数据均值)必须仅在训练数据上计算,然后应用于验证/测试数据。例如,计算均值并从整个数据集的每张图像中减去,然后将数据拆分为训练/验证/测试集将是一个错误。”
同时,检查每个样本或批次中的不同预处理。