神经网络中梯度爆炸问题的简明介绍

爆炸梯度是一种问题,在该问题中,大的误差梯度累积,导致在训练期间神经网络模型权重的更新非常大。

这会使您的模型不稳定,无法从您的训练数据中学习。

在本文中,您将了解深度人工神经网络中的爆炸梯度问题。

完成这篇文章后,您将了解:

  • 爆炸梯度是什么以及它们在训练过程中引起的问题。
  • 如何知道您的网络模型是否存在爆炸梯度。
  • 如何解决您网络中的爆炸梯度问题。

立即开始您的项目,阅读我的新书 《Python长短期记忆网络》,其中包含分步教程和所有示例的Python源代码文件。

让我们开始吧。

  • 更新于2018年10月:已删除对ReLU作为解决方案的提及。
A Gentle Introduction to Exploding Gradients in Recurrent Neural Networks

递归神经网络中爆炸梯度入门指南
照片由 Taro Taylor 拍摄,保留部分权利。

什么是爆炸梯度?

误差梯度是神经网络训练过程中计算出的方向和大小,用于以正确的方向和正确的量更新网络权重。

在深度网络或递归神经网络中,误差梯度会在更新过程中累积,导致非常大的梯度。这些反过来会导致网络权重产生大的更新,从而导致网络不稳定。在极端情况下,权重的值可能会变得非常大,以至于溢出并导致NaN值。

爆炸通过具有大于1.0的值的网络层重复乘以梯度的指数增长而发生。

爆炸梯度有什么问题?

在深度多层感知机网络中,爆炸梯度可能导致网络不稳定,该网络最多只能从训练数据中学习,最坏的情况是导致NaN权重值,这些值无法再更新。

…爆炸梯度可能导致学习不稳定。

— 第282页,《深度学习》,2016年。

在递归神经网络中,爆炸梯度可能导致网络不稳定,无法从训练数据中学习,最多也只能使网络无法学习长序列数据。

…爆炸梯度问题是指在训练过程中梯度的范数急剧增加。此类事件是由于长期成分的爆炸造成的

— 《训练递归神经网络的困难》,2013年。

如何知道您是否存在爆炸梯度?

在训练您的网络时,可能存在一些细微迹象表明您遭受了爆炸梯度,例如

  • 模型无法在您的训练数据上获得牵引力(例如,损失差)。
  • 模型不稳定,导致损失从一次更新到下一次更新发生大的变化。
  • 模型损失在训练过程中变为NaN。

如果您遇到这类问题,您可以深入研究以查看是否存在爆炸梯度问题。

有一些不太微妙的迹象可以用来确认您是否存在爆炸梯度。

  • 模型权重在训练过程中很快变得非常大。
  • 模型权重在训练过程中变为NaN值。
  • 在训练过程中,每个节点和层的误差梯度值始终大于1.0。

如何解决爆炸梯度?

有许多解决爆炸梯度的方法;本节列出了一些您可以使用的最佳实践方法。

1. 重新设计网络模型

在深度神经网络中,可以通过重新设计网络以减少层数来解决爆炸梯度问题。

在训练网络时使用较小的批量大小也可能有一些好处。

在递归神经网络中,在训练过程中更新的先前时间步长更少,称为截断反向传播,可能会减少爆炸梯度问题。

2. 使用长短期记忆网络

在递归神经网络中,由于该类型网络训练的固有不稳定性,可能会发生梯度爆炸,例如通过反向传播(本质上将递归网络转换为深度多层感知机神经网络)。

通过使用长短期记忆(LSTM)记忆单元和可能的相关的门控类型神经元结构,可以减少爆炸梯度。

采用LSTM记忆单元是用于序列预测的递归神经网络的新最佳实践。

3. 使用梯度裁剪

对于具有大批量大小的非常深的感知机网络和具有非常长输入序列长度的LSTM,仍然可能发生爆炸梯度。

如果爆炸梯度仍然发生,您可以在训练网络时检查并限制梯度的大小。

这称为梯度裁剪。

处理爆炸梯度有一个简单但非常有效的解决方案:如果梯度的范数超过给定的阈值,则裁剪梯度。

— 第5.2.4节,“神经网络在自然语言处理中的方法”,2017年。

具体来说,会检查误差梯度的值是否超过阈值,如果误差梯度超过阈值,则将其裁剪或设置为该阈值。

在某种程度上,可以通过梯度裁剪(在执行梯度下降步骤之前对梯度值进行阈值处理)来缓解爆炸梯度问题。

— 第294页,《深度学习》,2016年。

在Keras深度学习库中,您可以在训练之前通过在优化器上设置clipnormclipvalue参数来使用梯度裁剪。

好的默认值是clipnorm=1.0clipvalue=0.5

4. 使用权重正则化

另一种方法是,如果爆炸梯度仍然发生,可以检查网络权值的大小,并对网络的损失函数中的大权值应用惩罚。

这称为权重正则化,通常可以使用L1(绝对值权重)或L2(平方权重)惩罚。

对递归权重使用L1或L2惩罚有助于解决爆炸梯度问题

— 《训练递归神经网络的困难》,2013年。

在Keras深度学习库中,您可以通过在层上设置kernel_regularizer参数并使用L1L2正则化器来使用权重正则化。

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

文章

书籍

论文

文章

Keras API

总结

在本文中,您了解了训练深度神经网络模型时爆炸梯度的问题。

具体来说,你学到了:

  • 爆炸梯度是什么以及它们在训练过程中引起的问题。
  • 如何知道您的网络模型是否存在爆炸梯度。
  • 如何解决您网络中的爆炸梯度问题。

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

立即开发用于序列预测的 LSTM!

Long Short-Term Memory Networks with Python

在几分钟内开发您自己的 LSTM 模型。

...只需几行python代码

在我的新电子书中探索如何实现
使用 Python 构建长短期记忆网络

它提供关于以下主题的自学教程
CNN LSTM、编码器-解码器 LSTM、生成模型、数据准备、进行预测等等...

最终将 LSTM 循环神经网络引入。
您的序列预测项目。

跳过学术理论。只看结果。

查看内容

41条关于神经网络爆炸梯度入门指南的回复

  1. Nolan 2017年12月18日 上午7:55 #

    我曾在优化问题中使用复杂的梯度,这有助于解决这个问题。这种做法是否存在于神经网络中?

  2. Sabah 2017年12月18日 上午11:19 #

    感谢您提供研究论文和其他文献的链接。
    您认为对深度学习前沿方法感兴趣的人该如何跟进最新的研究?
    arXiv上有很多论文,很难决定读哪些或跳过哪些。

    • Jason Brownlee 2017年12月18日 下午3:28 #

      我建议关注一两年前有效的技术。最前沿的噪音太大,其中大部分是明年将不再有用的噪音。

  3. Amir Hossein 2017年12月18日 下午12:24 #

    谢谢你的文章。非常有帮助。这些解决爆炸梯度的修复方法也可以添加到列表中

    1. 谨慎初始化权重,例如“Xavier”初始化或“He”初始化。
    2. 执行梯度检查:有时错误发生在代码中的某个实现错误时;除非您使用的是Tensorflow反向传播等预打包库。如果您从头开始实现了网络,则进行GD检查

  4. Yateen Gupta 2017年12月18日 下午6:26 #

    谢谢 Jason 的文章。但我对 Sigmoid 或 Tanh 函数是否是爆炸梯度的原因感到疑惑。由于它们的导数对于大值和小的激活值趋向于零,它们确实会导致梯度消失。那么它们如何导致梯度爆炸呢?

    • jiaqi,zhang 2017年12月19日 下午6:11 #

      在“如何解决爆炸梯度”部分的方法中

      1 sigmoid->relu
      sigmoid 的梯度是 f(1-f),它在 (0,1) 之间;而 ReLU 的梯度是 {0,1}。这种替换如何解决爆炸梯度?

      2 lstm
      LSTM 通过替换乘法与加法来修复梯度消失,将长期依赖信息传递到最后一步;而且,我认为这种方法无法解决梯度爆炸问题。

      希望得到回复,谢谢

      • Xavier Qiu 2018年8月23日 上午6:13 #

        实际上,sigmoid 的梯度在 0 和 0.25 之间。希望能得到对这两个问题的解释。

  5. Rob vermillion 2017年12月19日 上午8:43 #

    在哪里可以找到可在 Chromebook 上使用的机器学习程序?Chromebook 不允许下载任何使用程序。

  6. general 2017年12月22日 下午11:33 #

    精彩的阅读,谢谢!

  7. Brad 2018年2月16日 上午9:01 #

    我推荐这篇相对较新的论文
    https://arxiv.org/abs/1712.05577

  8. Anil 2018年2月26日 下午10:39 #

    我认为 ReLU 用于处理梯度消失,而不是爆炸梯度。我说得对吗?

  9. Kaan Yilmaz 2018年10月15日 上午2:01 #

    ReLU 如何减小爆炸梯度问题?ReLU 函数对于局部正场是无界的。这意味着 ReLU 不会限制其对局部场>0 的输出。由于 ReLU 的输出将是另一个 ReLU 的输入,输出将由于累积乘法而爆炸。不是因为这个,ReLU 是导致爆炸梯度问题的原因之一吗?

    • Jason Brownlee 2018年10月15日 上午7:32 #

      确实,ReLU 解决了梯度消失问题。

      已修复。

      • Radhouane Baba 2019年10月9日 上午5:37 #

        不知何故,当我从 ReLU 切换到 Sigmoid 时,我从未遇到过爆炸梯度问题……

        • Jason Brownlee 2019年10月9日 上午8:16 #

          这种情况并非总是发生,但网络越深,或者输入越大,就越有可能爆炸(或消失)。

          • Radhouane Baba 2019年10月9日 下午7:28 #

            您认为我应该为此使用 Sigmoid(在 LSTM 中)吗?还是它已经过时了?

          • Jason Brownlee 2019年10月10日 上午6:56 #

            我相信 LSTM 使用 Sigmoid 和 Tanh 来实现不同的门。

            在 LSTM 中使用 ReLU 也可以很有效。

  10. Sina 2019年10月9日 上午6:38 #

    嗨,Jason,

    感谢您的帖子。
    长短期记忆网络如何直接影响梯度爆炸?
    我没有看到任何联系。此外,我认为这可能不是一种普遍适用的方法,因为许多应用都不是 LSTM 友好的,也就是说,其他架构可能是更好的选择。
    谢谢

    • Jason Brownlee 2019年10月9日 上午8:18 #

      LSTM 降低了反向传播过程中梯度爆炸的可能性。也许可以比较一下 LSTM 和 SimpleRNN 在同一个问题上的表现?

  11. Lukas 2020年2月16日 上午7:31 #

    看到文章的“您将学到什么”和“结论”比实际内容还长,真是令人沮丧。

  12. Guney 2020年4月3日 上午8:37 #

    嗨,Jason,

    我以前没有遇到过这种情况,但读了您的帖子让我对此感到好奇。您认为在一个小的前馈神经网络(例如一个隐藏层)中是否可能观察到爆炸梯度问题?如果可能,为什么会发生这种情况?

    非常感谢

  13. Jessy 2020年10月16日 下午6:55 #

    嗨,
    Swish 激活应该在隐藏层中使用。或者我可以在输入层使用它吗?
    Swish 激活可以用来替换 LSTM 架构中的 Sigmoid 激活。可能吗?

  14. Allen 2021年5月5日 上午5:58 #

    这里还有一些未提及的方法。
    1 – 对激活层进行归一化,如 Batch Normalization、Layer Normalization 等。
    2 – 对权重进行归一化,如谱归一化。
    3 – 使用带有跳跃连接的模块,如残差块。

  15. vitor 2022年1月19日 上午10:57 #

    我可以对输入值进行分数化,也可以使用 LOG10。

    • James Carmichael 2022年1月20日 上午7:56 #

      感谢您的反馈 Vitor!

  16. Abolfazl 2023年11月20日 上午5:40 #

    我有一点不明白,如果我们用大的权重进行初始化,然后对我们的损失函数关于我们的参数求导,我们会得到大的梯度,然后在更新参数时,我们从旧参数中减去大的梯度,这会减小我们参数的大小。
    我不明白这里有什么问题

发表回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。