Mobile wallpaper 1Mobile wallpaper 2Mobile wallpaper 3Mobile wallpaper 4
1891 字
9 分钟
多层感知机:数值稳定性与模型初始化

在构建和训练深度神经网络时,我们常常将注意力集中在模型架构、损失函数和优化器上。然而,一个看似不起眼却至关重要的环节——模型参数的初始化——往往决定了训练的成败。糟糕的初始化可能导致模型在训练初期就陷入停滞(梯度消失)或数值溢出(梯度爆炸),亦或是让网络中的神经元“集体偷懒”,学习不到有意义的特征。本文将深入探讨数值稳定性与模型初始化的核心原理,并解析如何通过巧妙的初始化策略为模型训练铺平道路。

问题的根源:梯度传播的脆弱性#

神经网络的训练依赖于反向传播算法,其核心是链式法则。梯度信息从输出层逐层回传,每一层的梯度都是上一层梯度与本层局部导数的乘积。正是这个连续的乘法运算,埋下了数值不稳定的种子。

WARNING

梯度爆炸与梯度消失:如果每一层回传的梯度因子都略大于1,经过数十甚至数百层的连乘,梯度值会像滚雪球一样急剧膨胀,最终超出计算机的浮点数表示范围,导致NaNInf,这就是梯度爆炸。反之,如果梯度因子都略小于1,梯度值则会指数级衰减至近乎为零,导致浅层网络的参数几乎得不到更新,这就是梯度消失

打破对称性:让神经元“各司其职”#

除了数值稳定性,初始化的另一个核心任务是打破对称性。想象一下,如果某一层的所有神经元都被初始化为完全相同的权重和偏置,会发生什么?

WARNING

对称性问题:如果神经元初始状态相同,那么在相同的输入下,它们会产生完全相同的输出。在反向传播时,它们也会收到完全相同的梯度,并按照完全相同的方式更新。最终,这些神经元将始终保持同步,相当于整个层只学习到了一个特征,这是对模型容量的巨大浪费。

用一个简单的两层感知机为例,假设隐藏层有两个神经元 h1h_1h2h_2,初始权重均为 ww,激活函数为 σ\sigma

  1. 前向传播:对于输入 xx,有 h1=σ(wx)h_1 = \sigma(w \cdot x)h2=σ(wx)h_2 = \sigma(w \cdot x)。输出完全相同。
  2. 反向传播:由于 h1h_1h2h_2 对最终损失的贡献相同,它们接收到的梯度 grad1\text{grad}_1grad2\text{grad}_2 也必然相等。
  3. 权重更新:使用 SGD 更新,wnew=woldηgradw_{new} = w_{old} - \eta \cdot \text{grad}。由于初始权重和梯度都相同,更新后的权重依然相同。

这个循环将永远持续下去,神经元无法分化。因此,我们必须通过随机初始化来赋予每个神经元一个独特的“起点”

初始化的平衡艺术:Xavier 初始化#

随机初始化不能是简单的“随便初始化”。如果权重初始值过大,前向传播时激活值容易进入饱和区(如 Sigmoid 函数的两端),导致梯度极小;反向传播时则可能直接引发梯度爆炸。如果初始值过小,激活值和梯度信号会在传播过程中迅速衰减。

我们需要一个科学的指导原则。一个理想的目标是:保持数据在每一层网络间传播时,其分布的方差(即信号的“强度”)大致稳定。这样,无论是前向的信号还是反向的梯度,都能有效地贯穿整个网络。

Xavier Glorot 等人提出的 Xavier 初始化(或称 Glorot 初始化)正是基于这一思想。它针对的是线性激活函数或类线性的饱和激活函数(如 Tanh, Sigmoid)。

其推导基于以下假设:输入 xx、权重 ww 均值为零且相互独立。对于一个线性层 y=i=1ninwixiy = \sum_{i=1}^{n_{in}} w_i x_i,输出的方差为: Var(y)=ninVar(w)Var(x)Var(y) = n_{in} \cdot Var(w) \cdot Var(x) 其中 ninn_{in} 是该层的输入维度(或称扇入)。

为了保持方差不变,即 Var(y)=Var(x)Var(y) = Var(x),我们需要令: ninVar(w)=1Var(w)=1ninn_{in} \cdot Var(w) = 1 \quad \Rightarrow \quad Var(w) = \frac{1}{n_{in}}

然而,反向传播过程对权重方差有类似但不同的要求,它依赖于该层的输出维度 noutn_{out}(扇出),即 Var(w)=1noutVar(w) = \frac{1}{n_{out}}

TIP

Xavier 初始化采用了一个优雅的折中方案,同时考虑前向和反向传播,将权重的方差设定为: Var(w)=2nin+noutVar(w) = \frac{2}{n_{in} + n_{out}} 在实践中,我们通常从均值为零、方差为该值的高斯分布或均匀分布中采样来初始化权重。

当 ReLU 遇上初始化:He 初始化的诞生#

Xavier 初始化在 Tanh 时代表现优异,但随着 ReLU 及其变体成为深度网络的主流激活函数,新的问题出现了。

[!QUESTION] ReLU 激活函数(f(x)=max(0,x)f(x) = \max(0, x))会把一半的输入直接置零。如果我们在使用 ReLU 的网络中依然套用 Xavier 初始化,信号的强度(方差)在每一层传递后会发生什么变化?

答案是:方差会减半。因为 ReLU 将一半的神经元输出设为零,相当于丢弃了一半的信号。在一个 LL 层的深度网络中,信号方差将衰减为原来的 (1/2)L(1/2)^L,这会导致严重的梯度消失问题。

为了解决这个问题,何恺明等人提出了 He 初始化(Kaiming 初始化)。其核心思想很简单:既然 ReLU “杀死”了一半的神经元,那么我们在初始化时就把权重的方差扩大一倍,以补偿这个损失。

具体地,对于使用 ReLU 的层,He 初始化的方差设置为: Var(w)=2ninVar(w) = \frac{2}{n_{in}} 这个公式仅考虑了前向传播的方差保持。对于其变体如 Leaky ReLU,公式中的系数 2 会做相应调整(例如,对于 negative_slope=a 的 Leaky ReLU,系数为 2/(1+a2)2 / (1 + a^2))。

实践与总结#

在现代深度学习框架中,这些初始化方法都已内置,我们通常只需一个参数即可调用:

import torch.nn as nn
# Xavier 初始化 (适用于 Tanh/Sigmoid)
linear = nn.Linear(100, 200)
nn.init.xavier_uniform_(linear.weight)
# He 初始化 (适用于 ReLU)
conv = nn.Conv2d(3, 64, kernel_size=3)
nn.init.kaiming_normal_(conv.weight, mode='fan_out', nonlinearity='relu')
核心要点回顾
  1. 数值稳定性:初始化不当是导致梯度爆炸和梯度消失的常见原因之一。
  2. 打破对称性:随机初始化是必须的,以确保神经元能学习到不同的特征。
  3. 方差保持:优秀的初始化策略旨在使网络各层的激活值方差在传播过程中保持稳定。
  4. 因地制宜
    • Xavier 初始化:适用于 Tanh、Sigmoid 等饱和激活函数。
    • He 初始化:是 ReLU 家族激活函数的标准搭档。

正确的初始化是成功训练深度模型的基石。它虽不直接参与学习,却为整个优化过程设定了一个良好的起点,使得梯度能够稳定、高效地流动,让网络中的每一个神经元都能发挥其应有的作用。理解其背后的原理,能帮助我们在面对更复杂的网络结构或训练难题时,做出更明智的调整。

多层感知机:数值稳定性与模型初始化
https://blog.solmount.top/posts/numerical-stability-and-weight-initialization/
作者
空 柏
发布于
2026-03-16
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

封面
Sample Song
Sample Artist
封面
Sample Song
Sample Artist
0:00 / 0:00