介绍

在训练模型的时候,对于一个网络来说:

  • 前部:数据集中在前部,网络前面的层变化,则会导致后面的层也跟着变化->收敛速度慢
  • 后部:损失是集中在网络后面的,所以往往后面的层训练较快
    那有没有一种方式,使网络后面的层尽量保持不变呢?

批量归一化

定义

通过固定小批量数据的均值和方差,再引入可学习参数 γ 和 β 对数据进行调整,有助于加速模型的训练收敛,提高模型的稳定性 。
计算小批量均值和方差的公式:

μB=1BiBxi and σB2=1BiB(xiμB)2+ϵ\mu_B = \frac{1}{|B|} \sum_{i\in B} x_i \text{ and } \sigma_B^2 = \frac{1}{|B|} \sum_{i\in B} (x_i - \mu_B)^2 + \epsilon

然后对其做额外的调整:

xi+1=γxiμBσB+βx_{i + 1} = \gamma \frac{x_i - \mu_B}{\sigma_B} + \beta

不再学习均值和方差,转而学习参数 γ 和 β

作用位置

  • 作用在
    • 全连接层和卷积层输出上,激活函数前
    • 全连接层和卷积层输入上
  • 对全连接层,作用在特征维
  • 对于卷积层,作用在通道维

实现

1
2
3
4
5
6
7
net = nn.Sequential(nn.Conv2d(1, 6, kernel_size=5), nn.BatchNorm2d(6),
nn.Sigmoid(), nn.MaxPool2d(kernel_size=2, stride=2),
nn.Conv2d(6, 16, kernel_size=5), nn.BatchNorm2d(16),
nn.Sigmoid(), nn.MaxPool2d(kernel_size=2, stride=2),
nn.Flatten(), nn.Linear(256, 120), nn.BatchNorm1d(120),
nn.Sigmoid(), nn.Linear(120, 84), nn.BatchNorm1d(84),
nn.Sigmoid(), nn.Linear(84, 10))

拉伸参数 gamma 和偏移参数 beta

1
net[1].gamma.reshape((-1,)), net[1].beta.reshape((-1,))

(tensor([2.1534, 2.1612, 2.0096, 1.9473, 1.8451, 1.3328], device=‘cuda:0’,
grad_fn=),
tensor([ 0.0310, -2.4748, 0.5816, 0.5764, -1.6917, -0.6970], device=‘cuda:0’,
grad_fn=))
输入图片说明

总结

  • 批量归一化固定小批量中的均值和方差,然后学习出适合的偏移和缩放
  • 可以加速收敛速度,但一般不改变模型精度