PyTorch - BatchNorm2d
flyfish
在《深入浅出PyTorch》这本书中翻译成归一化
在花书《深度学习》书中翻译成标准化
在《深度学习之美》书中翻译成规范化
在《动手学深度学习》书中翻译成归一化
在《深度学习卷积神经网络从入门到精通》书中翻译成归一化
归一化,因为带了一字,容易被理解成将数据映射到[0,1], 而标准化有把数据映射到一个合理的分布的意思,翻译的不统一,容易造成讨论的概念不一致,可以参考
特征缩放(Feature_scaling)
我这里采用了 标准化 的翻译
PyTorch提供了
torch.nn.BatchNorm1d
torch.nn.BatchNorm2d
torch.nn.BatchNorm3d
这里以BatchNorm2d为例说明它的计算过程是怎样的
import torch
import torch.nn as nn
input = torch.arange(0, 16).view(1,1,4,4).float()
# # tensor([[[[ 0., 1., 2., 3.],
# # [ 4., 5., 6., 7.],
# # [ 8., 9., 10., 11.],
# # [12., 13., 14., 15.]]]])
# With Learnable Parameters
m = nn.BatchNorm2d(1)
# Without Learnable Parameters
m = nn.BatchNorm2d(1, affine=False)
output = m(input)
print(output)
步骤
官网给的公式是
y = x − E [ x ] V a r [ x ] + ϵ ∗ γ + β y = \frac{x - \mathrm{E}[x]}{ \sqrt{\mathrm{Var}[x] + \epsilon}} * \gamma + \beta y=Var[x]+ϵx−E[x]∗γ+β
我们把公式分解
I n p u t : B = { x 1 , ⋯ , x m } \mathbf{Input}: \mathcal{B}=\{x_1,\cdots,x_m\} Input:B={x1,⋯,xm},为m个样本组成的mini-batch 。
第一步:计算mini-batch均值
μ B ← 1 m ∑ i = 1 m x i \mu_{\mathcal{B}} \leftarrow \frac{1}{m} \sum_{i=1}^m x_i μB←m1i=1∑mxi
第二步:计算mini-batch方差
σ B 2 ← 1 m ∑ i = 1 m ( x i − μ B ) 2 \sigma_{\mathcal{B}}^2 \leftarrow \frac{1}{m} \sum_{i=1}^m (x_i - \mu_{\mathcal{B}})^2 σB2←m1i=1∑m(xi−μB)2
第三步:标准化(normalize)
x ^ i ← x i − μ B σ B 2 + ϵ \hat{x}_i \leftarrow \dfrac{x_i-\mu_{\mathcal{B}}}{\sqrt{\sigma_{\mathcal{B}}^2+\epsilon}} x^i←σB2+ϵxi−μB
第四步:缩放和平移(scale and shift)
y i ← γ x ^ i + β ≡ B N γ , β ( x i ) y_i \leftarrow \gamma \hat{x}_i+\beta \equiv \mathrm{BN}_{\gamma, \beta}(x_i) yi←γx^i+β≡BNγ,β(xi)
因为上面是一个通道所以代码可以简写如下,这里是简写,后面的三个通道的例子是真正的计算过程,计算过程需要前三步
#第一步
first_mean= input.mean()#input的所有的数计算平均值 tensor(7.5000)
#第二步
second_variance=torch.pow(input-first_mean,exponent=2).mean()#tensor(21.2500)
#第三步
result=(input-first_mean)/(torch.sqrt(second_variance+1e-05))
输出结果都是
# tensor([[[[-1.6270, -1.4100, -1.1931, -0.9762],
# [-0.7593, -0.5423, -0.3254, -0.1085],
# [ 0.1085, 0.3254, 0.5423, 0.7593],
# [ 0.9762, 1.1931, 1.4100, 1.6270]]]])
import torch
import torch.nn as nn
input = torch.arange(0, 48).view(4,3,2,2).float()
# With Learnable Parameters
#m = nn.BatchNorm2d(3)
# Without Learnable Parameters
m = nn.BatchNorm2d(3, affine=False)
output = m(input)
print(output)
计算过程如下
去除维度 N,H,W,只留下C
import torch
input = torch.arange(0, 48).view(4,3,2,2).float()
eps=1e-5
mean = input.mean(dim=(0, 2, 3), keepdim=True)
var = torch.pow((input - mean) ,exponent= 2).mean(dim=(0, 2, 3), keepdim=True)
result = (input - mean) / torch.sqrt(var + eps)
print(result)
结果是两者输出结果相同
nn.BatchNorm2d(num_features)
应用批归一化即对小批量(mini-batch)数据组成的输入数据进行批标准化(Batch Normalization)操作,通过减少内部协变量偏移来加速深度网络训练。
1、num_features:
来自期望输入的特征数,该期望输入的大小为batch_size × num_features × height × width
输入输出相同)
输入Shape:(N, C, H, W)
输出Shape:(N, C, H, W)
2、eps: 为保证数值稳定性(分母不能趋近或取0),给分母加上的值。默认为1e-5。
3、momentum: 用于running_mean和running_var计算的值。 可以将累积移动平均线(cumulative moving average)(即简单平均线 simple average)设置为“无”。 默认值:0.1
3、affine: 一个布尔值,当设为true,给该层有可学习的仿射参数。
4、track_running_stats:一个布尔值,当设置为True时,此模块跟踪运行平均值和方差;设置为False时,此模块不跟踪此类统计信息,并且始终在训练和评估模式下使用批处理统计信息。 默认值:True