《动手学深度学习Pytorch版》之批量归一化
对深层神经⽹络来说,即使输⼊数据已做标准化,训练中模型参数的更新依然很容易造成靠近输出层输出的剧烈变化。
在模型训练时,批量归⼀化利⽤⼩批量上的均值和标准差,不断调整神经⽹络中间输出,从⽽使整个神经⽹络在各层的中间输出的数值更稳定。
一、预备知识
1、分为三类
- 对全连接层做批量归一化
- 数据输入(二维):(batch_size,n_feature)
- 数据输出(二维):(batch_size,n_feature)
- 计算均值和方差
mean = X.mean(dim=0) #dim=0,按列求平均值,输出为
var = ((X - mean) ** 2).mean(dim=0) #**2表示按元素平方
举例
batch_size = 10
torch.manual_seed(0)
X_fc = torch.rand(batch_size,256)
print(X_fc.size())
mean = X_fc.mean(dim=0)
print(mean.size())
print((X_fc-mean).size())
print(((X_fc-mean)**2).size()) #**2表示按元素平方
print(((X_fc-mean)**2).mean(dim=0).size())
输出
torch.Size([10, 256])
torch.Size([256])
torch.Size([10, 256])
torch.Size([10, 256])
torch.Size([256])
- 对卷积层做批量归一化(见图解)
- 数据输入(四维):(batch_size,n_channel,p,q)
- 数据输出(四维):(batch_size,n_channel,p,q)
- 计算均值和方差
# 使用二维卷积层的情况,计算通道维上(axis=1)的均值和方差。这里我们需要保持
# X的形状以便后面可以做广播运算
mean = X.mean(dim=0, keepdim=True).mean(dim=2, keepdim=True).mean(dim=3, keepdim=True)
var = ((X - mean) ** 2).mean(dim=0, keepdim=True).mean(dim=2, keepdim=True).mean(dim=3, keepdim=True)
举例
结合后面的批量归一化图解理解
batch_size = 2
n_channel = 2
p = 2
q = 2
torch.manual_seed(0)
X_cov = torch.rand(batch_size,n_channel,p,q)
print(X_cov.size())
if len(X_cov.shape) in (2, 4):
print("True")
#dim=0,按批量维求平均值
print(X_cov.mean(dim=0, keepdim=True).size())
#dim=2,按特征高维求平均值
print(X_cov.mean(dim=0, keepdim=True).mean(dim=2, keepdim=True).size())
#dim=3,按特征宽维求平均值
print(X_cov.mean(dim=0, keepdim=True).mean(dim=2, keepdim=True).mean(dim=3, keepdim=True).size())
输出
torch.Size([2, 2, 2, 2])
True
torch.Size([1, 2, 2, 2])
torch.Size([1, 2, 1, 2])
torch.Size([1, 2, 1, 1])
- 预测时的批量归一化
2、均值方差计算公式
均值方差计算:
参考:https://blog.csdn.net/Apikaqiu/article/details/104379960
mean()函数的参数:dim=0,按列求平均值,返回的形状是(1,列数);dim=1,按行求平均值,返回的形状是(行数,1),默认不设置dim的时候,返回的是所有元素的平均值。
#输入x,这里的行数理解为批量数batch_size,列数理解为特征数n_feature
x:
tensor([[ 0., 1., 2.],
[ 3., 4., 5.],
[ 6., 7., 8.],
[ 9., 10., 11.]])
#dim=0,按列求平均值
x_mean0:
tensor([[4.5000, 5.5000, 6.5000]])
#dim=1,按行求平均值
x_mean1:
tensor([[ 1.],
[ 4.],
[ 7.],
[10.]])
#默认不设置dim的时候,返回的是所有元素的平均值
x_mean:
tensor(5.5000)
3、批量归一化方差均值计算
二、批量归一化图解
假设某一批次的数据为2个2行2列2深度的张量(2,2,2,2),BN的过程如下:
相当于:(batch_size=2,n_channel=2,p=2,q=2)
第一步:计算每一层深度(即通道数)的均值和方差(输出最终维数为[1, 2, 1, 1])
第二步:对每一层设置2个参数,γ和β。假设第1深度γ=2、β=3;第2深度γ=5、β=8。
计算公式: