← 返回笔记列表
深度学习 第 18 / 49 篇

深度学习:梯度消失与梯度爆炸 — 为什么深层网络难训练

查看“深度学习”专题目录(18/49)
本文目录 13 个小节

先修知识

阅读本文前,建议先理解:

1. 问题根源:链式法则中的连乘

1.1 展开看第一层权重的梯度

以之前 3 层网络为例,第一层权重的梯度为:

∂loss∂W1=xTδ1\frac{\partial \text{loss}}{\partial W^1} = x^T \delta^1

把 δ1\delta^1 逐层展开:

∂loss∂W1=xT[(((a3−y)(W3)T)⊙act′(z2))(W2)T⊙act′(z1)]\frac{\partial \text{loss}}{\partial W^1} =x^T\left[\left(\left((a^3-y)(W^3)^T\right)\odot\text{act}'(z^2)\right)(W^2)^T\odot\text{act}'(z^1)\right]

1.2 层数变深的后果

如果是 100 层网络,第一层权重的梯度中包含:

  • 99 个激活函数导数值连乘
  • 99 个权重矩阵连乘

连乘的性质:

乘数100 个连乘的结果
全部 = 0.70.7100≈3.2×10−160.7^{100} \approx 3.2 \times 10^{-16} → 梯度消失,参数几乎不更新
全部 = 1.51.5100≈4.1×10171.5^{100} \approx 4.1 \times 10^{17} → 梯度爆炸,参数剧烈震荡

梯度消失和梯度爆炸是深度神经网络训练的头号障碍。


2. 应对一:选对激活函数

梯度公式里连乘了 act′(z)\text{act}'(z),所以激活函数的导数值范围至关重要。

2.1 Sigmoid — 不适合隐藏层

sigmoid

属性值
导函数取值范围(0, 0.25]
最大值仅 0.25,且只在 x=0x=0 处取得

多个 sigmoid 的局部导数可能使梯度衰减,但完整 Jacobian 还包含权重矩阵,不能只由导数上界推出必然梯度消失。

结论:深层前馈网络的隐藏层通常避免大量使用 sigmoid,但 LSTM 等门控结构仍会使用它;并非只能用于二分类输出层。

2.2 Tanh — 比 Sigmoid 好,但仍有问题

tanh

属性值
导函数取值范围(0, 1]
饱和区$

比 Sigmoid 好(导数上限高),但输入的绝对值稍微大一点就进入饱和区,导数仍接近于 0。

2.3 ReLU — 深度学习默认选择

RELU

属性值
x>0x > 0 时导数恒为 1
x≤0x \leq 0 时导数0(神经元抑制)

导数为 1 意味着——正半轴上梯度在传播时不会被缩放,这一局部导数不缩小梯度;权重矩阵、非激活通路等因素仍可能导致整体梯度消失或爆炸。

这是 ReLU 能支持深层网络训练的根本原因。


3. 应对二:正确的参数初始化

梯度公式里还连乘了权重 WW。权重初始化不当,同样会导致梯度消失或爆炸。

3.1 必须随机初始化 — 打破对称性

如果同一层的所有神经元参数初始化为相同值:

  • 它们的输入相同、输出相同
  • 反向传播的梯度也相同
  • 每次更新后依然相同
  • 多个神经元退化成一个神经元

初始化必须随机,让不同神经元学到不同的特征。

3.2 控制方差 — Kaiming 初始化

假设输入已标准化(均值 0,方差 1)。

问题:一层有 nn 个输入,每个是”输入 × 权重”的累加 → 输出的方差会被放大为 nn 倍。层数一多,方差逐层膨胀或收缩。

再加上 ReLU 大约让一半神经元输出为 0,方差应修正为 n2\frac{n}{2}。

为了保持每层输出的方差稳定,需要将权重初始化为:

均值=0,标准差=2n\text{均值} = 0, \quad \text{标准差} = \sqrt{\frac{2}{n}}

其中 nn 是该层输入的数量(即上一层的神经元数)。这就是 Kaiming 初始化(也叫 He 初始化)。

激活函数推荐初始化标准差
ReLUKaiming (He)2/n\sqrt{2/n}
Tanh / SigmoidXavier (Glorot)g2/(fanin+fanout)g\sqrt{2/(fan_{in}+fan_{out})},gg 取决于激活约定

PyTorch 层会执行默认初始化,但它不一定是针对后续 ReLU 的 He 正态初始化。要复现上述标准差,应明确调用 nn.init.kaiming_normal_;相关细节见 PyTorch 初始化。


4. 其他方法(后续会讲到)

除了激活函数和初始化,还有其他缓解梯度消失/爆炸的技术:

方法简述
批量归一化(Batch Normalization)在每层内部对输出做标准化,保证数值稳定
残差连接(Residual Connection)给梯度提供一条”高速公路”,跳过中间层直接往前传

5. 总结

问题:链式法则导致前层梯度 = 大量导数连乘
     ├── 每项 < 1  → 梯度消失(深层参数几乎不更新)
     └── 每项 > 1  → 梯度爆炸(参数震荡发散)

三大应对:
     ├── 激活函数   → ReLU(正半轴导数 = 1,不衰减)
     ├── 参数初始化 → 随机 + Kaiming(方差 √(2/n))
     └── (后续)     → 批量归一化、残差连接

为什么 ReLU 能支持深层网络:
    Sigmoid 导数 ≤ 0.25  → 10 层后梯度 ≈ 0
    ReLU 正半轴导数 = 1  → 100 层后梯度依然在
继续学习本专题