He初始化专为ReLU及其变体设计,Xavier初始化仅适用于Sigmoid和Tanh;二者必须与对应激活函数匹配,否则易致梯度消失或爆炸,尤其在深层网络中。

He 初始化和 Xavier 初始化不是“可选优化项”,而是针对不同激活函数的必要匹配策略。用错会导致训练卡在早期、loss不降、梯度几乎为零——尤其在深层网络中,这种问题往往被误判为数据或学习率问题。
He 初始化只适用于 ReLU 及其变体
He 初始化(也叫 kaiming 初始化)的核心假设是:激活函数在正半轴线性、负半轴截断(如 ReLU、LeakyReLU)。它让前向传播时「状态值」(即激活函数输入)的方差保持稳定。
- 如果你用了
nn.ReLU()却用Xavier,前几层输出容易饱和,梯度变小 - 如果你用了
nn.Tanh()却用He,权重初始范围偏大,第一轮 forward 就可能溢出或梯度爆炸
He 的 PyTorch 实现必须显式指定 nonlinearity:
nn.init.kaiming_normal_(layer.weight, mode='fan_in', nonlinearity='relu') nn.init.kaiming_uniform_(layer.weight, mode='fan_in', nonlinearity='leaky_relu')
-
mode='fan_in'(默认):适配前向传播稳定性,更常用 -
mode='fan_out':适配反向传播稳定性,仅在特定自定义层中需手动调整
注意:nonlinearity='relu' 不能写成 'ReLU' 或 'torch.nn.ReLU',否则会静默忽略参数,退化为标准正态分布。
立即学习“Python免费学习笔记(深入)”;
Xavier 初始化只适用于 Sigmoid 和 Tanh
Xavier(Glorot)初始化要求激活函数关于 0 对称、可导、输出有界——这正好是 Sigmoid 和 Tanh 的特性。它同时约束前向激活值和反向梯度的方差。
快速生成专业的 Python 脚本和应用代码。一键创建完整项目结构,支持CLI、API、爬虫、Bot、Django等多种项目类型,包含完整的项目结构、配置文件、依赖管理、测试、README和文档。
- 在 PyTorch 中,
nn.Sigmoid()和nn.Tanh()配Xavier是安全组合 - 但如果你把
nn.Sigmoid()换成torch.sigmoid()(函数式调用),nn.init.xavier_*依然有效——因为初始化只看层结构,不依赖激活层是否是模块实例
常用写法:
nn.init.xavier_uniform_(layer.weight, gain=nn.init.calculate_gain('tanh'))
nn.init.xavier_normal_(layer.weight, gain=nn.init.calculate_gain('sigmoid'))-
gain不是可有可无的参数:它根据激活函数斜率自动缩放方差,漏掉会导致实际初始化范围偏大(sigmoid的 gain ≈ 1,tanh≈ 5/3) - 如果你用自定义激活函数(比如
Swish),calculate_gain不支持,需手动设gain=1.0或查论文推荐值
全局初始化别只靠 apply(),要检查 weight 和 bias 是否都被覆盖
很多人写:
def init_fn(m):
if isinstance(m, nn.Linear):
nn.init.kaiming_normal_(m.weight)
model.apply(init_fn)这会漏掉 bias ——而 nn.Linear 默认初始化 bias 为 0,通常没问题,但如果你禁用了 bias(bias=False),这段代码就完全没效果。
更稳妥的做法是明确处理:
def init_fn(m):
if isinstance(m, nn.Linear):
nn.init.kaiming_normal_(m.weight, nonlinearity='relu')
if m.bias is not None:
nn.init.zeros_(m.bias) # 偏置统一清零,除非你有特殊理由同样要注意:卷积层(nn.Conv2d)也支持 kaiming<em>*</em> 和 xavier*,但 fan_in 计算方式不同(含 kernel size),PyTorch 内部已自动处理,无需手动改参数。
He 和 Xavier 的区别不在“谁更强”,而在“谁不破坏你激活函数的数学前提”。用错一个,模型可能跑三天才发现 loss 停在 0.69 不动——这时候翻初始化代码比调 learning rate 更快定位问题。

















