共计 1337 个字符,预计需要花费 4 分钟才能阅读完成。
背景与痛点
在深度学习中,Normalization(归一化)技术是训练稳定性的重要保障。对于 Transformer 架构来说,归一化层的选择尤为关键。传统上,Layer Normalization(LN)因其对序列数据的适应性成为主流选择,但 Batch Normalization(BN)在某些场景下可能表现更优。

- LN 的局限性 :虽然 LN 在序列任务中表现稳定,但它忽略了 batch 维度上的统计信息,可能导致部分任务的信息损失
- BN 的优势场景 :当 batch size 足够大且数据分布相对稳定时,BN 往往能提供更好的梯度传播特性
技术对比:BN vs LN
- 计算方式差异
- BN 沿 batch 维度计算均值方差,对 batch size 敏感
-
LN 沿特征维度计算,更适合变长序列
-
训练动态性
- BN 的统计量会随 batch 变化,带来轻微正则化效果
-
LN 提供更稳定的训练曲线
-
推理差异
- BN 需要维护 running stats,LN 则不需要
PyTorch 实现细节
import torch
import torch.nn as nn
class TransformerWithBN(nn.Module):
def __init__(self, d_model, nhead, num_layers):
super().__init__()
self.encoder_layers = nn.ModuleList([
nn.TransformerEncoderLayer(
d_model=d_model,
nhead=nhead,
norm_first=True,
# 关键替换:将默认的 LN 替换为 BN
norm_layer=nn.BatchNorm1d(d_model)
) for _ in range(num_layers)
])
def forward(self, src):
# 需要将序列维度与 batch 维度交换
# (seq_len, batch, features) -> (batch, features, seq_len)
src = src.permute(1, 2, 0)
for layer in self.encoder_layers:
src = layer(src)
return src.permute(2, 0, 1)
性能考量
通过 ImageNet 上的 ViT 实验对比:
- batch_size=256 时
- BN:Top- 1 准确率 78.3%,训练波动±0.5%
-
LN:Top- 1 准确率 77.1%,训练波动±0.3%
-
batch_size=32 时
- BN:Top- 1 准确率 72.8%,训练波动±2.1%
- LN:Top- 1 准确率 75.4%,训练波动±0.7%
避坑指南
- 小 batch size 问题
- 解决方案:使用同步 BN(SyncBN)跨多卡计算统计量
-
替代方案:采用 running stats 的动量调大(0.99→0.999)
-
序列长度变化
-
处理技巧:对短序列进行 padding 并添加 mask
-
初始化敏感
- 建议:将 BN 层的 weight 初始化为 1,bias 初始化为 0
总结与选型建议
根据任务特点选择:
- 优先考虑 BN 的场景:
- 固定长度的输入(如图像 patch 序列)
- 大批量训练环境(batch_size>128)
-
对推理速度要求严格的部署
-
坚持使用 LN 的场景:
- 变长序列处理
- 小批量训练
- 需要强稳定性的任务
实践中可以尝试在浅层使用 BN、深层使用 LN 的混合方案,往往能获得更好的效果。
正文完
发表至: 深度学习
四天前
