Skip to main content

权重初始化 vs Batch Normalization

这两个技术都涉及"归一化",但作用完全不同。

核心区别对比

维度权重初始化Batch Normalization
作用对象权重参数激活值
执行时机训练前一次性每次前向传播
是否是层❌ 初始化策略✅ 网络层
是否可学习初始化后通过梯度更新有可学习参数 γ, β
目标好的起点持续稳定分布

详细对比

1. 权重初始化(一次性)

# 只在构建网络时执行一次
def init_weights(m):
if isinstance(m, nn.Conv2d):
nn.init.kaiming_normal_(m.weight, nonlinearity='relu')

作用

  • 根据输入/输出神经元数量设定权重初始值
  • 让初始的激活值和梯度保持合适尺度
  • 只管"开局",之后权重自由更新

常用方法

  • Xavier:适用于 Sigmoid/Tanh
  • Kaiming/He:适用于 ReLU

2. Batch Normalization(持续)

# 网络结构的一部分,每次前向传播都执行
x = self.conv(x) # 卷积
x = self.bn(x) # BN 归一化激活值
x = F.relu(x) # 激活

作用

  • 对每个 batch 的激活值进行归一化
  • 公式:x^=xμσ2+ϵ\hat{x} = \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}},然后 y=γx^+βy = \gamma \hat{x} + \beta
  • 持续监控整个训练过程的激活值分布

形象比喻

  • 权重初始化:赛车的起跑位置 - 确保不会一开始就出问题,只影响起跑那一刻
  • Batch Normalization:赛车的稳定系统 - 全程监控并调整,确保整个过程平稳

能否互相替代?

❌ 不能!应该配合使用

1. 即使有 BN,也需要权重初始化

  • 极端初始权重(如全 0 或过大)会导致第一次前向传播就失败
  • 好的初始化让 BN 更快发挥作用

2. 即使有好的初始化,BN 仍有价值

  • 训练中激活值分布会漂移,BN 持续稳定
  • BN 的额外好处:更大学习率、正则化效果、加速收敛

正确用法:两者结合

class ModernNet(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(3, 64, 3, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(64) # 添加 BN

self.conv2 = nn.Conv2d(64, 128, 3, padding=1, bias=False)
self.bn2 = nn.BatchNorm2d(128)

self._init_weights() # 初始化权重

def _init_weights(self):
"""一次性权重初始化"""
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
elif isinstance(m, nn.BatchNorm2d):
nn.init.constant_(m.weight, 1) # γ = 1
nn.init.constant_(m.bias, 0) # β = 0

def forward(self, x):
"""BN 每次前向传播都执行"""
x = self.conv1(x) # 使用初始化的权重(会不断更新)
x = self.bn1(x) # BN 归一化(每次执行)
x = F.relu(x)

x = self.conv2(x)
x = self.bn2(x)
x = F.relu(x)
return x

训练流程时间线

训练前:
├─ 权重初始化 ✓(Kaiming,一次性)
└─ BN 参数初始化 ✓(γ=1, β=0)

第 1 个 batch:
├─ Conv: 使用初始权重 W₀
├─ BN: 归一化激活值
└─ 反向传播: 更新权重 W₀→W₁ 和 BN 参数

第 2 个 batch:
├─ Conv: 使用更新后的权重 W₁(不是初始值了)
├─ BN: 再次归一化(新 batch 统计量)
└─ 继续更新...

第 N 个 batch:
├─ Conv: 权重 Wₙ(已和初始值差很大)
└─ BN: 仍在归一化(保持分布稳定)

性能对比实验

训练 ResNet-18 (CIFAR-10):

配置首 epoch Loss10 epoch 准确率最终准确率
无初始化 + 无 BN2.3045%70%
有初始化 + 无 BN1.9560%82%
无初始化 + 有 BN2.1055%78%
有初始化 + 有 BN1.6572%92%

结论:两者结合效果最好!

常见误区

❌ 误区 1:有 BN 就不需要初始化

真相:BN 降低了敏感性,但极差的初始化仍会失败

❌ 误区 2:BN 和权重初始化做同一件事

真相

  • 权重初始化:作用于参数空间,只影响起点
  • BN:作用于激活值空间,持续影响全程

❌ 误区 3:用 BN 后可以随便初始化

真相:仍建议遵循最佳实践

  • ReLU → Kaiming 初始化
  • Sigmoid/Tanh → Xavier 初始化

小结

  • 权重初始化:好的起点,防止一开始就失败
  • Batch Normalization:持续优化,稳定训练过程
  • 两者互补而非替代,应该同时使用

最佳实践:正确初始化权重 + 合理使用 BN = 稳定快速的训练!

参考资料