Slav Ivanov作者丁楠雅、林亦霖校对王菁 编辑吴金笛翻译

你的神经网络不起作用的37个理由(附链接)

本文列举了在搭建神经网络过程中的37个易错点,并给出了解决建议。

有一个网络已经训练了12个小时。一切看起来都很好:梯度是逐渐变化的,损失在减少。但接下来的预测:都是零,所有的图像背景都没有被检测到。“我做错了什么?”——我问我的电脑,但它没有回答我。

你从哪里开始检查是否你的模型输出了垃圾(例如,预测输出了平均值,或者它的准确性真的很差)?

由于许多原因,神经网络可能不会进行训练。在许多调试过程中,我经常发现自己在做同样的检查。我把我的经验和最好的想法整理在这个便利的列表中,希望它们对你也有用。

目录

  • 1. 如何使用本指南?

  • 2. 数据集问题

  • 3. 数据规范化或增强的问题

  • 4. 实现问题

  • 5. 训练问题

1.如何使用本指南?

很多方面都可能出错。但是其中一些比其他的更有可能被防范。我通常从以下简短的清单开始,作为紧急的第一反应:

  • 1. 从一个已知适用于这类数据的简单模型开始(例如,图像的VGG)。如果可能,使用标准损失。

  • 2. 关闭所有的附加功能,例如正则化和数据增强。

  • 3. 如果对一个模型进行微调,要仔细检查预处理,因为它应该与原始模型的训练相同。

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

  • 5. 从一个非常小的数据集(2-20个样本)开始。对它进行过度拟合,并逐渐添加更多的数据。

  • 6. 开始逐步添加所有被省略的部分:增强/正则化、自定义损失函数、尝试更复杂的模型。

如果上面的步骤没有解决问题,那就根据下面的列表逐一验证。

2.数据集问题

  • 1.检查你的输入数据

检查你向网络输入的数据是否有意义。例如,我不止一次搞混了图像的宽度和高度。有时候,我会错误地输入全0数据。或者我会一遍又一遍地使用相同的批次。因此,打印/显示几批输入和目标输出,以确保它们是正确的。
  • 2.尝试随机输入

尝试传入随机数而不是实际数据,看看错误是否相同。如果是这样,这是一个确定的信号,说明你的网络在某个时候将数据转换为了垃圾。试着一层一层或一个操作一个操作的调试看看哪里出错了。
  • 3. 检查数据加载程序

你的数据可能没问题,但是将输入传递到网络的代码可能会出错。在任何操作之前打印并检查第一层的输入。
  • 4. 确保输入连接到输出

检查一些输入样本是否有正确的标签。同时确保对输入样例进行打乱的方式与输出标签的相同。
  • 5. 输入和输出之间的关系是否过于随机?

也许与随机部分相比,输入输出关系中的非随机部分太小了(人们可能认为股价就是这样的)。即输入与输出不充分相关。没有一种通用的方法来检测这一点,因为这取决于数据的性质。
  • 6. 数据集中是否有太多噪音

当我从一个食品网站上抓取一个图像数据集时,这种情况发生在我身上。有很多网络无法学习的不好的标签。手动检查一批输入样本,看看标签是否正常。

截止点是有争议的,因为此文(https://arxiv.org/pdf/1412.6596.pdf)使用50%损坏的标签使MNIST的准确度达到50%以上。

  • 7. 打乱数据集

如果你的数据集没有被打乱,并且有一个特定的顺序(按标签排序),这可能会对学习产生负面影响。打乱你的数据集以避免这种情况。确保输入和标签打的乱顺序相同。
  • 8. 减少类别不平衡

是否每个B类图像对应1000个A类图像?那么你可能需要平衡你的损失函数或尝试其他类不平衡方法。(https://machinelearningmastery.com/tactics-to-combat-imbalanced-classes-in-your-machine-learning-dataset/)
  • 9. 你有足够的训练样本吗?

如果你正在从零开始训练一个网络(即不是微调),你可能需要大量的数据。对于图像分类,人们认为每个类需要1000张或更多的图像。
(https://stats.stackexchange.com/questions/226672/how-few-training-examples-is-too-few-when-training-a-neural-network/226693#226693)
  • 10. 确保你的批次中不只包含一个标签

 这可能发生在排序的数据集中(即前10k个样本包含相同的类)。通过打乱数据集很容易解决。
  • 11. 减少批量大小

此文(https://arxiv.org/abs/1609.04836)指出,批量较大会降低模型的泛化能力。
 
除了1。使用标准数据集(例如mnist、cifar10)

感谢@hengcherkeng:

当测试新的网络架构或编写新的代码时,首先使用标准数据集,而不是你自己的数据。这是因为这些数据集有很多参考结果,并且它们被证明是“可解的”。不存在标签噪声、训练/测试分布差异、数据集难度过大等问题。

3.数据则正则化或增强

  • 12. 规范的功能

你是否将输入标准化为零均值和单位方差?
  • 13. 你的数据增强太多了吗?

增强具有正则化作用。与其他形式的正则化权重L2、dropout等)结合使用过多会导致网络不匹配。
  • 14. 检查预训练模型的预处理

如果你使用的是预训练模型,请确保使用的规范化和预处理与训练时使用的模型相同。例如,一个图像像素是否应该在[0,1]、[- 1,1]或[0,255]范围内。
  • 15. 检查训练/验证/测试集的预处理

CS231n指出了一个常见的陷阱:

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

此外,检查每个样本或批次的不同预处理。

4.实现问题

  • 16. 试着解决这个问题的简单版本

这将有助于找到问题所在。例如,如果目标输出是一个对象类和坐标,则尝试将预测限制为对象类。
  • 17. “随机”寻找正确的损失

同样来自优秀的CS231n:使用小参数初始化,无需正则化。例如,如果我们有10个类,随机意味着我们将在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. 进行梯度检查

如果你手工实现梯度下降,进行梯度检查可以确保你的反向传播能够正常工作。更多信见:

1 http://ufldl.stanford.edu/tutorial/supervised/DebuggingGradientChecking/

2 http://cs231n.github.io/neural-networks-3/#gradcheck

3https://www.coursera.org/lecture/machine-learning/gradient-checking-Y3s6r

5.训练问题

  • 27. 解决一个非常小的数据集

对一小部分数据进行过度拟合,并确保其工作正常。例如,只训练1或2个例子,看看你的网络能否学会区分这些。继续对每个类别添加更多的示例。
  • 28. 检查权重初始化

如果不确定,请使用Xavier或He初始化。此外,你的初始化可能会导致错误的局部最小值,因此尝试不同的初始化,看看是否有帮助。
  • 29. 更改超参数

也许你使用了一组特别糟糕的超参数。如果可行,尝试网格搜索
  • 30.减少正规化

过多的正则化会导致网络严重不拟合。减少正则化,如dropout、batch norm、weight/bias L2正则化等。在优秀的“程序员实践深度学习”课程中,Jeremy Howard建议首先摆脱不拟合。这意味着你要对训练数据进行充分的过拟合,然后才能解决过拟合问题。
  • 31. 给它时间 

也许你的网络在开始做出有意义的预测之前需要更长的时间来训练。如果你的损失在稳步下降,就再训练更多的时间。
  • 32. 从训练模式切换到测试模式

有些框架具有Batch Norm、Dropout等层,其他层在训练和测试期间的行为有所不同。切换到适当的模式可能有助于你的网络正确预测。
  • 33. 可视化训练

  • 监视每一层的激活、权重和更新。

    确保它们的大小匹配。

    例如,参数更新的大小(权重和偏差)应该是1-e3。

  • 考虑一个可视化库,比如Tensorboard和Crayon。

    在紧要关头,你还可以打印权重/偏差/激活。

  • 注意那些平均值远远大于0的层激活。尝试Batch Norm或ELUs。

  • Deeplearning4j指出了在权重和偏差的直方图中应该期望什么:

“对于权重,这些直方图应该在一段时间后具有近似高斯(正态)分布。对于偏差,这些直方图通常从0开始,并且通常以近似高斯分布结束(LSTM是一个例外)。注意那些发散到+/-∞的参数。注意那些非常大的偏移量。如果类别的分布非常不平衡,有时可能会在输出层中进行分类。”

检查层的更新,他们应该形成一个高斯分布

  • 34. 尝试不同的优化器

你选择的优化器不应该阻止你的网络进行训练,除非你选择了特别糟糕的超参数。然而,合适的任务优化器有助于在最短的时间内获得最多的训练。该论文指出你正在使用的算法应该指定优化器。如果没有,我倾向于使用Adam或带动量的普通SGD。

查看这篇由Sebastian Ruder撰写的优秀文章,了解更多关于梯度下降优化器的知识。

http://ruder.io/optimizing-gradient-descent/
  • 35. 爆炸/消失的梯度

  • 检查层的更新,因为非常大的值可以说明梯度爆炸。梯度剪切可能会有所帮助。

  • 检查层激活。Deeplearning4j提供了一个很好的指导方针:“激活的良好标准偏差在0.5到2.0之间。明显超出这一范围可能意味着消失或爆炸的激活。”

  • 36. 升高/降低学习率

学习率将导致你的模型收敛得非常缓慢。

学习率会在开始时迅速减少损失,但可能很难找到一个好的解决方案。

用你目前的学习速度乘以0.1或10来解决问题。
  • 37. 克服NaN

在训练RNN时,据我所知,得到一个NaN(Non-a-Number)是一个更大的问题。一些解决方法:
  • 降低学习速度,特别是如果你在前100次迭代中得到了NaNs。

  • NaNs可以由除以0,或0或负数的自然对数产生。

  • Russell Stewart在如何应对NaN中有很好的建议。

    http://get.mysecurify.com/view/item_81593.html

  • 试着一层一层地评估你的网络,看看NaNs出现在哪里。

我遗漏什么了吗?有什么错误吗?请在下方留言让我知道。

嗨,朋友,我是Slav,企业家和开发者。此外,我也是SaaS公司Encharge - marketing automation software的联合创始人。

原文标题:37 Reasons why your Neural Network is not working
原文链接:https://blog.slavv.com/37-reasons-why-your-neural-network-is-not-working-4020854bd607
THU数据派
THU数据派

THU数据派"基于清华,放眼世界",以扎实的理工功底闯荡“数据江湖”。发布全球大数据资讯,定期组织线下活动,分享前沿产业动态。了解清华大数据,敬请关注姐妹号“数据派THU”。

入门深度学习其他智能领域神经网络梯度下降
6
相关数据
深度学习技术

深度学习(deep learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。 深度学习是机器学习中一种基于对数据进行表征学习的算法,至今已有数种深度学习框架,如卷积神经网络和深度置信网络和递归神经网络等已被应用在计算机视觉、语音识别、自然语言处理、音频识别与生物信息学等领域并获取了极好的效果。

网格搜索技术

网格搜索是一项模型超参数优化技术,常用于优化三个或者更少数量的超参数,本质是一种穷举法。对于每个超参数,使用者选择一个较小的有限集去探索。然后,这些超参数笛卡尔乘积得到若干组超参数。网格搜索使用每组超参数训练模型,挑选验证集误差最小的超参数作为最好的超参数。

权重技术

线性模型中特征的系数,或深度网络中的边。训练线性模型的目标是确定每个特征的理想权重。如果权重为 0,则相应的特征对模型来说没有任何贡献。

Dropout技术

神经网络训练中防止过拟合的一种技术

高斯分布技术

正态分布是一个非常常见的连续概率分布。由于中心极限定理(Central Limit Theorem)的广泛应用,正态分布在统计学上非常重要。中心极限定理表明,由一组独立同分布,并且具有有限的数学期望和方差的随机变量X1,X2,X3,...Xn构成的平均随机变量Y近似的服从正态分布当n趋近于无穷。另外众多物理计量是由许多独立随机过程的和构成,因而往往也具有正态分布。

VGG技术

2014年,牛津大学提出了另一种深度卷积网络VGG-Net,它相比于AlexNet有更小的卷积核和更深的层级。AlexNet前面几层用了11×11和5×5的卷积核以在图像上获取更大的感受野,而VGG采用更小的卷积核与更深的网络提升参数效率。VGG-Net 的泛化性能较好,常用于图像特征的抽取目标检测候选框生成等。VGG最大的问题就在于参数数量,VGG-19基本上是参数量最多的卷积网络架构。VGG-Net的参数主要出现在后面两个全连接层,每一层都有4096个神经元,可想而至这之间的参数会有多么庞大。

参数技术

在数学和统计学裡,参数(英语:parameter)是使用通用变量来建立函数和变量之间关系(当这种关系很难用方程来阐述时)的一个数量。

收敛技术

在数学,计算机科学和逻辑学中,收敛指的是不同的变换序列在有限的时间内达到一个结论(变换终止),并且得出的结论是独立于达到它的路径(他们是融合的)。 通俗来说,收敛通常是指在训练期间达到的一种状态,即经过一定次数的迭代之后,训练损失和验证损失在每次迭代中的变化都非常小或根本没有变化。也就是说,如果采用当前数据进行额外的训练将无法改进模型,模型即达到收敛状态。在深度学习中,损失值有时会在最终下降之前的多次迭代中保持不变或几乎保持不变,暂时形成收敛的假象。

学习率技术

在使用不同优化器(例如随机梯度下降,Adam)神经网络相关训练中,学习速率作为一个超参数控制了权重更新的幅度,以及训练的速度和精度。学习速率太大容易导致目标(代价)函数波动较大从而难以找到最优,而弱学习速率设置太小,则会导致收敛过慢耗时太长

损失函数技术

在数学优化,统计学,计量经济学,决策理论,机器学习和计算神经科学等领域,损失函数或成本函数是将一或多个变量的一个事件或值映射为可以直观地表示某种与之相关“成本”的实数的函数。

超参数技术

在机器学习中,超参数是在学习过程开始之前设置其值的参数。 相反,其他参数的值是通过训练得出的。 不同的模型训练算法需要不同的超参数,一些简单的算法(如普通最小二乘回归)不需要。 给定这些超参数,训练算法从数据中学习参数。相同种类的机器学习模型可能需要不同的超参数来适应不同的数据模式,并且必须对其进行调整以便模型能够最优地解决机器学习问题。 在实际应用中一般需要对超参数进行优化,以找到一个超参数元组(tuple),由这些超参数元组形成一个最优化模型,该模型可以将在给定的独立数据上预定义的损失函数最小化。

验证集技术

验证数据集是用于调整分类器超参数(即模型结构)的一组数据集,它有时也被称为开发集(dev set)。

神经网络技术

(人工)神经网络是一种起源于 20 世纪 50 年代的监督式机器学习模型,那时候研究者构想了「感知器(perceptron)」的想法。这一领域的研究者通常被称为「联结主义者(Connectionist)」,因为这种模型模拟了人脑的功能。神经网络模型通常是通过反向传播算法应用梯度下降训练的。目前神经网络有两大主要类型,它们都是前馈神经网络:卷积神经网络(CNN)和循环神经网络(RNN),其中 RNN 又包含长短期记忆(LSTM)、门控循环单元(GRU)等等。深度学习是一种主要应用于神经网络帮助其取得更好结果的技术。尽管神经网络主要用于监督学习,但也有一些为无监督学习设计的变体,比如自动编码器和生成对抗网络(GAN)。

梯度下降技术

梯度下降是用于查找函数最小值的一阶迭代优化算法。 要使用梯度下降找到函数的局部最小值,可以采用与当前点的函数梯度(或近似梯度)的负值成比例的步骤。 如果采取的步骤与梯度的正值成比例,则接近该函数的局部最大值,被称为梯度上升。

噪音技术

噪音是一个随机误差或观测变量的方差。在拟合数据的过程中,我们常见的公式$y=f(x)+\epsilon$中$\epsilon$即为噪音。 数据通常包含噪音,错误,例外或不确定性,或者不完整。 错误和噪音可能会混淆数据挖掘过程,从而导致错误模式的衍生。去除噪音是数据挖掘(data mining)或知识发现(Knowledge Discovery in Database,KDD)的一个重要步骤。

规范化技术

规范化:将属性数据按比例缩放,使之落入一个小的特定区间,如-1.0 到1.0 或0.0 到1.0。 通过将属性数据按比例缩放,使之落入一个小的特定区间,如0.0到1.0,对属性规范化。对于距离度量分类算法,如涉及神经网络或诸如最临近分类和聚类的分类算法,规范化特别有用。如果使用神经网络后向传播算法进行分类挖掘,对于训练样本属性输入值规范化将有助于加快学习阶段的速度。对于基于距离的方法,规范化可以帮助防止具有较大初始值域的属性与具有较小初始值域的属相相比,权重过大。有许多数据规范化的方法,包括最小-最大规范化、z-score规范化和按小数定标规范化。

过拟合技术

过拟合是指为了得到一致假设而使假设变得过度严格。避免过拟合是分类器设计中的一个核心任务。通常采用增大数据量和测试样本集的方法对分类器性能进行评价。

正则化技术

当模型的复杂度增大时,训练误差会逐渐减小并趋向于0;而测试误差会先减小,达到最小值后又增大。当选择的模型复杂度过大时,过拟合现象就会发生。这样,在学习时就要防止过拟合。进行最优模型的选择,即选择复杂度适当的模型,以达到使测试误差最小的学习目的。

动量技术

优化器的一种,是模拟物理里动量的概念,其在相关方向可以加速SGD,抑制振荡,从而加快收敛

批次技术

模型训练的一次迭代(即一次梯度更新)中使用的样本集。

图像分类技术

图像分类,根据各自在图像信息中所反映的不同特征,把不同类别的目标区分开来的图像处理方法。它利用计算机对图像进行定量分析,把图像或图像中的每个像元或区域划归为若干个类别中的某一种,以代替人的视觉判读。

优化器技术

优化器基类提供了计算梯度loss的方法,并可以将梯度应用于变量。优化器里包含了实现了经典的优化算法,如梯度下降和Adagrad。 优化器是提供了一个可以使用各种优化算法的接口,可以让用户直接调用一些经典的优化算法,如梯度下降法等等。优化器(optimizers)类的基类。这个类定义了在训练模型的时候添加一个操作的API。用户基本上不会直接使用这个类,但是你会用到他的子类比如GradientDescentOptimizer, AdagradOptimizer, MomentumOptimizer(tensorflow下的优化器包)等等这些算法。

推荐文章
暂无评论
暂无评论~