Batch Normalization、Layer Normalization 的总结与实现
一、前言
共同点:两者都属于归一化的方法,用在不同的场景下。Batch Normalization 从公式上来看是对不同样本张量在同一个维度(通道)进行归一化,能够降低不同样本之间的差异性。Layer Normalization 是对同一个样本里面不同的通道做归一化,降低了样本间特征的差异性。
关于贝塞尔校正,就是求方差的时候,是把累积的平方差值被 n 除还是被 n -1 除。使用了贝塞尔校正就是被 n - 1 除。
二、Batch Normalization(BN)
1. 简介
BN 一般在卷积层使用。
物理意义:让每张图片的相同通道的所有像素值使用相同的的均值和方差做归一化。
作用:
- 使得数据分布一致。使得每一层的输入都近似标准正态分布,缓解了内部协变量偏移问题。
- 避免梯度爆炸、梯度消失。
- 具有一定的正则化效果,可以防止过拟合。
- 降低模型对网络参数的影响,使网络学习更稳定,降低参数初始化对模型训练的影响(因此可以选择较大的初始学习率)。
公式:
y
=
x
−
m
e
a
n
(
X
)
(
v
a
r
(
X
)
+
e
p
s
)
∗
γ
+
β
y = \frac{x - mean(X)}{\sqrt(var(X) + eps)} * \gamma+ \beta
y=(var(X)+eps)x−mean(X)∗γ+β
ps:假设输入为 [N, C, H, W],要计算的 x 处于第 i(i < C)个通道上,则
m
e
a
n
(
X
)
mean(X)
mean(X) 是指将 N 个数据的第 i 个通道的所有像素值求均值,即一共要对 N * H * W 个数据求均值,
γ
\gamma
γ 和
β
\beta
β 的维度均为 [1, C, 1, 1],以对应 C 个通道。
2. 实现
关于是否使用贝塞尔校正:
numpy.std() :无法设置是否使用贝塞尔校正,公式中未使用贝塞尔校正。
torch.std():unbiased 为 True 时使用贝塞尔校正,默认为 True。
torch 调用:
# 唯一需要输入的参数 num_features 是指输入的通道数 C
# torch 中 BatchNorm2d 的实现未使用贝塞尔校正
# affine 指定仿射参数(即公式中的 γ 和 β)是否可学习,若不可学习,γ 为 1,β 为 0
torch.nn.BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True)
# 调用 API
inputx = torch.randn(3, 3, 3, 3)
batch_norm_op = nn.BatchNorm2d(num_features=3)
bn_y = batch_norm_op(inputx)
# 手动实现
eps = 1e-5
mean = torch.mean(inputx, axis=(0, 2, 3), keepdims=True)
std = torch.std(inputx, axis=(0, 2, 3), keepdims=True,unbiased=False)
verify_bn_y = (inputx - mean) / torch.sqrt(std ** 2 + eps)
# x:[N, C, H, W]
y = torch.mean(x, axis=(1))
# y 形状为 [N, H, W],y[n0, h0, w0] = x[n0, :, h0, w0] 的所有元素求均值,即可以理解为按指定的轴取值然后求均值,axis 指定多个轴也是同理
二、Layer Normalization(LN)
1. 简介
作用与 BN 相同。
公式:
y
=
x
−
m
e
a
n
(
X
)
(
v
a
r
(
X
)
+
e
p
s
)
∗
γ
+
β
y = \frac{x - mean(X)}{\sqrt(var(X) + eps)} * \gamma+ \beta
y=(var(X)+eps)x−mean(X)∗γ+β
ps:假设输入为 [N, C, H, W],
m
e
a
n
(
X
)
mean(X)
mean(X) 和
v
a
r
(
X
)
var(X)
var(X) 分别计算指定通道上的均值和方差,且指定通道只能是最后一个或几个。在 CV 中,Layer Normalization 一般指定最后三个通道,即 [C, H, W] 这三个通道,此时,
y
y
y 的形状为 [N],
m
e
a
n
(
X
)
mean(X)
mean(X) 一共需要对 C * H * W 个数据求均值,
v
a
r
(
X
)
var(X)
var(X) 同理。
γ
\gamma
γ 和
β
\beta
β 的形状和指定通道相同,CV 中为 [C, H, W]。
2. 实现
torch 调用:
# 唯一需要输入的参数 normalized_shape 指定通道
# 未采用贝塞尔校正
# elementwise_affine 指定仿射参数(即公式中的 γ 和 β)是否可学习,若不可学习,γ 为 1,β 为 0
torch.nn.LayerNorm(normalized_shape, eps=1e-05, elementwise_affine=True)
# 调用 API
inputx = torch.randn(2, 4, 3, 4)
layer_norm = nn.LayerNorm([4, 3, 4])
ln_y = layer_norm(inputx)
# 手动实现
eps = 1e-5
mean = torch.mean(inputx, axis=(1, 2, 3), keepdims=True)
std = torch.std(inputx, axis=(1, 2, 3), keepdims=True,unbiased=False)
verify_ln_y = (inputx - mean) / torch.sqrt(std ** 2 + eps)
三、其它
另外两种归一化方法,和以上两种方法类似,可以类比。
1. Group Normalization(GN)
顾图思意:
2. Instance Normalization(IN)
顾图思意: