权重初始化对深层网络训练的影响远比想象中大。如果每层权重初始化得过小,激活值会在前向传播中逐层收缩;反向传播时梯度又会连续乘以这些小于1的权重,到达浅层时几乎为零,这就是梯度消失。He初始化与正交初始化是两种有效的应对手段,但它们的作用机制并不相同。下面从方差传播的角度拆开分析。

初始化如何影响梯度传播
深层网络训练困难的一个核心原因是信号在前向和反向传播中的尺度变化。假设网络每一层都是线性变换加激活函数,前向传播可以理解为将输入向量逐层映射。若每层权重矩阵的奇异值都小于1,输入经过多层后范数会指数级收缩;若奇异值大于1,则激活值会爆炸。对于梯度来说,反向传播通过链式法则将误差一层层乘回去,权重矩阵的转置会再次作用于梯度,因此权重尺度对梯度的影响是双倍的。经典Xavier初始化试图让前向和反向的方差都保持不变,但它的推导基于线性激活或tanh这类对称激活函数,实际使用ReLU时就会失效。
ReLU把负数清零,意味着每一层大约会损失一半的信号,因此要保持方差不变,权重初始化需要比Xavier大一倍。如果仍然使用Xavier初始化,在很深的ReLU网络中,激活值方差会逐层变小,梯度到达浅层时可能已经消失。He初始化正是针对这种非对称激活函数做了修正,它用2除以输入维度来调整方差,使ReLU网络的前向信号和反向梯度都能维持合理尺度。
He初始化的推导与使用
He初始化也叫Kaiming初始化,它从保持前向传播方差不变的目标出发。对一层全连接网络,假设输入x的每个分量均值为0、方差为Var(x),权重w独立同分布且均值为0、方差为Var(w)。经过线性变换后,输出y的方差为fan_in乘以Var(w)乘以Var(x)。如果激活函数是ReLU,由于负半轴输出为0,正向传播后方差会减半。因此要让输出方差与输入方差一致,需要满足fan_in乘以Var(w)除以2等于1,即Var(w)等于2除以fan_in。实际使用的高斯初始化标准差就是sqrt(2/fan_in),均匀分布初始化则使用sqrt(6/fan_in)作为边界。
在PyTorch中,可以直接调用kaiming_normal_或kaiming_uniform_。下面这段代码对全连接网络应用He初始化,所有线性层都会按fan_in和ReLU非线性进行初始化,偏置置零。
import torch
import torch.nn as nn
def he_init(m):
if isinstance(m, nn.Linear):
nn.init.kaiming_normal_(m.weight, mode='fan_in', nonlinearity='relu')
if m.bias is not None:
nn.init.zeros_(m.bias)
model = nn.Sequential(
nn.Linear(784, 256),
nn.ReLU(),
nn.Linear(256, 128),
nn.ReLU(),
nn.Linear(128, 10)
)
model.apply(he_init)
print(model[0].weight.std().item())
代码中的kaiming_normal_会根据每一层的输入维度自动计算标准差,mode为fan_in表示用输入神经元数量,nonlinearity为relu表示针对ReLU修正。这种方式比手动计算标准差更不易出错。He初始化在VGG、ResNet等以ReLU为主体的网络里已经成为事实标准,很多框架也将它设置为Conv2d和Linear的默认初始化。
正交初始化的原理与实现
与He初始化控制方差大小不同,正交初始化关注的是权重矩阵的结构。一个正交矩阵的列向量两两正交且模长为1,它的最大奇异值等于1,条件数也为1。这意味着前向传播不会放大或缩小任何方向的信号,反向传播时梯度经过转置矩阵,尺度同样被保持。对于需要长期记忆或者循环连接的网络,正交初始化可以显著缓解梯度消失和爆炸。比如在RNN中,隐藏状态反复乘以同一个权重矩阵,如果该矩阵的谱半径小于1,状态会迅速衰减;如果谱半径大于1,状态会发散。把权重初始化成正交矩阵,恰恰能在初期保持稳定。
实际生成正交矩阵可以使用QR分解。先生成一个随机高斯矩阵,然后对它做QR分解得到Q矩阵,再根据R的对角线符号调整Q的列方向,确保Q是真正的正交矩阵。NumPy示例如下。
import numpy as np
def random_orthogonal_matrix(n):
a = np.random.randn(n, n)
q, r = np.linalg.qr(a)
d = np.diagonal(r)
ph = d / np.abs(d)
q = q * ph
return q
W = random_orthogonal_matrix(128)
print(np.allclose(W.T @ W, np.eye(128)))
这段代码输出True说明W的转置乘以W接近单位矩阵。在PyTorch中也可以直接使用nn.init.orthogonal_初始化Linear或Conv层的权重。不过要注意,正交初始化严格要求矩阵是方阵,而全连接层的输入输出维度往往不相等。PyTorch的orthogonal_在处理非方阵时会生成半正交矩阵,即列向量仍然正交,但行数多于列数,这仍然能保持范数,只是在数学上不再是传统意义上的正交矩阵。
此外,正交初始化在深度线性网络、GAN的生成器以及循环神经网络的权重初始化中都有应用。对于ReLU网络,正交初始化单独使用时效果可能不如He初始化,因为ReLU的非线性会破坏正交变换保持范数的性质。但如果配合Batch Normalization或者使用tanh这类对称激活函数,正交初始化的优势会更加明显。
两种初始化如何选择
He初始化和正交初始化并不是替代关系,它们分别从尺度和结构两个角度稳定信号传播。对于以卷积层和全连接层为主、激活函数是ReLU及其变体的网络,He初始化是最直接的选择,它实现简单、计算开销低,并且能很好地配合Batch Normalization。对于RNN、LSTM、GRU这类循环结构,隐藏状态会反复经过同一个权重矩阵,正交初始化通常比He初始化更能避免长期依赖中的梯度问题。ResNet中的某些旁路连接也可以使用正交初始化来减少信息损失。
如果拿不准该用哪种,可以先根据网络结构选择:前馈网络优先He,循环网络优先正交。另一个实用建议是观察训练初期的梯度范数。如果在几轮迭代后浅层梯度明显小于深层,可以考虑增强初始化尺度或改用正交初始化;如果梯度出现NaN,则说明初始权重过大,需要减小方差。初始化只是训练成功的一个环节,但它往往决定了优化器能否在合理时间内找到有效解。
| 对比维度 | He初始化 | 正交初始化 |
|---|---|---|
| 核心数学依据 | 保持ReLU前向方差 | 保持矩阵谱范数为1 |
| 适用激活函数 | ReLU、Leaky ReLU、PReLU | tanh、线性、对称激活 |
| 典型网络 | CNN、全连接网络 | RNN、LSTM、深度线性网络 |
| 实现复杂度 | 低 | 中,需QR分解或半正交化 |
这张对比表概括了两者的主要差异。实际项目中,默认初始化可能已经做了He初始化,所以很多时候训练不稳定并不是初始化单独造成的,还需要结合学习率、归一化层和激活函数一起排查。但理解初始化的作用,可以让调参更有方向。