2-参数初始化
1. 初始化的核心问题
1.1 对称性破缺(Symmetry Breaking)
假设网络有权重
由于
初始化的首要目标是破坏这种对称性:让每个神经元在训练初期拥有独立的激活响应,从而保证梯度在反向传播时能够流经不同路径,独立更新每个权重。
1.2 梯度尺度控制(Gradient Scale Control)
设第
若权重方差过大,则
1.3 信号传播稳定性
综合前向与反向两个方向,我们希望:
- 前向传播稳定性:各层激活的方差大致相同,信号不会爆炸或消失。
- 反向传播稳定性:各层损失函数对权重梯度的方差大致相同,梯度不会爆炸或消失。
这两个目标分别对应 Xavier 和 He 初始化的设计出发点。
2. 全零初始化为什么不工作
设所有权重
反向传播中,损失对权重的梯度:
由于
即使只将偏置初始化为零而保留随机权重,若权重方差过小,同样会导致各神经元输出趋同。
3. 随机初始化
3.1 基本思想
从某一概率分布(通常为均值 0 的对称分布)中独立同分布(i.i.d.)采样每个权重:
常用分布:
- 高斯初始化:
- 均匀初始化:
,其中 使方差匹配
对称分布保证正向和反向信号可以双向流动,独立采样破缺对称性。但方差
4. Xavier/Glorot 初始化
4.1 核心思想
Xavier Glorot 在 2010 年的论文 Understanding the difficulty of training deep feedforward neural networks 中提出:初始化权重的方差应使前向激活方差和反向梯度方差在各层保持一致。
假设:激活函数为线性(identity)或近似线性(如 Sigmoid、Tanh,在零点附近近似线性)。
4.2 数学推导——前向激活方差
设
假设权重和激活独立同分布,且权重均值为 0,则
这里用了独立性推导
为了使每层激活方差保持不变,即
4.3 数学推导——反向梯度方差
反向传播中,第
在激活函数为恒等函数(线性)的假设下,
同理可得上式中
4.4 综合前向与反向条件
前向要求
这就是 Xavier 初始化(亦称 Glorot 初始化)的方差公式。相应地,若使用均匀分布
PyTorch 实现(torch.nn.init.xavier_uniform_ / xavier_normal_)即基于上述公式。
4.5 Xavier 与激活函数的对应关系
Xavier 初始化的推导假设激活函数在线性区间,这正是 Sigmoid 和 Tanh 在零点附近的特性。对于这些激活函数,若初始权重过大(
5. He/Kaiming 初始化
5.1 核心思想
He Kaiming 等人在 2015 年的论文 Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification 中指出:Xavier 的推导假设激活函数是线性的,但 ReLU 在负区间输出为 0,这导致有效方差在经过 ReLU 层时减半。
5.2 数学推导——ReLU 导致方差减半
设输入
原因是
5.3 前向激活方差推导
对于第
要求
5.4 反向梯度方差推导
同理,ReLU 在反向传播中也会将负区间的梯度置零,因此反向的有效方差同样减半。要维持反向梯度方差不变,需要
5.5 He 初始化公式
综合前向与反向,He 初始化的方差取折中:
(若每层神经元数相同即
对应的均匀分布参数:
PyTorch 实现:torch.nn.init.kaiming_uniform_ / kaiming_normal_,另有关于 mode 参数的选择——mode='fan_in' 仅考虑前向(用于残差网络主分支),mode='fan_out' 仅考虑反向(用于残差网络skip分支)。
5.6 Xavier 与 He 初始化对比
| 初始化方法 | 方差公式 | 激活函数假设 | 适用场景 |
|---|---|---|---|
| Xavier | 线性 / Sigmoid / Tanh | 浅层网络、CNN、MLP(非ReLU) | |
| He | ReLU / LeakyReLU / ELU | 深度CNN、ResNet、Transformer |
6. 正交初始化(Orthogonal Initialization)
6.1 思想来源
正交初始化来源于对递归神经网络(RNN)的训练稳定性分析。在标准 RNN 中,状态转移矩阵
设
6.2 正交初始化方法
正交初始化要求
实现方法:对随机矩阵
6.3 应用场景
- RNN / LSTM / GRU:权重矩阵(尤其是循环权重)使用正交初始化是标准实践,配合梯度裁剪(gradient clipping)可同时防止梯度爆炸和消失。
- 权重矩阵的奇异值控制:在 Transformer 中,QKV 投影矩阵
虽非循环矩阵,但其谱半径影响注意力的平滑程度。经验上常见(empirical common practice)对注意力矩阵使用截断正态初始化并配合 LayerNorm 稳定信号。
7. Bias 初始化
7.1 基本规则
偏置
| 场景 | 推荐初始化值 | 理由 |
|---|---|---|
| ReLU / LeakyReLU | 避免初始阶段大量神经元输出为负导致死 ReLU | |
| Sigmoid / Tanh | 输入零点时激活在非饱和区(Sigmoid 的最大导数点、Tanh 的零点) | |
| LSTM / GRU 门控 | 特定值(如 forget gate 偏置初始化为 1) | 保证初始 forget 门开启,记忆单元可正常传递信息 |
| 输出层偏置 | 根据输出分布设置(如二分类偏置设为类先验的对数几率) | 让网络初始预测接近真实分布,加速收敛 |
7.2 LSTM 中的特殊处理
LSTM 的 forget 门偏置
8. 深层网络中初始化不当与梯度消失/爆炸的关系
8.1 方差传播的量化分析
考虑一个
前向传播中激活方差的递推:
递推
反向传播中梯度方差的递推同理:
由此可量化三类情况:
| 条件 | 结果 | 后果 |
|---|---|---|
| 信号/梯度指数增长,爆炸 | ||
| 各层方差保持稳定,理想情况 | ||
| 信号/梯度指数衰减,消失 |
Xavier 初始化的设计恰好满足
8.2 非线性饱和的额外影响
上述推导假设激活函数为恒等函数。实际中若激活函数为 Sigmoid,当
9. 残差结构与初始化
9.1 残差连接的基本形式
ResNet 中,第
其中
9.2 为什么残差可以缓解初始化问题
若没有残差连接,深层网络的梯度流完全依赖每层的初始化方差稳定性。有了残差连接,即使残差分支的权重初始化为很小的值(接近零),恒等映射仍然保证信号直接传递:
这使得网络在训练初期等同于一个浅层网络,随着残差分支权重逐渐大学习到有用的变换。ResNet 的成功本质上是通过架构设计绕过了初始化难的问题,而非解决了初始化问题。
9.3 残差网络中权重的初始化建议
即便有残差连接,残差分支(即两个卷积层或全连接层)仍需合理初始化。标准实践(以 ResNet-50 为例):
- conv1:使用 He 初始化(Kaiming Normal,
mode='fan_out') - conv2(3×3 卷积):使用 He 初始化,不使用
fan_out,而使用fan_in(因为 conv2 的输入输出通道数不同,残差分支需维持前向方差) - BatchNorm:
gamma初始化为 1(缩放因子为 1,保证初始残差分支输出接近恒等),beta初始化为 0
若 BatchNorm 的 gamma 错误初始化为 0,残差分支的方差在训练初期为 0,残差连接传递的仅是恒等映射,残差分支永远学不到任何东西(对应 “零残差”问题,网络退化为普通深层网络)。
10. Transformer 中的初始化工程考虑
10.1 标准初始化方案
Transformer 架构(GPT、BERT 等)广泛使用 Xavier 初始化对 QKV 投影和 FFN 投影进行初始化,但在具体实现上有若干工程经验:
- QKV 投影
:使用 Xavier 初始化( torch.nn.init.xavier_uniform_),方差为。 - 输出投影
:使用 Xavier 初始化,但部分实现对 使用较小的方差(如 ),以控制注意力分数 的量级,防止 softmax 过度锐化。 - FFN 投影:第一层(扩展层)
使用 Xavier,方差 ;第二层(压缩层) 使用 Xavier,方差 。
10.2 为什么需要特殊处理
Transformer 中的 QKV 投影矩阵是正方形的(均为
GPT-2 等模型采用残差缩放(residual scaling):将残差路径的输出乘以
10.3 Embedding 层的初始化
词嵌入(Embedding)矩阵
- 标准做法:
,即 Xavier 初始化中 的变体。方差取 使得嵌入向量的欧氏长度期望约为 ,各 token 在表示空间中大致均匀分布。 - 特殊考虑:若使用余弦相似度作为预训练目标(如 CLIP 的文本编码器),部分实现会将 Embedding 初始化为常数范数(如 L2 normalized),避免训练初期各 token 表示长度差异过大。
- 归一化的配合:Embedding 后通常接 LayerNorm,若 LayerNorm 在 Embedding 之后,则嵌入初始化的方差影响不大——LayerNorm 会自动将表示标准化;但若 LayerNorm 在 Embedding 之前(较少见),则需更仔细控制嵌入方差。
11. 工程实践
11.1 训练前如何检查初始化是否合理
步骤 1:前向传播测试(forward test)
在正式训练前,用少量样本(batch size = 1~4)跑一次完整前向传播,记录每层激活值的均值和方差:
for l in range(1, L+1):
z_mean, z_std = z[l].mean().item(), z[l].std().item()
a_mean, a_std = a[l].mean().item(), a[l].std().item()
print(f"Layer {l}: z mean={z_mean:.4f}, z std={z_std:.4f}, "
f"a mean={a_mean:.4f}, a std={a_std:.4f}")合理标准:
- 各层激活的均值应大致在 0 附近(ReLU 允许正值均值,Tanh 允许小偏移)
- 各层激活的标准差应大致在同一量级(允许 ~2x 的波动)
- 若某层标准差骤降 10 倍以上,很可能该层梯度消失;若骤升 10 倍以上,则梯度爆炸
步骤 2:梯度流测试(gradient flow test)
记录反向传播时每层权重的梯度范数
grad_norms = []
for l in range(1, L+1):
grad_norm = grads[l].norm().item()
grad_norms.append(grad_norm)
print(f"Layer {l} grad norm: {grad_norm:.6e}")合理标准:
- 各层梯度范数应在同一量级(允许 ~5x 的波动)
- 梯度范数若从浅层到深层递减超过 100 倍,存在梯度消失;若递增超过 100 倍,存在梯度爆炸
11.2 如何观察初始 loss、激活分布、梯度范数
初始 loss 监控:
- 初始 loss 若远大于预期的随机初始 loss(如多分类随机猜测
,若初始 loss 高出 5 倍以上),说明初始化可能将激活推入饱和区或导致数值不稳定 - 经验上常见(empirical common practice)记录前 10 个 step 的 loss,若 loss 在前几个 step 即 NaN / Inf,说明数值爆炸
激活分布可视化:
- 使用直方图或统计摘要(均值、方差、偏度、峰度)观察各层激活分布
- ReLU 后若激活均值接近 0.5×std,且大量为 0(稀疏度 > 80%),说明网络稀疏度过高,可能存在大量死 ReLU
- 若激活集中在极端值(如
量级),说明存在激活爆炸
梯度范数曲线:
- 训练过程中监控梯度范数曲线,若某些层梯度范数趋近 0 且不恢复,则存在梯度消失
- 梯度爆炸的典型表现是 loss 突然变为 NaN,或参数范数突然增大 10 倍以上
11.3 大模型训练中的特殊处理
Embedding 层
大模型(如 LLaMA、GPT-3)中,词表大小
- 使用
初始化后,通常会在 Embedding 层后接 LayerNorm,将表示标准化,控制表示长度的初始尺度 - 经验上常见(empirical common practice)在 Embedding 后加 tied embedding(共享输入输出嵌入),这意味着输入嵌入的初始化会直接影响输出层的梯度,需确保两者初始化一致
归一化层(Norm)的初始化
Transformer 中通常有三处归一化:
- Pre-norm(前置归一化):LayerNorm 在注意力/FFN 之前
- Post-norm(后置归一化):LayerNorm 在残差之后(原始 Transformer 使用)
- RMSNorm:简化版 LayerNorm,移除了均值中心化,仅做方差归一化
LayerNorm 初始化:
- 缩放因子
初始化为 1(保证残差路径初始为恒等) - 偏移因子
初始化为 0
若
BatchNorm(用于大模型中偶尔出现的 CNN backbone):
- 移动均值/方差初始化为全局统计量(若有预训练统计值)或 batch 统计值
- 可学习参数
分别初始化为 1 和 0
Projection 层的初始化
大模型中三类 projection 层的初始化策略:
| 层类型 | 初始化方法 | 理由 |
|---|---|---|
| QKV 投影 | Xavier | 保持各层方差稳定 |
| 输出投影 | 较小方差( | 控制注意力 logits 量级 |
| FFN 第一层(扩展) | Xavier( | 保证 ReLU 输入方差合理 |
| FFN 第二层(压缩) | Xavier( | 维持残差路径方差稳定 |
12. 常见错误案例
案例 1:He 初始化用于 Sigmoid 网络
错误:对使用 Sigmoid/Tanh 的网络使用 He 初始化。
原因:He 初始化基于 ReLU 的方差减半假设,补偿因子 2 会在 Sigmoid/Tanh 的非饱和区间产生过大的激活方差(通常
案例 2:所有偏置初始化为 0 且权重方差过小
错误:所有权重
原因:这会导致所有神经元的输出在训练初期趋近于 0(经 Sigmoid / Tanh 后趋近 0 或 -1/1 的饱和端),死神经元比例极高,网络几乎不学习。正确做法是使用合适的权重方差(Xavier / He 公式计算),或对 ReLU 将偏置初始化为小正值。
案例 3:LSTM 忘记初始化 forget gate 偏置
错误:LSTM 的 forget gate 偏置初始化为 0。
后果:初始 forget gate 输出
案例 4:BatchNorm 参数初始化错误
错误:BatchNorm 的
后果:该层的输出方差被压缩至 0,梯度在反向传播时流经此层后趋近于 0,训练无法推进。这在实践中常被忽略,是导致”网络不学习”的一个隐蔽原因。
案例 5:正交初始化后对非方阵权重使用 QR 分解
错误:对
后果:正交矩阵必须满足
13. 初始化选择速查表
| 激活函数 | 推荐初始化 | 方差公式 | 归一化配合 |
|---|---|---|---|
| Sigmoid / Tanh | Xavier (Glorot) | BatchNorm 在激活前 | |
| ReLU / LeakyReLU | He (Kaiming) | BatchNorm 在激活前 | |
| ELU | He | LayerNorm / BatchNorm | |
| GELU (Transformer) | Xavier | LayerNorm 在激活前(Pre-norm)或后(Post-norm) | |
| Swish / SiLU | Xavier | LayerNorm 配合使用 | |
| LSTM / GRU 循环权重 | 正交初始化 | — | — |
| LSTM / GRU 门控偏置 | — | — | |
| Embedding | LayerNorm 配合使用 | ||
| LayerNorm | 1 | — | — |
| LayerNorm | 0 | — | — |
| BatchNorm | 1 | — | — |
| BatchNorm | 0 | — | — |
| 输出层偏置 | 类先验对数几率(分类)或 0(回归) | — | — |
补充说明:
torch.nn.init.calculate_gain('relu')/calculate_gain('sigmoid')可计算框架推荐增益值,配合自定义初始化使用。- 残差网络中残差分支的 BatchNorm
必须初始化为 1,切勿设为 0。 - 大模型训练中若使用 Pre-norm(现代 Transformer 主流),LayerNorm 在注意力/FFN 之前,此时 LayerNorm 的
若初始化为非 1 值会影响残差信号的初始尺度,需特别注意。