当我的神经网络不能很好地泛化时我该怎么办?

机器算法验证 神经网络 过拟合 常问问题
2022-02-09 06:03:52

我正在训练一个神经网络并且训练损失减少了,但验证损失没有,或者它减少的比我预期的要少得多,基于非常相似的架构和数据的参考或实验。我怎样才能解决这个问题?


至于问题

当我的神经网络不学习时我该怎么办?

对于这个问题的启发,这个问题是有意留下的,以便其他关于如何将神经网络的泛化误差降低到已被证明可以达到的水平的问题,可以作为这个问题的重复而关闭。

另请参阅 Meta 上的专用线程:

是否存在一个通用问题,我们可以将“为什么我的神经网络不能很好地泛化”类型的问题重定向到该问题?

4个回答

首先,让我们提一下“我的神经网络不能很好地泛化”是什么意思,和“我的神经网络性能不好”有什么区别

在训练神经网络时,您会不断地在一组称为训练集的标记数据上对其进行评估。如果您的模型不能正常工作并且似乎没有从训练集中学习,那么您还没有泛化问题,请参阅这篇文章但是,如果您的模型在训练集上取得了令人满意的性能,但在以前看不见的数据(例如验证/测试集)上表现不佳,那么您确实存在泛化问题。

为什么你的模型没有正确泛化?

最重要的部分是理解为什么你的网络不能很好地泛化。大容量机器学习模型具有记忆训练集的能力,这可能导致过度拟合

过度拟合是估计器已经开始很好地学习训练集以至于它已经开始对训练样本中的噪声进行建模(除了所有有用的关系)的状态。

例如,在下图中,我们可以看到右行的蓝色是如何明显过拟合的。

但是为什么会这样呢?

当试图在新的、以前看不见的数据(即验证/测试集)上评估我们的模型时,模型的性能将比我们预期的要差得多。

如何防止过拟合?

在帖子的开头,我暗示您的模型的复杂性实际上是导致过度拟合的原因,因为它允许模型从训练集中提取不必要的关系,从而映射其固有的噪声。减少过度拟合的最简单方法是从本质上限制模型的容量。这些技术称为正则化技术。

  • 参数规范惩罚这些为每个模型的权重更新函数添加了一个额外的项,这取决于参数的范数。该术语的目的是对抗实际更新(即限制每个权重可以更新多少)。这使得模型对异常值和噪声更加鲁棒。此类正则化的示例是L1 和 L2正则化,可以在LassoRidgeElastic Net回归器上找到。
    由于神经网络中的每个(完全连接的)层的功能很像简单的线性回归,因此这些都用于神经网络。最常见的用途是分别对每一层进行正则化。
    keras 实现

  • 早停这种技术试图过早停止估计器的训练阶段,在它学会从数据中提取所有有意义的关系时,然后开始对其噪声进行建模。这是通过监控验证损失(或您选择的验证指标)并在该指标停止改进时终止训练阶段来完成的这样,我们给估计器足够的时间来学习有用的信息,但不足以从噪声中学习。keras 实现

  • 神经网络特定的正则化。一些例子是:
    • 辍学Dropout是一种有趣的技术,效果非常好。Dropout 应用于网络中的两个连续层之间。在每次迭代中,连接两层的指定百分比的连接(随机选择)被丢弃这导致后续层依赖于其与前一层的所有连接。
      keras 实现
    • 迁移学习这特别用于深度学习。这是通过将您的网络的权重初始化为另一个网络的权重来完成的,该网络具有在大型通用数据集上预训练的相同架构。
    • 其他可能限制深度神经网络过度拟合的因素是:批量标准化,它可以作为一个调节器,在某些情况下(例如 inception 模块)和 dropout 一样有效;SGD 中相对较小的批次,也可以防止过拟合;在隐藏层的权重中添加小的随机噪声。

除了限制模型的容量之外,防止过度拟合的另一种方法是提高数据的质量。最明显的选择是去除异常值/噪声,但实际上它们的用处有限。一种更常见的方式(尤其是在与图像相关的任务中)是数据增强在这里,我们尝试随机变换训练示例,以便在模型看来它们不同时,它们传达相同的语义信息(例如,左右翻转图像)。
数据增强概述

实用建议:

  • 到目前为止,最有效的正则化技术是dropout,这意味着您应该首先使用它。但是,您不需要(也可能不应该)到处放置 dropout!最容易过拟合的层是全连接(FC)层,因为它们包含的参数最多。Dropout 应该应用于这些层(影响它们与下一层的连接)。
  • 批量归一化,除了具有正则化效果之外,还可以通过其他几种方式帮助您的模型(例如,加速收敛,允许使用更高的学习率)。它也应该在 FC 层中使用。
  • 如前所述,在训练阶段比预定时间更早地停止模型也可能是有益的。提前停止的问题在于,无法保证在任何给定点上,模型都不会再次开始改进。比提前停止更实用的方法是存储在验证集上实现最佳性能的模型的权重。但是要小心,因为这不是对模型性能的无偏估计(只是比训练集好)。还可以在验证集上过拟合。稍后再谈。
    keras 实现
  • 在某些应用程序(例如与图像相关的任务)中,强烈建议遵循已经建立的架构(例如 VGG、ResNet、Inception),您可以找到 ImageNet 的权重。该数据集的通用性允许特征反过来足够通用以用于任何与图像相关的任务。除了对过度拟合具有鲁棒性外,这将大大减少训练时间。
    类似概念的另一种用法如下:如果您的任务没有太多数据,但您可以找到另一个类似的任务,您可以使用迁移学习来减少过度拟合。首先针对具有较大数据集的任务训练您的网络,然后尝试微调将模型设置为您最初想要的模型。在大多数情况下,初始训练将使您的模型对过度拟合更加稳健。
  • 数据增强虽然拥有更大的数据集总是有帮助的,但数据增强技术确实有其缺点。更具体地说,您必须小心不要过于强烈地扩充,因为这可能会破坏数据的语义内容。例如,在图像增强中,如果您过度平移/移动/缩放或调整图像的亮度/对比度,您将丢失其中包含的大部分信息。此外,需要以特别的方式为每个任务实施增强方案(例如,在手写数字识别中,数字通常是对齐的,不应该旋转太多;也不应该向任何方向翻转,因为它们不是水平/垂直对称的。医学图像也是如此)。
    简而言之,注意不要通过数据增强产生不真实的图像。此外,增加的数据集大小将需要更长的训练时间。就个人而言,当我看到我的模型在训练集上接近损失时,我开始考虑使用数据增强。0

有大量经验证据表明,足够深的神经网络可以记住大量数据集上的随机标签(Chiyuan Zhang、Samy Bengio、Moritz Hardt、Benjamin Recht、Oriol Vinyals,“理解深度学习需要重新思考泛化”)。因此,原则上,通过获得足够大的 NN,我们总是可以将训练误差降低到极小的值,在实践中受到数值准确性的限制,无论任务多么无意义。

泛化错误的情况完全不同我们不能确定对于每个学习问题,是否存在一个可学习的 NN 模型,该模型可以产生尽可能低的泛化误差。为此,第一步是

1.正确设定你的期望

找到一个有信誉的参考资料,它告诉您存在一种架构,可以在您的数据集或您可以找到参考资料的最相似的数据集上达到您正在寻找的泛化错误。例如,看这里

目前最先进的卷积神经网络有哪些?

查找 CNN 在各种任务上的当前(在回答时)SOTA(最先进的)性能。在您对自己的数据集进行训练之前,尝试在这些参考数据集上重现此类结果是一个好主意,以测试您的所有基础设施是否正确。

2. 确保您的培训程序完美无缺

问题答案中描述的所有检查

当我的神经网络不学习时我该怎么办?

确保您的训练过程正常,是成功减少泛化错误的先决条件(如果您的 NN 不学习,它就无法学习泛化)。这些检查包括,除其他外:

  • 单元测试
  • 数据集检查(查看训练集和测试集的一些随机输入/标签样本,并检查标签是否正确;检查输入图像的宽度和大小;在训练/测试集中打乱样本,看看它是否影响结果;等)
  • 随机化测试
  • 标准化您的预处理和包版本
  • 保留数值实验日志

3. 尝试获得超收敛

Leslie N. Smith 和 Nicholay Topin的“超收敛:使用大学习率对神经网络进行非常快速的训练”表明,在某些情况下,大学习率与 Leslie N. Smith 的循环学习率方法的组合充当了正则化器,将收敛速度加快一个数量级,并减少对广泛正则化的需求。因此,这是一件好事之前尝试

4. 将正则化设置为 MAXXX

正则化通常会增加训练时间(坏),增加训练误差并减少泛化误差(好),但过多的正则化实际上会增加两个错误(欠拟合)。出于这个原因,并且由于训练时间的增加,您成功地设法过拟合训练集之后,通常最好一次引入各种正则化技术。请注意,正则化本身并不一定意味着您的泛化误差会变小:模型必须具有足够大的容量才能实现良好的泛化特性。这通常意味着您需要一个足够深的网络,然后才能看到正则化的好处。

最古老的正则化方法可能是提前停止和权重衰减。其他一些:

  • 减少批大小:较小的批大小通常与较小的泛化错误相关,因此可以尝试一下。但是,请注意有些人质疑 minibatch 的用处:根据我的经验,它们会有所帮助(只要您不必使用疯狂的小尺寸,例如),但是 Elad Hoffer、Itay Hubara、Daniel Soudry 的训练时间更长,更好地泛化:缩小神经网络大批量训练中的泛化差距不同意。请注意,如果您使用批量规范(见下文),那么小批量将非常有害。m=16
  • 使用 SGD 而不是自适应优化器:@shimao 已经涵盖了这一点,因此我只是为了完整起见而提及它
  • 使用 dropout:如果您使用 LSTM,请仅对 LSTM 层的输入和输出单元使用标准 dropout。对于循环单元(门),使用循环辍学,正如 Yarin Gal在他的博士论文中首次展示的那样。论文但是,如果您使用 CNN,则现在使用 dropout 的频率较低。相反,你倾向于……
  • ...使用批量归一化:最新的 CNN 架构避开辍学,转而支持批量归一化。这可能只是一种时尚,也可能是因为 dropout 和 batch normalization 显然不能很好地结合在一起(Xiang Li、Shuo Chen、Xiaolin Hu、Jian Yang,Understanding the Disharmony between Dropout and Batch Normalization by Variance移)。由于当您拥有大量数据集时,batch norm 比 dropout 更有效,这可能是 dropout 在 CNN 架构中失宠的原因。如果您使用批量标准化,请验证每一层的权重和偏差分布看起来是否接近标准正态。对于 RNN,实现批量标准化很复杂:权重标准化(Tim Salimans,Diederik P. Kingma,Weight Normalization: A Simple Reparameterization to Accelerate Training of Deep Neural Networks ) 是一种可行的替代方案。
  • 使用数据增强:它还具有正则化效果。

5.超参数/架构搜索

如果没有其他帮助,您将不得不测试多个不同的超参数设置(贝叶斯优化在这里可能会有所帮助)或多个不同的架构更改(例如,可能在您的 GAN 架构和您正在处理的数据集中,批处理规范仅适用于生成器,但是当添加到鉴别器时也会使事情变得更糟)。请务必在井井有条的日志中记录这些漫长而无聊的实验结果。

PS 对于 GAN,谈论泛化错误没有多大意义:上面的例子只是为了表明深度学习中仍有很多炼金术,你希望能正常工作的东西,有时不要't,或者反之亦然,一些多次运行良好的东西,突然对你产生了新的数据集。

我在文献中看到的常用正则化技术列表是:

  1. 使用批量归一化,这是一种非常有效的正则化器,以至于我很少看到再使用 dropout,因为它根本没有必要。
  2. 少量重量衰减。
  3. 一些较新的正则化技术包括Shake-shake(Xavier Gastaldi 的“Shake-Shake regularization”)和Cutout(Terrance DeVries 和 Graham W. Taylor 的“Improved Regularization of Convolutional Neural Networks with Cutout”)。特别是,可以轻松实现 Cutout 使其非常有吸引力。我相信这些比辍学效果更好——但我不确定。
  4. 如果可能的话,更喜欢全卷积架构而不是全连接层架构。将 VGG-16 与在单个全连接层中具有 1 亿个参数的 VGG-16 与具有 10 倍层数且参数更少的 Resnet-152 进行比较。
  5. 与 Rmsprop 和 Adam 等其他优化器相比,更喜欢 SGD。它已被证明可以更好地概括。(Nitish Shirish Keskar 和 Richard Socher 的“通过从 Adam 切换到 SGD 来提高泛化性能”)

我觉得 Djib2011 对自动化方法给出了很好的观点,但它们并没有真正解决我们如何知道用于减少过度拟合的方法是否发挥作用的根本问题。因此,作为 DeltaIV 答案的重要脚注,我想根据过去 2 年的最新研究将其包括在内。神经网络的过度拟合不仅与模型过度记忆有关,还与模型无法学习新事物或处理异常有关。

检测黑盒模型中的过度拟合:模型的可解释性直接与您判断模型泛化能力的能力有关。因此,许多可解释的图都是检测过拟合的方法,可以告诉你上面建议的任何方法的效果如何。可解释性图直接检测到它,尤其是在您比较验证图和测试结果图时。这本未出版的书的第 5 章和第 6 章讨论了过拟合领域检测的最新进展:可解释建模

根据这本书,我想提一下其他三种检测和消除过拟合的方法,这对某些人来说可能很明显,但我个人发现人们经常忘记这些。因此,如果不是一个想法,我想强调它们:

  1. 特征选择检测:模型具有的参数数量和特征越少越好。因此,如果您只包括 1 亿个中的重要部分(可能有 7500 万个),您将拥有一个更好的泛化模型。问题是许多神经网络在特征选择方面并不完美,尤其是当 #2 存在时。Bootstrap 或 Boosting 从根本上无法同时解决这两个问题(只有一个名为 wild bootstrap 的版本可以)。简单来说,如果你给你神经网络垃圾数据,那么它就会给你垃圾。(上面提到的 L2 Normalization 非常擅长帮助解决这个问题)

  2. 检测和处理异常: “异常值”越少,模型越通用。“异常值”不仅指数据中的异常值。数据中的异常值(如您在箱线图中看到的那种)对于神经网络来说是一个过于狭隘的定义。您还需要考虑模型误差中的异常值(称为影响)以及其他异常情况。因此,在运行网络之前检测异常非常重要。神经网络可以对一种类型的异常具有鲁棒性,但不能对所有其他类型的异常具有鲁棒性。反例方法、批评方法、对抗性示例方法和影响图非常适合帮助您发现异常值,然后弄清楚如何将它们考虑在内。(即更改参数甚至删除一些数据)

  3. 基于统计或伦理考虑的分层抽样、过抽样和欠抽样:我希望我是欠抽样和过抽样方面的专家,但我不是,但我知道分层抽样。对重要因素(例如种族、性别、性别)进行聚类,然后按聚类进行分层抽样对于在考虑大数据时不过度拟合至关重要。在进行图像检测时,在某些领域法律要求分层抽样与聚类相结合,以避免种族歧视。上面链接的书简要介绍了执行此操作的方法。

PS我应该包含更多链接吗?