关于这个问题,其实很多同学都会有疑问,因为在论文中是一系列的公式展开,其实并不是很好理解。
关于BN
其实BN操作的目地是使一批feature map 进行归一化,避免数据过大而导致网络性能的不稳定。我记得网有一篇博文中对BN有较详细的介绍,大概意思就是,输入数据经过若干层的网络输出其实会让数据特征分布和初始分布不一致,降低模型的泛化性能,引入BN机制后,先将特征变为标准正态分布,然后再通过γ和β两个参数将标准正态分布适当拉回归一化前的分布,相当于在原分布和标准正态分布进行折中,以此增强模型的泛化性。
BN的运算过程
这里假设特征图的格式为 (N,C,H,W) 类型,这里假设为 (2,2,2,2)类型的,比如下图,上下为两个通道,横向为两个特征图,每个特征图为 2*2 ,经过 BN后,最终结果为 右半部份。具体计算公式为:
即最终计算的时候,是将特征图中,同一批次中,按照通道进行归一化,每个样本的不同通道间是没什么关系的,不同样本的相同通道是符合同一个正态分布的。
Pytorch中的nn模块中的BatchNormal2d函数的实验
import torch
import torch.nn as nn
#num_features - num_features from an expected input of size:batch_size*num_features*height*width
#eps:default:1e-5 (公式中为数值稳定性加到分母上的值)
#momentum:动量参数,用于running_mean and running_var计算的值,default:0.1
input=torch.randn(2, 2, 3, 4) # 生成一个三维矩阵,bitch_size=2, C=2, H=3, W=4
m=nn.BatchNorm2d(2, affine=True) # 2为输入的通道数,affine参数设为True表示weight和bias将被使用,即 gamma 和 Beta
output=m(input) # 批正则化变换
print(input)
print(m.weight) # gamma
print(m.bias) # Beta
print(output)
print(output.size())
使用计算公式计算
print(input[:,0])
firstChannelMean=torch.Tensor.mean(input[:,0])#求2个样本第一通道的平均值
firstCVar=torch.Tensor.var(input[:,0],False)#求2个样本第一个通道的方差
batchNor=((input[0][0][0][0]-firstChannelMean)/(torch.pow(firstCVar,0.5)+m.eps))*m.weight[0]+m.bias[0] #普通的公式
print(batchNor) # 输出该位置对应的BN结果