梯度消失详解

梯度消失 Link to heading

梯度消失问题在深层神经网络中尤为常见,尤其是在使用Sigmoid或Tanh等激活函数时。下面通过一个简单的实例来说明梯度消失的现象。

假设我们有一个非常简单的神经网络,结构如下:

  • 输入层:1个神经元
  • 隐藏层:3层,每层1个神经元
  • 输出层:1个神经元

每层的激活函数为 Sigmoid,权重和偏置随机初始化。

网络结构 Link to heading

输入层 (x) → 隐藏层1 (h1) → 隐藏层2 (h2) → 隐藏层3 (h3) → 输出层 (y)

激活函数 Link to heading

Sigmoid 函数的公式为:

$$ \sigma(z) = \frac{1}{1 + e^{-z}} $$

其导数为:

$$ \sigma'(z) = \sigma(z) \cdot (1 - \sigma(z)) $$

Sigmoid 函数的导数最大值为 0.25(当 $z = 0$ 时),且随着 $|z|$ 增大,导数趋近于 0。


梯度计算过程 Link to heading

假设我们使用均方误差(MSE)作为损失函数:

$$ L = \frac{1}{2}(y_{\text{true}} - y_{\text{pred}})^2 $$

在反向传播过程中,梯度从输出层向输入层传递。以隐藏层1的梯度为例:

$$ \frac{\partial L}{\partial h_1} = \frac{\partial L}{\partial h_3} \cdot \frac{\partial h_3}{\partial h_2} \cdot \frac{\partial h_2}{\partial h_1} $$

每一层的梯度计算都涉及 Sigmoid 函数的导数:

$$ \frac{\partial h_i}{\partial h_{i-1}} = \sigma'(z_i) \cdot w_i $$

其中 $z_i$ 是第 $i$ 层的输入,$w_i$ 是第 $i$ 层的权重。

由于 Sigmoid 函数的导数 $\sigma'(z_i)$ 最大为 0.25,且随着层数增加,梯度会不断缩小:

$$ \frac{\partial L}{\partial h_1} = \frac{\partial L}{\partial h_3} \cdot \sigma'(z_3) \cdot w_3 \cdot \sigma'(z_2) \cdot w_2 \cdot \sigma'(z_1) \cdot w_1 $$

如果权重 $w_i$ 较小(例如 $w_i < 1$),梯度会进一步缩小,导致:

$$ \frac{\partial L}{\partial h_1} \approx 0 $$

梯度消失的结果 Link to heading

  • 隐藏层1的参数几乎不更新,因为梯度趋近于零。
  • 网络无法有效学习输入数据的特征,训练效果差。

解决方法 Link to heading

  1. 使用 ReLU 激活函数: ReLU 的导数为 1(当输入大于 0 时),避免了梯度消失问题。

    $$ \text{ReLU}(z) = \max(0, z) $$
  2. 使用 Batch Normalization: 标准化每一层的输入,缓解梯度消失问题。

  3. 使用残差网络(ResNet): 通过跳跃连接(skip connection)将梯度直接传递到浅层,避免梯度消失。

ReLu解决办法 Link to heading

ReLU(Rectified Linear Unit)激活函数可以有效避免梯度消失问题,主要原因在于它的导数特性以及它对梯度传播的影响。

ReLU 的定义为:

$$ \text{ReLU}(z) = \max(0, z) $$

其导数为:

$$ \text{ReLU}'(z) = \begin{cases} 1 & \text{if } z > 0 \\ 0 & \text{if } z \leq 0 \end{cases} $$

关键点 Link to heading

  • 当输入 $z > 0$ 时,ReLU 的导数为 1,梯度不会缩小。
  • 当输入 $z \leq 0$ 时,ReLU 的导数为 0,神经元会“死亡”(即不激活),但激活的神经元梯度不会衰减。

相比之下,Sigmoid 的导数最大为 0.25,且随着输入值的增大或减小,导数会迅速趋近于 0,导致梯度消失。

梯度传播的影响 Link to heading

在反向传播过程中,梯度是通过链式法则逐层传递的。假设我们使用 ReLU 激活函数,梯度计算如下:

对于第 $i$ 层:

$$ \frac{\partial h_i}{\partial h_{i-1}} = \text{ReLU}'(z_i) \cdot w_i $$

如果 $z_i > 0$,则 $\text{ReLU}'(z_i) = 1$,因此:

$$ \frac{\partial h_i}{\partial h_{i-1}} = w_i $$

梯度的大小主要取决于权重 $w_i$,而不会因为激活函数的导数而缩小。如果权重 $w_i$ 初始化合理(例如使用 He 初始化),梯度可以稳定地传播到浅层。

在 ReLU 的情况下:

  • 梯度不会因为激活函数的导数而缩小(当 $z > 0$ 时)。
  • 即使网络很深,梯度仍然可以有效地传播到浅层。

假设我们使用 ReLU 激活函数替换 Sigmoid,重新计算梯度:

对于隐藏层1的梯度:

$$ \frac{\partial L}{\partial h_1} = \frac{\partial L}{\partial h_3} \cdot \text{ReLU}'(z_3) \cdot w_3 \cdot \text{ReLU}'(z_2) \cdot w_2 \cdot \text{ReLU}'(z_1) \cdot w_1 $$

如果每一层的输入 $z_i > 0$,则 $\text{ReLU}'(z_i) = 1$,因此:

$$ \frac{\partial L}{\partial h_1} = \frac{\partial L}{\partial h_3} \cdot w_3 \cdot w_2 \cdot w_1 $$

梯度的大小主要取决于权重 $w_i$,而不会因为激活函数的导数而缩小。如果权重初始化合理,梯度可以稳定地传播到浅层,避免了梯度消失问题。