BatchNorm

AI
  • Batch Normalization(批量归一化) 是一种标准化技术,用于深度神经网络训练,尤其CV

Batch Norm做了什么

对于一个批次里的多个样本,它们有相同的特征。但不同样本的同一个特征,数值范围可能差异很大。比如一个批次里有两个人,A年收入500万,B年收入5万。那么这两个样本传入网络时,年收入这个特征的数值范围波动剧烈,导致模型在批次之间来回调整,训练不稳定。

所以我们需要让同一个特征在不同样本之间的数值范围接近,对每个特征在批次维度上进行归一化也就是让每个特征在当前批次上的均值为0、方差为1。

对比记忆:

  • LayerNorm:对一个样本的所有特征做归一化(行内归一化)
  • BatchNorm:对一个批次内的同一个特征做归一化(列内归一化)

BatchNorm解决了什么

它主要解决的是训练过程中的内部协变量偏移(ICS),但视角和LayerNorm不同。

1. 内部协变量偏移

首先你需要知道模型的训练过程:
前向传播 → 计算损失 → 反向传播 → 计算梯度 → 更新所有层的参数(W1,W2,W3…)

1
2
3
4
5
6
7
8
9
10
11
12
13
# 假设一个2层网络,批次大小为2
# 批次输入:两个样本
x = [[1, 100], # 样本1:特征1=1,特征2=100
[2, 50]] # 样本2:特征1=2,特征2=50
# 第1步训练
W1 = [[0.1, 0.2]] # 初始权重
h1 = x @ W1.T = [[0.1*1+0.2*100, 0.1*2+0.2*50]] = [[20.1, 10.2]] # 输出范围正常
# 计算损失,更新W1(假设梯度让W1变大)
W1_new = [[0.5, 0.6]]
h1_new = x @ W1_new.T = [[0.5*1+0.6*100, 0.5*2+0.6*50]] = [[60.5, 31.0]]
# 第2层看到h1从[20.1, 10.2]变成[60.5, 31.0]
# 变化很大!而且两个样本的特征1和特征2之间的比例也变了
# 这就是BatchNorm要解决的第2层输入分布不稳定问题

我们知道模型训练过程中,参数会不断更新,导致每一层的输入分布也在变化。如果同一个特征在不同样本之间数值范围波动太大(比如年收入这个特征,有的样本是5万,有的是500万),那么:

  • 梯度计算会被大数值样本主导:年收入500万的那个样本,它的梯度会远远大于年收入5万的样本,模型只关注“有钱人”,忽略了“普通人”的模式。
  • 训练震荡:这个批次样本A(高收入)主导更新,下个批次样本B(低收入)主导更新,模型来回摇摆,难以收敛。

2. 对学习率更友好

没有BatchNorm时,你对学习率非常敏感:

  • 学习率稍大:遇到大数值样本,一步跨太远,崩了
  • 学习率稍小:遇到小数值样本,几乎不动- Batch Normalization(批量归一化) 是一种标准化技术,用于深度神经网络训练
    有了BatchNorm,每个特征的数值范围都被稳定在相似的尺度上,你可以用更大的学习率,训练更快更稳。

注意:BatchNorm主要解决的是批次内特征尺度不一致导致的训练不稳定,而不是直接解决梯度爆炸/消失(虽然它能缓解)。梯度爆炸/消失更多是网络深度和激活函数的问题。

BatchNorm的具体实现

前文提到,我们需要对每个特征批次维度上进行归一化,也就是让这个特征在当前批次上的均值为0、方差为1。

公式

其中:

  • μ_B:当前批次上,某个特征的平均值

  • σ_B^2:当前批次上,某个特征的方差

  • γβ:可学习的缩放和平移参数(和LayerNorm一样)

举个例子

假设一个批次有2个样本,每个样本有3个特征(年龄、年收入、步数):

text

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
批次数据:
样本A: [25, 500000, 8000]
样本B: [35, 300000, 6000]

**对“年收入”这个特征进行BatchNorm**(其他特征同理):

1. 计算这一列的均值:μ = (500000 + 300000) / 2 = 400000

2. 计算这一列的方差:σ² = ((500000-400000)² + (300000-400000)²) / 2 = (100000² + (-100000)²) / 2 = 10^10

3. 标准差:σ = 100000

4. 归一化:

- 样本A的年收入:(500000 - 400000) / 100000 = 1

- 样本B的年收入:(300000 - 400000) / 100000 = -1

经过BatchNorm处理后

text

1
2
样本A: [年龄归一化后, 1, 步数归一化后]
样本B: [年龄归一化后, -1, 步数归一化后]

γ和β同样是可学习参数。如果网络发现原始分布更好,可以把γ=100000、β=400000学回来(还原原始值);如果某种中间分布更好,也可以调整。

和[[LayerNorm]]的对比

操作 对谁归一化 结果
LayerNorm 一个样本的所有特征 这个样本的3个特征之间范围接近
BatchNorm 一个特征的所有样本 这个特征在不同样本之间范围接近

用上面的例子:

  • LayerNorm后:样本A自己的年龄、收入、步数三个数范围接近(比如[-0.7, 1.4, -0.7])

  • BatchNorm后:样本A和样本B的收入这两个数范围接近(比如[1, -1])

这样下来你得到了什么?

  1. 特征尺度统一:不同样本的同一个特征不再有量级差异。年收入500万和30万的人,在归一化后可能变成1和-0.5,处于同一数量级。高收入样本不再主导梯度。
  2. 训练更稳定:每个批次输入给下一层的分布都大致相同(均值0、方差1),参数更新不再被批次间的数值波动干扰。
  3. 可以使用更大的学习率:因为数值范围被控制住了,不用担心一步踩空。
  4. 有一定正则化效果:因为每个批次的均值和方差都有微小波动,相当于给训练引入了噪声,可以防止过拟合(这也是为什么BatchNorm层后面通常不需要再加Dropout的原因之一)。

一个关键的注意事项

BatchNorm在训练和推理时的行为不同

  • 训练时:用当前批次的均值和方差
  • 推理时:用训练过程中所有批次的移动平均(running average),因为推理时可能只有一个样本,没法算批次统计量

这是BatchNorm和LayerNorm的一个本质区别:LayerNorm不依赖批次大小,训练推理行为一致;BatchNorm依赖批次大小,且训练推理行为不同。

站内搜索
常搜: