深度神经网络在训练数据很少的情况下,很可能会很快过拟合训练数据集。
具有不同模型配置的神经网络集成(Ensembles of neural networks)已知可以减少过拟合,但需要额外计算成本来训练和维护多个模型。
通过在训练期间随机丢弃节点,可以使用单个模型来模拟拥有大量不同网络架构的情况。这被称为衰减(dropout),它提供了一种非常计算成本低且效果显著的正则化方法,可以 减少各种深度神经网络的过拟合和提高泛化误差。
在本帖中,您将发现衰减正则化在减少过拟合和提高深度神经网络泛化能力方面的应用。
阅读本文后,你将了解:
- 神经网络中较大的权重是网络更复杂且过拟合训练数据的迹象。
- 概率性地丢弃网络中的节点是一种简单有效的正则化方法。
- 在使用衰减时,建议使用具有更多训练和权重约束的大型网络。
用我的新书《更好的深度学习》来启动你的项目,书中包含分步教程和所有示例的 Python 源代码文件。
让我们开始吧。

深度神经网络正则化中的 Dropout 简介
照片由 Jocelyn Kinghorn 拍摄,部分权利保留。
概述
本教程分为五个部分;它们是:
- 过拟合的问题
- 随机丢弃节点
- 如何衰减
- 衰减的示例
- 使用衰减正则化的技巧
过拟合的问题
在相对较小的数据集上训练的大型神经网络可能会过拟合训练数据。
这会导致模型学习到训练数据中的统计噪声,从而在评估新数据(例如测试数据集)时表现不佳。由于过拟合,泛化误差会增加。
减少过拟合的一种方法是拟合相同数据集上的所有可能的不同神经网络,并对每个模型的预测进行平均。这在实践中是不可行的,可以通过使用一小组不同的模型(称为集成)来近似。
在计算能力无限的情况下,对固定大小的模型进行“正则化”的最佳方法是平均所有可能的参数设置的预测,并根据训练数据赋予每个设置的后验概率权重。
— 衰减:防止神经网络过拟合的简单方法,2014。
即使是集成近似也存在一个问题,即它需要拟合和存储多个模型,如果模型很大,需要数天或数周的训练和调优,这可能是一个挑战。
随机丢弃节点
衰减是一种正则化方法,它近似于并行训练大量具有不同架构的神经网络。
在训练期间,一些层的输出被随机忽略或“*丢弃*”。这使得该层看起来和行为像一个具有不同节点数量和与前一层连接方式的层。实际上,训练期间层的每次更新都是使用该层配置的“*不同视图*”执行的。
通过丢弃一个单元,意味着将其暂时从网络中移除,以及其所有传入和传出的连接。
— 衰减:防止神经网络过拟合的简单方法,2014。
衰减使训练过程变得嘈杂,迫使层内的节点以概率性方式承担更多或更少的输入责任。
这种概念表明,衰减可能打破了网络层相互适应以纠正前一层错误的情况,从而使模型更加鲁棒。
……单元可能会发生变化,以纠正其他单元的错误。这可能导致复杂的共同适应。反过来,这又会导致过拟合,因为这些共同适应无法泛化到未见过的数据。[…]
— 衰减:防止神经网络过拟合的简单方法,2014。
衰减模拟了给定层的稀疏激活,有趣的是,这反过来又会促使网络实际上学会稀疏表示作为副作用。因此,它可被用作活动正则化的替代方法,以在自动编码器模型中鼓励稀疏表示。
我们发现,作为衰减的副作用,隐藏单元的激活会变得稀疏,即使没有引入稀疏的正则化器。
— 衰减:防止神经网络过拟合的简单方法,2014。
由于衰减下的层输出是随机子采样的,这会减少网络的容量或在训练期间使网络变薄。因此,在使用衰减时,可能需要更宽的网络,例如更多的节点。
想要通过深度学习获得更好的结果吗?
立即参加我为期7天的免费电子邮件速成课程(附示例代码)。
点击注册,同时获得该课程的免费PDF电子书版本。
如何衰减
衰减在神经网络中是逐层实现的。
它可以与大多数类型的层一起使用,例如密集全连接层、卷积层和循环层,如长短期记忆网络层。
衰减可以应用于网络中的任何或所有隐藏层以及可见层或输入层。它不用于输出层。
“衰减”一词是指在神经网络中丢弃单元(隐藏和可见)。
— 衰减:防止神经网络过拟合的简单方法,2014。
引入了一个新的超参数,该超参数指定了层输出被丢弃的概率,或者反过来,层输出被保留的概率。这种解释是一种实现细节,可能因论文或代码库而异。
在隐藏层中,每个节点输出的保留概率通常为0.5,可见层输入的保留概率接近1.0,例如0.8。
在最简单的情况下,每个单元以固定的概率 p 被保留,独立于其他单元,其中 p 可以通过验证集选择,或者简单地设置为 0.5,这似乎对于各种网络和任务都接近最优。然而,对于输入单元,最优保留概率通常更接近 1 而不是 0.5。
— 衰减:防止神经网络过拟合的简单方法,2014。
在训练完成后进行预测时,不使用衰减。
由于衰减,网络的权重将比正常情况大。因此,在最终确定网络之前,首先将权重按选择的衰减率进行缩放。然后可以像平常一样使用该网络进行预测。
如果在训练期间以概率 p 保留一个单元,则该单元的传出权重在测试时乘以 p。
— 衰减:防止神经网络过拟合的简单方法,2014。
权重缩放可以在训练时执行,在每次小批量更新之后。这有时被称为“*反向衰减*”,并且在训练期间不需要修改权重。Keras 和 PyTorch 深度学习库都以这种方式实现衰减。
在测试时,我们按衰减率缩减输出。……请注意,此过程可以通过在训练时执行这两个操作并在测试时保持输出不变来实现,这通常是实际的实现方式。
— 第 109 页,Python 深度学习,2017。
衰减在实践中效果很好,可能取代了权重正则化(例如权重衰减)和活动正则化(例如表示稀疏性)的需要。
……衰减比其他标准的计算成本低廉的正则化器(如权重衰减、滤波器范数约束和稀疏活动正则化)更有效。衰减还可以与其他形式的正则化结合使用,以获得进一步的改进。
— 第 265 页,深度学习,2016。
衰减的示例
本节总结了一些在近期研究论文中使用的衰减示例,以提供如何以及在何处使用的建议。
Geoffrey Hinton 等人在他们于 2012 年发表的、首次引入衰减的论文“通过防止特征检测器协同适应来改进神经网络”中,将该方法应用于各种不同类型的问题,并取得了改进的结果,包括手写数字识别(MNIST)、照片分类(CIFAR-10)和语音识别(TIMIT)。
……我们使用相同的衰减率——所有隐藏单元衰减 50%,可见单元衰减 20%
Nitish Srivastava 等人在他们于 2014 年发表的、引入衰减的期刊论文“衰减:防止神经网络过拟合的简单方法”中,将衰减应用于各种计算机视觉、语音识别和文本分类任务,并发现它在每个问题上都持续提高了性能。
我们训练了用于不同领域数据集分类问题的衰减神经网络。我们发现,与不使用衰减的神经网络相比,衰减在所有数据集上的泛化性能都得到了提高。
在计算机视觉问题上,在网络的层之间使用了不同的衰减率,并结合了最大范数权重约束。
衰减应用于网络的所有层,其中保留单元的概率 p = (0.9, 0.75, 0.75, 0.5, 0.5, 0.5),分别对应于网络中的不同层(从输入到卷积层再到全连接层)。此外,所有权重都使用了最大范数约束 c = 4。[…]
文本分类任务使用了更简单的配置。
我们在输入层使用了 p = 0.8 的保留概率,在隐藏层使用了 p = 0.5 的保留概率。所有层都使用了 c = 4 的最大范数约束。
Alex Krizhevsky 等人在他们著名的 2012 年论文“深度卷积神经网络的 ImageNet 分类”中,通过深度卷积神经网络和衰减正则化在 ImageNet 数据集上的照片分类方面取得了(当时)最先进的成果。
我们在模型的前两个全连接层中使用衰减。没有衰减,我们的网络会表现出显著的过拟合。衰减大约使收敛所需的迭代次数增加一倍。
George Dahl 等人在他们于 2013 年发表的论文“使用线性整流单元和衰减改进深度神经网络以用于 LVCSR”中,使用深度神经网络结合线性整流激活函数和衰减,在标准语音识别任务上取得了(当时)最先进的成果。他们使用贝叶斯优化程序来配置激活函数的选择和衰减的量。
……贝叶斯优化程序发现,对于我们训练的 sigmoid 网络,衰减并没有帮助。总的来说,ReLUs 和衰减似乎搭配得很好。
使用衰减正则化的技巧
本节提供了一些使用神经网络衰减正则化的技巧。
适用于所有网络类型
衰减正则化是一种通用方法。
它可以与大多数(甚至可能所有)类型的神经网络模型一起使用,特别是最常见的网络类型,如多层感知机、卷积神经网络和长短期记忆循环神经网络。
在 LSTM 的情况下,输入和循环连接可能需要使用不同的衰减率。
衰减率
衰减超参数的默认解释是训练层中给定节点的概率,其中 1.0 表示无衰减,0.0 表示该层没有输出。
隐藏层中衰减的良好值为 0.5 到 0.8 之间。输入层使用较高的衰减率,例如 0.8。
使用更大的网络
较大的网络(更多的层或更多的节点)更容易过拟合训练数据。
在使用衰减正则化时,可以冒较小的过拟合风险使用更大的网络。实际上,由于衰减会概率性地降低网络容量,因此可能需要一个大型网络(每层更多的节点)。
一个好的经验法则是,将衰减前的层节点数除以建议的衰减率,并将其用作使用衰减的新网络中的节点数。例如,一个拥有 100 个节点且建议衰减率为 0.5 的网络,在使用衰减时需要 200 个节点(100 / 0.5)。
如果 n 是任何层中的隐藏单元数,p 是保留单元的概率……一个好的衰减网络应该至少有 n/p 个单元。
— 衰减:防止神经网络过拟合的简单方法,2014。
网格搜索参数
与其猜测网络的合适衰减率,不如系统地测试不同的速率。
例如,以 0.1 的增量测试 1.0 到 0.1 之间的值。
这将帮助您发现最适合您特定模型和数据集的方法,以及模型对衰减率的敏感程度。更敏感的模型可能不稳定,并且可能受益于尺寸的增加。
使用权重约束
网络权重将因层激活的概率性移除而增大。
权重过大可能是网络不稳定的迹象。
为了对抗这种影响,可以施加权重约束,强制层中所有权重的范数(幅度)低于指定值。例如,建议使用 3-4 之间的值作为最大范数约束。
[…] 我们可以使用最大范数正则化。这会将每个隐藏单元的传入权重向量的范数限制在一个常数 c 以内。c 的典型值范围是 3 到 4。
— 衰减:防止神经网络过拟合的简单方法,2014。
这确实引入了一个额外的超参数,可能需要为模型进行调优。
与较小的数据集一起使用
与其他正则化方法一样,衰减在训练数据量有限且模型很可能过拟合训练数据的问题上更有效。
训练数据量大的问题可能从使用衰减中获得的益处较少。
对于非常大的数据集,正则化对泛化误差的降低作用很小。在这些情况下,使用衰减和更大的模型的计算成本可能超过正则化的好处。
— 第 265 页,深度学习,2016。
进一步阅读
如果您想深入了解,本节提供了更多关于该主题的资源。
书籍
- 第 7.12 节 衰减,深度学习,2016。
- 第 4.4.3 节 添加衰减,Python 深度学习,2017。
论文
- 通过防止特征检测器协同适应来改进神经网络, 2012.
- Dropout:一种防止神经网络过拟合的简单方法, 2014.
- 使用线性整流单元和衰减改进深度神经网络以用于 LVCSR, 2013.
- 衰减训练作为自适应正则化, 2013.
文章
文章
总结
在本帖中,您发现了衰减正则化在减少过拟合和提高深度神经网络泛化能力方面的应用。
具体来说,你学到了:
- 神经网络中较大的权重是网络更复杂且过拟合训练数据的迹象。
- 概率性地丢弃网络中的节点是一种简单有效的正则化方法。
- 在使用衰减时,建议使用具有更多训练和权重约束的大型网络。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
这有点离题。
为什么您的大部分博文都关注深度学习方法,而不是更适合时间序列数据的其他方法?
好问题,通常是因为我收到的关于深度学习的问题和兴趣是时间序列数据的 100:1 倍,尤其是关于 Python 开源库的深度学习。
那么,如果您在做一个个人项目,您会选择深度学习还是能取得最佳结果的方法?
我选择对项目来说能取得最佳结果且复杂度最低的方法。
感谢分享。这是一个非常容易理解的解释——我期待在我下一个项目中使用它。
谢谢。
太棒了,在 2018 年结束前读到这些。新年快乐,希望 Jason 能有更多精彩内容!
谢谢。
感谢撰写这篇介绍。对初学者来说非常友好。真的很容易理解。很高兴在这里看到这么多通俗易懂的介绍。
谢谢,很高兴您觉得有用!
这是一个奇怪的概念……
在我看来,神经网络中的每个节点都应该有特定的含义(例如,某个节点可以指定分类汽车图片时应该/不应该包含的特定线条)。使用衰减时,您消除了节点这种“含义”。
您对此有何看法?
我认为节点在某种抽象层面上具有“含义”的想法很好,但也要考虑模型具有很多冗余,这有助于其泛化能力。
最后一点“与较小的数据集一起使用”是不正确的。请再次阅读:“对于非常大的数据集,正则化对泛化误差的降低作用很小。在这些情况下,使用衰减和更大的模型的计算成本可能超过正则化的好处。”他们说,对于较小的数据集,正则化效果很好。但是对于较大的数据集,正则化不起作用,最好使用衰减。
在实践中,与小数据相比,大数据上的正则化益处较少。
只是想说您的文章太棒了。很高兴看到一些很棒的示例以及解释。我不会认为自己是人群中最聪明的,但您的解释连我都能够理解——感谢您的发布!
谢谢 Liz,很高兴这些教程对您有帮助!
你好,在我看来,这句
“衰减超参数的默认解释是训练层中给定节点的概率,其中 1.0 表示无衰减,0.0 表示该层没有输出。”
措辞令人困惑,因为它指的是训练节点的概率,而不是节点被“丢弃”的概率。您似乎应该反转它以使其与下一节保持一致,下一节建议在丢弃更多节点时增加更多节点。如上引述所述,较低的衰减率会增加节点数,但我认为应该是反过来的,即节点数随着衰减率的增加而增加(丢弃的节点越多,需要的节点越多)。
B。
感谢您的反馈!
哇,这篇帖子写得非常好。花了时间和实际的努力
写一篇好文章……但又能说什么呢……我犹豫
很多,几乎什么也做不成。
谢谢。
您认为具体是什么原因呢?
嗨,Jason,
我收到您的邮件很久了,只想说它们非常有信息量,并且是一个绝佳的资源。它启发了我创建自己的网站 🙂 所以,谢谢您!
祝好,
保罗
谢谢 Paul!
本文提到“衰减可以应用于网络中的任何或所有隐藏层以及可见层或输入层。它不用于输出层。”
这个说法似乎是不正确的。当使用衰减来防止过拟合时,确实是输入和/或隐藏节点以一定的概率被移除。
当使用 dropconnect(衰减的变体)来防止过拟合时,权重(而不是隐藏/输入节点)以一定的概率被丢弃。因此,在隐藏层和输出层之间的 dropconnect 过程中,输出节点总是有一定的概率被移除。
因此,隐藏和输入/节点都可以以概率性方式移除以防止过拟合。
当然,您说的是 dropconnect。这里我们说的是 dropout。
Jason,非常感谢这篇精彩的帖子!
最终的模型是具有不同网络结构的模型的集成,还是仅一个在训练过程中找到的最佳模型的确定性模型?
不是。只有一个模型,集成只是一个比喻,用来帮助理解内部发生的事情。
谢谢!
不客气。
感谢这篇入门文章。
不客气。
这是一个很棒的总结。我欣赏您使用来源而不是常见的可疑说法的方式。谢谢。
谢谢!
一如既往地棒。
非常感谢。
不客气!
您好,感谢您的文章。我只是想知道,dropout 在线性回归问题中是否也有益。正如帖子中所见,dropout 被应用于分类问题,但它在像眼动跟踪问题等连续输出问题中是否也有用?
不客气。
我不知道,可能没有。也许你可以试试看。
先生,我正在使用单层 LSTM 模型,当我向 LSTM 模型添加 dropout 时,准确率会下降,而在没有 dropout 的情况下准确率非常高,为什么会这样?
在 LSTM 模型中添加 dropout 是一个好方法吗??
添加 dropout 是随机屏蔽输出的一部分,以确保您不依赖于一个证据来生成输出。如果您看到这种情况,很可能意味着您的网络太简单了,以至于每个路径都非常重要。尝试增加一层中的神经元数量或增加层数。这可能有所帮助。
你好 Adrian
有没有关于“dropout”的详细逐行代码,而不仅仅是一个简单的函数“nn.dropout”?
我想自己选择让哪些节点变为零。所以我需要详细的代码。
我正在等待您的回复。
致敬
您可能需要开发自定义代码。Dropout 是随机的(概率性的)。
你好,我使用的是 TensorFlow,你能再澄清一下吗?我猜在 tensorflow.keras.Dropout() 中,rate 是要丢弃的比例,0 表示不丢弃;从这个意义上说,这里使用的约定是相反的(即 1-rate)。我说的对吗?还是我一直以来对 dropout rate 的使用方式都是错的?
https://tensorflowcn.cn/api_docs/python/tf/keras/layers/Dropout
你说得对。
重申最后一点,您的帖子提到
“dropout 超参数的默认解释是训练层中给定节点的概率,其中 1.0 表示不 dropout,0.0 表示该层没有输出。
隐藏层中 dropout 的一个好值在 0.5 到 0.8 之间。输入层使用更大的 dropout 率,例如 0.8。”
而使用 Python tensorflow / keras 文档则表示 ‘rate’ 参数指的是
“0 到 1 之间的浮点数,要丢弃的输入单元的比例”
请参阅 ‘tf.nn.dropout’ 或 ‘tf.keras.layers.Dropout’ 文档。
我只是重申这一点,以便其他人如果选择使用以下 tensorflow / keras 函数进行编码,他们可以使用
0.2 到 0.5
感谢您的反馈!继续努力!
“Dropout Rate
衰减超参数的默认解释是训练层中给定节点的概率,其中 1.0 表示无衰减,0.0 表示该层没有输出。
隐藏层中 dropout 的一个好值在 0.5 到 0.8 之间。输入层使用更大的 dropout 率,例如 0.8。”
这是错误的,0 表示不 dropout。
网站上有很多此类差异。
感谢 Vaibhav 的反馈!
也许这取决于您正在使用的框架。在 pytorch 中,dropout 为零表示不 dropout,即输出等于输入。而 dropout 为一表示所有内容都应被丢弃,输出全为零。
根据 Hinton 等人的说法
“在实践中,丢弃 20% 的输入单元和 50% 的隐藏单元通常被认为是最佳选择。”