循环神经网络的问题:梯度消失与梯度爆炸|Problems with RNNs: Vanishing and Exploding Gradients

bolin
发布于 2026-03-11 / 1 阅读
0
0

循环神经网络的问题:梯度消失与梯度爆炸|Problems with RNNs: Vanishing and Exploding Gradients

第一节:引言

在深度学习的序列建模中,循环神经网络(RNN)曾被寄予厚望。由于其循环连接的结构,理论上 RNN 能够保留无限长的历史信息。然而在实际训练中,你会发现它表现得非常“短视”——它能轻易记住上一个单词,却总是忘记上一个段落。

这种局限性的核心原因,在于反向传播(Backpropagation Through Time, BPTT)过程中发生的梯度消失(Vanishing Gradient)

1. 梯度的“接力棒”效应

要理解梯度消失,我们需要观察 RNN 是如何计算误差并更新权重的。假设我们有一个 4 个时间步的简单序列,损失函数 J(4) 在最后一个时间步产生。为了更新第一步的参数,梯度必须从 h(4) 一路向后传递到 h(1)

根据链式法则,我们计算目标函数对第一层隐藏状态的导数:

ABB6E2BA-AEBD-4698-87E9-3468ED89DABC.png

802A0387-4BB4-428D-80FA-8E37BFEB753D.png

2. 当“接力”信号变弱时

正如上图所示,如果这些中间导数(步长间的交互)的值很小:

  • 信号衰减: 随着反向传播的距离越来越远,梯度信号会呈指数级减小。

  • 学习停滞: 到了序列的开头部分,梯度已经小到几乎可以忽略不计。

  • 后果: 模型的权重更新将完全由“近期的”误差主导。这意味着模型无法学习到输入序列中远距离特征之间的逻辑关系。

简单来说,梯度消失让 RNN 变成了一个“金鱼脑”,它只记得刚发生的事情,而丢失了遥远的背景信息。


第二节:消失的本质(线性案例分析)

为了弄清楚梯度为何会消失,我们需要跳出直观印象,深入到数学推导中。虽然深度学习通常涉及复杂的非线性激活函数,但通过一个简化后的线性案例,我们可以清晰地看到问题的根源。

1. 模型简化与链式法则

假设我们的循环神经网络处于一个理想状态:激活函数 σ恒等函数(Identity Function),即 σ(x) = x

此时,隐藏状态的计算公式简化为:

7E28FED2-2E13-4380-9BBE-6CA4DC6E62D8.png

根据链式法则,相邻两个时间步隐藏状态的导数为:

689FE28E-9B63-467B-A6F3-58B2F6A8867E.png

这就意味着,每回溯一个时间步,梯度就会被乘上一个权重矩阵 Wh

BE7287FC-CC1B-4DA4-9E69-45381F540120.png

2. 跨越 个时间步后的恐怖效应

如果我们要计算第 i 步的损失对第 j 步隐藏状态的梯度(令跨度 = i - j),公式会变成:

2A8EF8EB-1926-46D1-A2D0-BF646360356F.png

这里的关键点在于 Wh。当时间步跨度 很大时,梯度的大小几乎完全取决于 Wh

3. 特征值分析:跌入零的深渊

如果我们利用 Wh 的特征向量作为基底来展开这个公式,梯度的演变可以表示为特征值 λi 次幂:

D462163D-2F14-4D44-9B37-EE4FA9AC09CC.png

  • 如果特征值 λi < 1 随着跨度 的增加,λi 会以指数级速度趋近于 0

  • 这导致梯度信号在传递几十步后就彻底消失(≈ 0),模型无法感知到远处的任何反馈。

E1DA4A2C-6358-4873-878D-1D53694169E5.png

4. 非线性情况下的变体

现实中我们使用 tanhsigmoid 等激活函数,情况依然类似。证明过程虽然更复杂(需要考虑激活函数的导数 σ'),但结论是一致的:只要权重矩阵和激活函数导数的乘积项较小,梯度依然会不可避免地消失。


第三节:梯度消失的实际影响

通过前两节的直观理解与数学推导,我们已经知道梯度在反向传播中会迅速衰减。但这种数学上的“趋近于 0”,在实际的深度学习任务(如自然语言处理)中究竟意味着什么?

1. 梯度的“竞争”:近距离 vs 远距离

在训练 RNN 时,模型参数的更新取决于所有时间步传回的梯度总和。

  • 近距离梯度(Close-by): 路径短,信号强。

  • 远距离梯度(Far away): 路径长,信号微弱。

当总梯度被近距离的信号主导时,模型会变得非常“功利”。它发现只需根据最近的几个单词就能大幅降低误差,于是它放弃了去学习那些复杂的、长距离的逻辑关系。

802A0387-4BB4-428D-80FA-8E37BFEB753D.png

2. 经典案例:语言模型中的长期依赖失效

让我们来看一个具体的语言模型(LM)任务。请看下面这段话:

“当她试着去打她的机票(tickets)时,她发现打印机没墨了。她去文具店买了一些墨盒。墨盒非常贵。在把墨盒装进打印机后,她终于打印了她的 ______。”

在这个填空任务中,为了预测出最后的词是 “机票(tickets)”,模型必须建立起第 7 个时间步(第一次提到机票)与结尾目标词之间的依赖关系。

  • RNN 的困境: 这个时间跨度可能超过了 20 或 30 个词。

  • 消失的联系: 由于梯度消失,结尾处的误差信号无法有效地传递回第 7 步。对于模型参数而言,远处的“机票”二字仿佛根本不存在。

  • 短视的预测: 经验表明,普通 RNN 的有效记忆长度通常只有 7 个 token 左右。它可能能预测出后面要接一个“名词”,但无法锁定是哪一个。

2EDA33F9-07DD-444F-ADE3-E6697500E85C.png

3. 结论:无法捕捉的语义逻辑

梯度消失不仅仅是一个数值稳定性问题,它直接限制了模型的认知能力。它让 RNN 只能学会简单的局部语法(如:冠词后接名词),而无法理解跨越段落的深层语义逻辑。


第四节:梯度爆炸

如果说梯度消失是让信号在深渊中渐渐微弱,那么它的极端反面——梯度爆炸(Exploding Gradient),则像是一场突如其来的地震,足以瞬间摧毁辛苦训练数小时的模型。

1. 什么是梯度爆炸?

回顾我们在第二节提到的数学推导:梯度的演变涉及 Wh

  • 当特征值 λi < 1 时,梯度消失。

  • 反之,如果特征值 λi > 1,随着跨度 的增大,梯度会以指数级速度膨胀。

2. 后果

在随机梯度下降(SGD)中,权重的更新公式为:

C78B4B94-8A03-47B1-AA89-BFAE53CA0701.png

当梯度变得巨大时,更新步长也会随之失控。

  • 错误的更新: 就像你本来只想在山坡上向下走一小步,结果因为步子太大,直接飞跃了山谷,掉到了遥远的“爱荷华州”。你不仅错过了最优解,还可能落入一个参数配置极差、损失函数极高的区域。

  • 计算崩溃: 在最极端的情况下,由于数值超出了浮点数的表示范围,权重会直接变成 Inf(无穷大)NaN(非数值)。此时,除了从上一个检查点重启训练外,别无他法。

231F77EB-98AD-4E9D-996C-93C5136E6F47.png


第五节:梯度裁剪(Gradient Clipping)

相比于隐晦的梯度消失,梯度爆炸是一个相对“暴力”且容易解决的问题。目前工业界最常用的手段是梯度裁剪(Gradient Clipping)

1. 核心思想

梯度裁剪的逻辑非常直观:如果梯度的范数(Norm)超过了一个预设的阈值(threshold),我们就强行把它按比例缩小。

其算法伪代码如下:

37F7FF60-8329-4B39-A8E7-C1CF34CC56C4.png

2. 它的直观意义

梯度裁剪并不会改变梯度的方向,它只是限制了更新的步长

  • 直观理解: 当模型想要“暴冲”时,我们把它拽住,让它依然朝着正确的方向走,但只允许走一小步。

  • 实践建议: 在训练 RNN 或 Transformers 时,记得设置梯度裁剪几乎是标配操作。虽然它不能从根本上解决梯度消失问题,但它能极大地提高训练的稳定性。

26BA0F0F-C6C7-43A2-B5D8-07B923368083.png



评论