核心问题:为什么需要归一化?神经网络训练时,每层的输入分布会随参数更新不断变化(Internal Covariate Shift),导致训练不稳定、收敛慢。归一化就是把数据"拉回"到均值为0、方差为1的分布,再通过可学习参数还原表达能力。
一、公式(两者一样,区别在于"沿哪个维度算")
$$ \hat{x} = \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}}, \quad y = \gamma \hat{x} + \beta $$
- $\mu$、$\sigma^2$:均值和方差(统计维度不同是BN和LN的核心区别)
- $\gamma$、$\beta$:可学习的缩放和偏移参数
- $\epsilon$:防止除零的小常数
二、Batch Norm(BN)
核心思想
跨样本、同一特征维度做归一化。
统计维度
假设输入 shape 为 [B, C, H, W](B=batch,C=通道,H/W=空间):
- 对每个通道 C,在 B、H、W 三个维度上计算均值和方差
- 每个通道有一组独立的 $\gamma$、$\beta$
直觉理解
“把这批图片里,同一个通道的所有像素值,统一归一化”
具体例子
输入:4张图,每张1个通道,2x2像素
数据(展平后每行是一张图的像素):
图1: [1, 2, 3, 4]
图2: [5, 6, 7, 8]
图3: [2, 3, 4, 5]
图4: [6, 7, 8, 9]
BN 把这 4×4=16 个数一起算均值和方差:
所有数:1,2,3,4,5,6,7,8,2,3,4,5,6,7,8,9
μ = (1+2+3+4+5+6+7+8+2+3+4+5+6+7+8+9) / 16 = 80/16 = 5.0
σ² = [(1-5)²+(2-5)²+...+(9-5)²] / 16 = 88/16 = 5.5
σ = √5.5 ≈ 2.345
归一化示例(以图1的像素值1为例):
x̂ = (1 - 5.0) / √(5.5 + ε) ≈ -4.0 / 2.345 ≈ -1.706
所有16个像素值都用同一个 μ=5.0、σ≈2.345 归一化
优点
- 效果好,训练稳定,允许更大学习率
- CV 任务(CNN)的标配
缺点
- 依赖 batch size:batch 太小时均值/方差估计不准,效果差
- 推理时需要维护全局统计量(running mean/var)
- 不适合 RNN/Transformer:序列长度不固定,batch 内样本差异大
三、Layer Norm(LN)
核心思想
同一样本、跨特征维度做归一化。
统计维度
假设输入 shape 为 [B, T, D](B=batch,T=序列长度,D=特征维度):
- 对每个 token(每个位置),在 D 维度上计算均值和方差
- 每个样本独立归一化,不依赖其他样本
直觉理解
“把这个词的所有特征值,归一化到同一尺度”
具体例子
输入:1个句子,3个词,每词4维特征
数据(每行是一个词的特征向量):
词1: [1, 2, 3, 4]
μ = (1+2+3+4)/4 = 2.5
σ² = [(1-2.5)²+(2-2.5)²+(3-2.5)²+(4-2.5)²] / 4 = [2.25+0.25+0.25+2.25]/4 = 1.25
σ = √1.25 ≈ 1.118
归一化后: [(-1.5/1.118), (-0.5/1.118), (0.5/1.118), (1.5/1.118)] ≈ [-1.342, -0.447, 0.447, 1.342]
词2: [5, 6, 7, 8]
μ = (5+6+7+8)/4 = 6.5
σ² = [(5-6.5)²+(6-6.5)²+(7-6.5)²+(8-6.5)²] / 4 = [2.25+0.25+0.25+2.25]/4 = 1.25
归一化后: ≈ [-1.342, -0.447, 0.447, 1.342](和词1形状相同,因为数值等间距)
词3: [2, 4, 6, 8]
μ = (2+4+6+8)/4 = 5.0
σ² = [(2-5)²+(4-5)²+(6-5)²+(8-5)²] / 4 = [9+1+1+9]/4 = 5.0
σ = √5.0 ≈ 2.236
归一化后: [(-3/2.236), (-1/2.236), (1/2.236), (3/2.236)] ≈ [-1.342, -0.447, 0.447, 1.342]
每个词独立计算自己的 μ 和 σ,互不影响
优点
- 不依赖 batch size,batch=1 也能正常工作
- 推理和训练行为一致,无需维护全局统计量
- NLP/Transformer 的标配
缺点
- 在 CV 任务上效果通常不如 BN
四、对比总结
| 对比项 | Batch Norm | Layer Norm |
|---|---|---|
| 归一化维度 | 跨样本(Batch维) | 跨特征(Feature维) |
| 统计量依赖 | 依赖整个 batch | 仅依赖单个样本 |
| batch size 敏感 | ✅ 敏感(小batch效果差) | ❌ 不敏感 |
| 推理时 | 需要 running mean/var | 直接计算,无需额外状态 |
| 适用场景 | CNN / 图像任务 | Transformer / NLP / RNN |
| 代表模型 | ResNet、VGG | BERT、GPT、LLaMA |
五、一句话记忆法
- BN:同一特征,跨样本归一 → “列归一化”(竖着看)
- LN:同一样本,跨特征归一 → “行归一化”(横着看)
数据矩阵(行=样本,列=特征):
特征1 特征2 特征3
样本1 [ 1, 2, 3 ] ← LN 沿这一行归一化
样本2 [ 4, 5, 6 ] ← LN 沿这一行归一化
样本3 [ 7, 8, 9 ] ← LN 沿这一行归一化
↑ ↑ ↑
BN 沿每列归一化
六、代码速览(PyTorch)
import torch
import torch.nn as nn
x = torch.randn(8, 64, 32, 32) # [B, C, H, W]
# Batch Norm:对每个通道归一化
bn = nn.BatchNorm2d(64)
out_bn = bn(x)
# Layer Norm:对最后几个维度归一化(通常是特征维)
x_seq = torch.randn(8, 128, 512) # [B, T, D]
ln = nn.LayerNorm(512) # 对 D=512 这一维归一化
out_ln = ln(x_seq)