Batch Normalization 是什么?为什么能加速训练?
简化版
Batch Normalization(批归一化,BN) 是对选定层的激活按 mini-batch 与特征/通道维做标准化的技术:对一个 mini-batch,把某层的激活值减均值、除标准差拉成均值 0、方差 1,再乘一个可学习的缩放 γ、加一个可学习的平移 β 恢复表达能力。作用:① 改善激活与梯度的数值尺度、使优化更平滑;“内部协变量偏移”是原论文解释但不是唯一机制,从而缓解梯度消失、加速收敛**;② 允许用更大的学习率、对初始化不那么敏感;③ 有轻微正则化效果(batch 统计带来的噪声)。训练时用 batch 的均值方差,推理时用训练阶段累积的全局均值方差。放在全连接/卷积层之后、激活之前(常见做法)。
详细版
BN 做什么(对每个特征维度):
① 算 batch 内均值 μ、方差 σ²
② 标准化:x̂ = (x - μ) / √(σ² + ε) → 均值0、方差1
③ 缩放平移:y = γ·x̂ + β → γ、β 可学习,恢复表达能力
为什么有效:
| 好处 | 原因 |
|---|---|
| 加速收敛 | 稳定各层输入分布,激活落在导数大的区域 |
| 缓解梯度消失 | 归一化后激活不易饱和,梯度更稳定 |
| 可用大学习率 | 数值稳定,不易发散 |
| 对初始化不敏感 | 每层输入被重新标准化 |
| 轻微正则 | batch 统计的噪声类似 Dropout |
训练 vs 推理(关键):
- 训练:用当前 mini-batch 的均值/方差。
- 推理:用训练时累积的全局(移动平均)均值/方差(推理没有 batch,且要结果确定)。
完整版教学
一、要解决的问题:层输入分布不断漂移
训练深层网络时,每一层的输入分布会随着前面层参数的更新而不断变化——前面层一变,后面层收到的输入分布就跟着变,后面层得反复适应「动来动去」的输入。这种现象被称为内部协变量偏移(Internal Covariate Shift)。它让训练变慢、需要更小的学习率、对初始化敏感。
Batch Normalization 的思路很直接:既然层输入分布老在漂移,那就在选定层对激活按规定维度标准化(拉回均值 0、方差 1),让每层收到的输入分布保持稳定。 这就像给每层一个「稳定的输入环境」,不用再反复适应漂移的分布。
(注:BN 有效的确切原因学界有争论,「减少内部协变量偏移」是原始解释,也有研究认为它主要是让损失曲面更平滑从而好优化——但「稳定分布、平滑优化」的直觉都指向同一效果。)
二、BN 具体怎么算——三步
对一个 mini-batch,在每个特征维度(或卷积的每个通道)上做:
① 求 batch 内均值和方差:
μ = batch 内该维度的平均
σ² = batch 内该维度的方差
② 标准化:
x̂ = (x - μ) / √(σ² + ε) → 拉成均值 0、方差 1(ε 防除零)
③ 缩放和平移(可学习):
y = γ · x̂ + β
关键是第③步的 γ(缩放)和 β(平移)是两个可学习的参数。为什么标准化完还要 γ、β?因为强制均值 0、方差 1 可能限制了该层的表达能力(比如 sigmoid 在 0 附近近似线性,全压到 0 附近就丢了非线性)。γ、β 让网络能在需要时把分布再调整回来——如果标准化不利,网络可以学出 γ、β 抵消它。所以 BN 既标准化了分布,又不牺牲表达能力。
三、为什么能加速训练、缓解梯度消失
- 稳定输入分布:每层输入被拉回稳定范围,后层不用反复适应漂移,训练更快更稳。
- 激活落在「敏感区」:把激活拉到均值 0 附近,避免落进 sigmoid/tanh 的饱和区(那里导数≈0),使激活函数导数较大、梯度不易消失(详见梯度消失专题)。
- 让损失曲面更平滑:归一化使优化更容易,梯度方向更可靠。
- 综合起来,BN 让网络收敛更快、能训练更深。
四、其他好处:大学习率、抗初始化、轻微正则
- 允许更大的学习率:数值被稳定,不易因大步长发散,从而可以用更大学习率进一步加速。
- 对权重初始化不那么敏感:反正每层输入都会被重新标准化,初始化差一点也能救回来。
- 轻微正则化效果:每个样本的归一化依赖于它所在的 mini-batch(用的是 batch 统计量),不同 batch 带来轻微随机噪声,类似 Dropout 的正则作用——用了 BN 后有时可以少用甚至不用 Dropout。
五、训练和推理的区别(高频考点)
这是 BN 最容易出错、也最常被追问的点:训练和推理用的均值方差不同。
- 训练时:用当前 mini-batch 的均值和方差来标准化。
- 推理时:没有 batch(可能一次只来一个样本),而且预测必须确定(不能因为同批别的样本不同而结果不同)。所以推理时用训练阶段累积的全局均值和方差——训练时用移动平均(running mean/var) 不断累积记录整个训练集的统计量,推理时直接拿来用。
所以用 BN 的网络,推理前要切换到 eval 模式(PyTorch 的 model.eval()),否则会错误地用单个 batch 的统计量,导致结果异常。这是实践中常见的坑。
训练模式用当前 mini-batch 的统计量归一化,并更新 running mean 与 running variance;推理模式通常使用训练期累计的 running 统计量。后两者是模型状态而不是通过反向传播学习的参数,γ、β 才是可学习参数。忘记切换 eval 模式会让单样本预测依赖当前批次,尤其在小 batch 下造成明显波动。
六、放在哪、局限与替代
- 位置:常放在线性/卷积之后,激活之前或依具体架构采用其他顺序(也有放激活后的实践)。
- 局限:依赖 batch 统计,所以小 batch 时效果差、不稳定(统计量不准);对 RNN/变长序列不友好(序列长度不一、batch 统计难做)。
- 替代:
- Layer Normalization(LN):在单个样本的特征维度上归一化,不依赖 batch——RNN、Transformer 用 LN。
- Group Norm、Instance Norm:小 batch 或特定任务(如风格迁移)用。
七、手算一个 batch,并看清训练与推理统计量
考虑某特征在一个 batch 中只有两个值 [1,3]。用训练前向常见的有偏方差计算,均值 μ=2、方差 σ²=1;忽略很小的 ε 后,标准化结果是 [-1,1]。若学到 γ=2,β=0.5,输出就变成 [-1.5,2.5],说明 γ、β 可以恢复或重塑尺度。
μ=(1+3)/2=2
σ²=[(1-2)²+(3-2)²]/2=1
x_hat=(x-2)/sqrt(1+ε) ≈ [-1,1]
y=2*x_hat+0.5 ≈ [-1.5,2.5]
框架在训练归一化和更新 running variance 时可能采用不同的有偏/无偏估计约定,动量参数的含义也可能不同,迁移实现时要查文档。推理时 running mean/variance 已冻结;若忘记 eval 模式,小 batch 预测会随同批样本变化。
记忆钩子:γ、β 是可学习参数,running mean/variance 是状态而不是通过反向传播学习的参数。
八、常见误区与追问
- 误区:BN 有效已经被完全证明只因为内部协变量偏移。 这是原始解释;平滑优化与重参数化等视角同样重要。
- 误区:推理时可以继续用当前请求的 batch 统计。 这会让单样本预测不稳定,常规 BN 应使用训练累计统计。
- 追问:卷积 BN 在哪些维度统计? 通常每个通道跨 batch 和空间位置统计,通道之间分别归一化。
- 追问:为什么小 batch 容易出问题? 均值方差估计噪声大,running statistics 也可能失真,可考虑 GroupNorm 或 SyncBN。
- 追问:BN 的 affine 参数能否关闭? 可以,但会减少可学习的尺度和平移自由度,是否合适取决于相邻层和任务。
九、加强记忆
Batch Normalization 对 mini-batch 内每层激活做标准化(x̂=(x-μ)/√(σ²+ε) 拉成均值0方差1),再用可学习的 γ、β 缩放平移恢复表达能力。作用:稳定各层输入分布(缓解内部协变量偏移)、让激活落在导数大的区域→缓解梯度消失、加速收敛、可用大学习率、对初始化不敏感、有轻微正则效果(batch 统计噪声)。关键区别:训练用当前 batch 的均值方差、推理用训练累积的全局(移动平均)均值方差(推理要切 eval 模式,否则出错)。位置:全连接/卷积后、激活前。局限:依赖 batch,小 batch 效果差、RNN/变长序列不友好 → 那些场景用 Layer Normalization(Transformer/RNN 用)。