神经网络的权重初始化会直接影响前向传播中的激活分布,以及反向传播时梯度能否稳定流动。本文从一个线性层出发,逐步比较零初始化、小随机数、Xavier 初始化和 Kaiming 初始化。
本文整理自 hengproject/ML_recall ↗ 中的 basics/weight_initialization.ipynb ↗。课程内容参考 USC CSCI 566: Deep Learning and Its Applications。
从零初始化开始#
以一个线性层为例。使用增广记号,将偏置合并到输入向量中:
x=[x0,x1,…,xn,b],Y=wTx.
如果所有权重都初始化为零,那么无论输入如何变化,线性层的输出都会是零:
import numpy as np
import matplotlib.pyplot as plt
x = np.ones(100)
w = np.zeros(100)
y = w.T @ x
print(y) # 0.0
python
更重要的是,对具有多个同构神经元的网络而言,相同的初始权重会产生相同的输出和梯度,神经元无法学习出不同特征。因此,需要用非零随机值打破对称性。
小随机数初始化#
一种直观方法是从方差很小的高斯分布中采样权重:
w∼N(μ,σ2).
np.random.seed(2025)
w = 0.01 * np.random.randn(100)
y = w.T @ x
python
单层网络中,这似乎没有问题;但在深层网络中,每一层都会继续缩小信号。下面构造一个六层、使用 tanh 激活函数的网络:
h0=x,hi=tanh(hi−1WiT).
dims = [4096] * 7
activations = []
x = np.random.randn(16, dims[0])
for fan_in, fan_out in zip(dims[:-1], dims[1:]):
w = 0.01 * np.random.randn(fan_in, fan_out)
x = np.tanh(x @ w.T)
activations.append(x)
python

越靠后的层,激活值越集中在零附近。信号和梯度逐层衰减,网络会变得难以训练。
Xavier 初始化#
Xavier 初始化的目标是让输入与输出的方差尽可能保持一致。对 fan_in 个输入,常用的正态分布形式为:
W∼N(0,nin1).
假设 Wji 与 xi 相互独立、均值为零,且
Wji∼N(0,nin1),Var(xi)=σ2.
对线性变换 zj=∑iWjixi+bj,有:
Var(zj)=i=1∑ninVar(Wjixi)=i=1∑ninVar(Wji)Var(xi)=nin⋅nin1⋅σ2=σ2.
tanh 在零附近近似线性,因此这种初始化能够在一定程度上让各层激活保持相近的方差:
dims = [4096] * 7
activations = []
x = np.random.randn(16, dims[0])
for fan_in, fan_out in zip(dims[:-1], dims[1:]):
w = np.random.randn(fan_in, fan_out) / np.sqrt(fan_in)
x = np.tanh(x @ w.T)
activations.append(x)
python

Xavier 与 ReLU#
将相同的 Xavier 初始化直接用于 ReLU,激活分布仍然会随网络加深而收缩:
for fan_in, fan_out in zip(dims[:-1], dims[1:]):
w = np.random.randn(fan_in, fan_out) / np.sqrt(fan_in)
x = np.maximum(0, x @ w.T)
python

ReLU 会把负值截断为零。在输入关于零对称的近似条件下,可将其视为使 E[z2] 大约减半。为保持尺度,需要令:
Var(zj)Var(ReLU(zj))=ninσw2σx2,≈21ninσw2σx2.
要求输出尺度与输入一致,可得:
21ninσw2σx2=σx2⟹σw2=nin2.
Kaiming 初始化#
因此,对 ReLU 网络可按下面的标准差初始化权重:
σw=nin2.
dims = [4096] * 7
activations = []
x = np.random.randn(16, dims[0])
for fan_in, fan_out in zip(dims[:-1], dims[1:]):
w = np.random.randn(fan_in, fan_out) * np.sqrt(2 / fan_in)
x = np.maximum(0, x @ w.T)
activations.append(x)
python

| 初始化方法 | 典型尺度 | 更适合的激活函数 |
|---|
| 小随机数 | 0.01⋅N(0,1) | 浅层网络或实验基线 |
| Xavier | Var(W)≈1/nin | tanh、sigmoid 等近似对称激活 |
| Kaiming | Var(W)≈2/nin | ReLU 及其变体 |
初始化方法的核心不是记住常数,而是控制信号在网络深度方向上的尺度。实际使用时,还应结合激活函数、残差连接、归一化层和框架提供的初始化 API 共同考虑。