搞清楚 BatchNorm、LayerNorm、RMSNorm 到底在干嘛

Infy AI Lv2

训练神经网络的时候,Normalization 几乎是标配。但 BatchNorm、LayerNorm、RMSNorm 这些东西,我之前一直没彻底搞明白它们的区别。公式都差不多,都是减均值除标准差,那到底差在哪?

这篇把它们放一起对比一下,顺便理一理各自适用的场景。

先从最基础的问题开始:为什么要 Normalize?

神经网络训练时有个烦人的问题:每一层的输入分布会随着前面层参数的更新而变化。这个现象叫 Internal Covariate Shift(ICS)。

直觉上理解:你在训练第 5 层的时候,第 4 层的输出分布变了,那第 5 层学到的东西可能就不太对了。就像你在练习投篮,但篮筐一直在移动。

但这个解释其实有点问题。2018 年 MIT 的一篇论文 How Does Batch Normalization Help Optimization? 做了实验,发现 BatchNorm 的效果和 ICS 关系不大。他们甚至故意往 BatchNorm 之后注入噪声来增加 ICS,结果模型训练得依然很好。

那 Normalization 到底在帮什么忙?

更靠谱的解释是:Normalization 让 loss landscape 变得更平滑了。

没有 Normalization 的时候,loss 曲面可能很崎岖,梯度方向变化剧烈,得用很小的学习率才能稳定训练。加了 Normalization 之后,loss 曲面变平滑了,梯度方向更一致,可以用更大的学习率,收敛更快。

从数学上看,Normalization 实际上是在约束每一层输出的尺度。如果没有这个约束,权重的微小变化可能导致输出的巨大变化,梯度就会爆炸。Normalization 相当于给每一层加了一个”稳压器”。

BatchNorm:开创者,但有硬伤

BatchNorm 是 2015 年 Ioffe 和 Szegedy 提出的,算是 Normalization 家族的开山之作。

公式推导

假设一个 mini-batch 包含 个样本 ,对于某一个特征维度(或者 CNN 里的某个通道),BatchNorm 的计算过程是:

第一步:计算 batch 内的均值

第二步:计算 batch 内的方差

第三步:归一化

这里 是一个很小的数(比如 ),防止除零。

第四步:缩放和偏移

等等,刚归一化完又加 ,这不是白干了吗?

不是的。归一化是强制把分布限制在均值 0、方差 1,但这可能不是最优的分布。 是可学习的参数,让网络自己决定需要什么样的分布。极端情况下,如果网络学到 ,那就等于没有归一化。

训练和推理的不一致

BatchNorm 有个麻烦的地方:训练时用的是当前 batch 的统计量,但推理时 batch size 可能是 1,没法算统计量。

解决方案是用 移动平均。训练过程中维护全局的均值和方差:

推理时就用这个

这带来一个问题:训练和推理的行为不一致。如果你忘了调用 model.eval(),或者训练时的 batch 分布和推理时差异很大,就可能出问题。我之前就踩过这个坑,调了半天才发现是 BatchNorm 的锅。

对 batch size 的依赖

BatchNorm 对 batch size 很敏感。batch size 太小的话, 的估计就不准,方差可能很大。

一般来说,batch size 至少要 16 以上,BatchNorm 才能稳定工作。但有些任务(比如目标检测、分割)由于显存限制,batch size 经常只有 2 或 4,这时候 BatchNorm 就不太行了。

后来有人提出了 GroupNorm 来解决这个问题,但那是另一个故事了。

BatchNorm 的梯度

这部分稍微硬核一点,但理解梯度对于理解 BatchNorm 的行为很重要。

,我们来推导

由于 都依赖于所有的 ,所以求导会有点复杂。设 ,那么:

这个式子有什么含义?

  • :来自上游的梯度
  • :减去梯度的均值(类似于中心化)
  • :减去和方向相关的分量

后两项可以理解为一种”去相关”操作,让梯度分布更均匀,这也是为什么 BatchNorm 能让训练更稳定。

LayerNorm:Transformer 的标配

BatchNorm 在 CNN 上效果很好,但到了 RNN 和 Transformer 这边就不太行了。原因很简单:序列任务里,不同样本的长度可能不一样,在 batch 维度上取统计量不太合理。

2016 年 Ba 等人提出了 LayerNorm,思路是:不跨样本,只在单个样本的特征维度上做归一化。

公式

对于一个样本的特征向量

注意这里 是对每个特征位置单独设置的,形状是

和 BatchNorm 的对比

用一张图来说明会更清楚。假设输入形状是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
输入张量: (B, T, D)
B = batch size
T = 序列长度
D = 特征维度(hidden size)

BatchNorm: 对每个特征位置 d ∈ [1,D]
计算所有 (b,t) 位置的均值和方差
→ 归一化维度: (B, T)
→ 每个 d 共享一组统计量

LayerNorm: 对每个 (b,t) 位置
计算所有 d ∈ [1,D] 的均值和方差
→ 归一化维度: (D,)
→ 每个 (b,t) 位置独立计算

关键区别:

  • BatchNorm 让同一个特征在不同样本之间对齐
  • LayerNorm 让同一个样本的不同特征之间对齐

为什么 Transformer 用 LayerNorm?

几个原因:

  1. 不依赖 batch:每个样本独立计算,batch size 是 1 也能正常工作
  2. 处理变长序列:不同样本长度不一样也没问题
  3. 训练推理一致:不需要维护移动平均,train()eval() 行为相同

但 LayerNorm 也有缺点。它假设同一层的不同特征之间有可比性,这在某些情况下可能不成立。比如,如果特征的第 1 维表示”年龄”,第 2 维表示”收入”,把它们一起归一化就有点奇怪。

不过在 Transformer 里,hidden state 的每一维没有明确的语义,所以这个问题不大。

LayerNorm 的位置:Pre-Norm vs Post-Norm

原始 Transformer(Vaswani 2017)用的是 Post-Norm:

1
2
3
4
5
# Post-Norm
x = x + Attention(x)
x = LayerNorm(x)
x = x + FFN(x)
x = LayerNorm(x)

后来发现 Pre-Norm 训练更稳定,尤其是在深层网络里:

1
2
3
# Pre-Norm
x = x + Attention(LayerNorm(x))
x = x + FFN(LayerNorm(x))

为什么 Pre-Norm 更稳定?

直觉上,Pre-Norm 相当于给残差路径加了一个”开关”。在训练初期,Attention 和 FFN 的输出可能很不稳定,但由于有 LayerNorm 在前面”压住”,输出的尺度不会太离谱。而 Post-Norm 是先加了残差再归一化,如果 Attention 输出炸了,加上残差之后再归一化可能已经来不及了。

从梯度角度看,Pre-Norm 的梯度可以直接通过残差连接流回去,不会被 LayerNorm 截断。而 Post-Norm 的梯度必须经过 LayerNorm,可能会被”调制”。

现在大部分 LLM(GPT、LLaMA、Qwen 等)都用 Pre-Norm。

RMSNorm:去掉均值,更快更简单

2019 年 Zhang 和 Sennrich 提出了 RMSNorm(Root Mean Square Normalization),核心思想是:LayerNorm 里减均值这一步,真的有必要吗?

公式

RMSNorm 只用 RMS(均方根)来归一化:

注意这里没有 (偏移项)。原论文里也没加,因为实验发现加不加效果差不多。

和 LayerNorm 的对比

把两者拆开看:

LayerNorm 做了两件事

  1. 减均值(中心化):
  2. 除标准差(缩放):

RMSNorm 只做一件事

  1. 除 RMS(缩放):

数学上,LayerNorm 和 RMSNorm 的关系是:

这是因为:

如果 ,那么 ,两者就差不多了。

为什么去掉均值也可以?

这是个好问题。我的理解是:

  1. Pre-Norm 架构下,均值的影响不大。残差连接本身会累积偏移,LayerNorm 减均值只是暂时”清零”了一下,但过了残差连接偏移又回来了。

  2. 可学习的 可以补偿。如果网络真的需要某种偏移, 可以学到。

  3. 实验说话。论文里做了大量实验,发现 RMSNorm 和 LayerNorm 效果几乎一样。

计算效率

RMSNorm 省掉了:

  • 计算均值
  • 减均值
  • 偏移项 的加法和存储

这些节省对于 LLM 这种规模的模型来说很可观。论文报告说大概能减少 7%-15% 的 Normalization 计算时间。

考虑到 Transformer 里 Norm 层的数量(每个 layer 有两个),这个优化是值得的。

实现对比

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import torch
import torch.nn as nn

class LayerNorm(nn.Module):
def __init__(self, dim, eps=1e-6):
super().__init__()
self.eps = eps
self.gamma = nn.Parameter(torch.ones(dim))
self.beta = nn.Parameter(torch.zeros(dim))

def forward(self, x):
mean = x.mean(dim=-1, keepdim=True)
var = x.var(dim=-1, keepdim=True, unbiased=False)
x_norm = (x - mean) / torch.sqrt(var + self.eps)
return self.gamma * x_norm + self.beta


class RMSNorm(nn.Module):
def __init__(self, dim, eps=1e-6):
super().__init__()
self.eps = eps
self.gamma = nn.Parameter(torch.ones(dim))

def forward(self, x):
rms = torch.sqrt(x.pow(2).mean(dim=-1, keepdim=True) + self.eps)
x_norm = x / rms
return self.gamma * x_norm

RMSNorm 的代码更短,计算更少。

其他变体:GroupNorm、InstanceNorm

既然都整理了,顺便把其他几种 Norm 也说一下。

InstanceNorm

InstanceNorm 最早用在风格迁移任务里。它对每个样本的每个通道单独做归一化。

对于形状 的输入,InstanceNorm 在 维度上计算统计量:

可以理解为:每张图的每个通道,单独归一化。

用途:风格迁移、图像生成。在这些任务里,每张图的风格信息很重要,不希望被 batch 里其他图片”污染”。

GroupNorm

GroupNorm 是 2018 年 He 等人提出的,介于 LayerNorm 和 InstanceNorm 之间。

它把 个通道分成 个组,每组内做归一化:

时,GroupNorm 退化成 InstanceNorm。
时,GroupNorm 接近 LayerNorm。

用途:小 batch size 的 CNN 任务(目标检测、分割等)。在 batch size = 1 或 2 的情况下,GroupNorm 效果比 BatchNorm 好很多。

总结对比

方法 归一化维度 依赖 batch 主要用途
BatchNorm 对每个 CNN(batch size >= 16)
LayerNorm 对每个 Transformer
RMSNorm 对每个 LLM
InstanceNorm 对每个 风格迁移
GroupNorm 对每个 小 batch CNN

深入理解:Normalization 的几何意义

这部分稍微抽象一点,但有助于理解为什么这些 Norm 能 work。

把 Normalization 看成几何变换:

  1. 减均值:把数据中心移到原点(平移)
  2. 除标准差:把数据缩放到单位球面(缩放)

LayerNorm 是把每个样本的特征向量投影到单位球面上(严格来说是经过缩放后的球面)。

RMSNorm 更直接:就是把向量除以它的(加权)模长。

从这个角度看,Normalization 是在限制每一层输出的”能量”或”幅度”,防止信号在层与层之间传播时不断放大。

实践建议

最后给一些工程上的建议:

  1. CNN(batch size >= 16):用 BatchNorm,效果经过充分验证
  2. CNN(batch size < 16):考虑 GroupNorm 或者同步 BatchNorm
  3. Transformer(小模型):LayerNorm 和 RMSNorm 都可以
  4. LLM(大模型):优先 RMSNorm,省计算
  5. 训练不稳定:检查 Norm 的位置(Pre-Norm 通常更稳定)
  6. 推理行为异常:检查是否正确设置了 eval() 模式(BatchNorm 的坑)

关于 的选择:一般 就够了。如果用 float16/bfloat16 训练,可以稍微调大一点()防止数值问题。


写到这里,这些 Norm 方法的脉络应该比较清楚了:

BatchNorm 解决了深层 CNN 的训练问题,但依赖 batch → LayerNorm 去掉 batch 依赖,适配了 Transformer → RMSNorm 进一步简化,去掉均值计算,大模型更友好。

选择哪种 Norm,主要看你的模型结构和计算约束。没有绝对的好坏,只有适不适合。

  • 标题: 搞清楚 BatchNorm、LayerNorm、RMSNorm 到底在干嘛
  • 作者: Infy AI
  • 创建于 : 2025-12-26 10:30:00
  • 更新于 : 2025-12-26 11:52:58
  • 链接: https://www.rasior.com/2025/12/26/normalization-notes/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。