​BatchNormallization​​​是神经网络中的一个正则化技术,可以加速网络的收敛,并且在一定程度上解决深度网络“梯度弥散”的问题。它本是数据预处理的一种方法,​​google​​​的研究人员将它应用在了神经网络中。​​论文地址​

nn.BatchNormalization原理_神经网络

nn.BatchNormalization原理_神经网络_02

nn.BatchNormalization原理_.net_03

nn.BatchNormalization原理_神经网络_04

nn.BatchNormalization原理_神经网络_05

详解

在这里,只探究其具体运算过程,我们假设在网络中间经过某些卷积操作之后的输出的​​feature map​​​的尺寸为​​4×3×2×2​

4为​​batch​​​的大小,3为​​channel​​​的数目,2×2为​​feature map​​的长宽

整个​​BN​​层的运算过程如下图:

nn.BatchNormalization原理_.net_06

上图中,​​batch size​​​一共是4, 对于每一个​​batch​​​的​​feature map​​​的​​size​​是3×2×2

对于所有​​batch​​​中的同一个​​channel​​​的元素进行求均值与方差,比如上图,对于所有的​​batch​​​,都拿出来最后一个​​channel​​,一共有4×4=16个元素。

然后求区这16个元素的均值与方差,求取完了均值与方差之后,对于这16个元素中的每个元素进行减去求取得到的均值与方差,然后乘以​​gamma​​​加上​​beta​​,公式如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-80ZbesM8-1576137603204)(C:\Users\mi\AppData\Roaming\Typora\typora-user-images\image-20191212152234134.png)]

所以对于一个​​batch normalization​​​层而言,求取的均值与方差是对于所有​​batch​​​中的同一个​​channel​​​进行求取,​​batch normalization​​​中的​​batch​​体现在这个地方。

​batch normalization​​​层能够学习到的参数,对于一个特定的​​channel​​​而言实际上是两个参数,​​gamma​​​与​​beta​​​,对于​​total​​​的​​channel​​​而言实际上是​​channel​​数目的两倍。

用​​pytorch​​​验证上述想法是否准确,用上述方法求取均值,以及用​​batch normalization​​层输出的均值,看看是否一样?

# -*-coding:utf-8-*-
from torch import nn
import torch


m = nn.BatchNorm2d(3) # bn设置的参数实际上是channel的参数
input = torch.randn(4, 3, 2, 2) # 模拟feature map的尺寸
output = m(input)
# print(output)
a = (input[0, 0, :, :]+input[1, 0, :, :]+input[2, 0, :, :]+input[3, 0, :, :]).sum()/16
b = (input[0, 1, :, :]+input[1, 1, :, :]+input[2, 1, :, :]+input[3, 1, :, :]).sum()/16
c = (input[0, 2, :, :]+input[1, 2, :, :]+input[2, 2, :, :]+input[3, 2, :, :]).sum()/16
print(‘The mean value of the first channel is %f‘ % a.data)
print(‘The mean value of the first channel is %f‘ % b.data)
print(‘The mean value of the first channel is %f‘ % c.data)
print(‘The output mean value of the BN layer is %f, %f, %f‘ % (m.running_mean.data[0],m.running_mean.data[0],m.running_mean.data[0]))
print(m)

输出值:

nn.BatchNormalization原理_神经网络_07

咦,怎么不一样,貌似差了一个小数点,可能与​​BN​​​层的​​momentum​​​变量有关系,在生命​​batch normalization​​​层的时候将​​momentum​​设置为1试一试。

m.momentum=1

输出结果:

nn.BatchNormalization原理_.net_08

参考:

​​

​​

​​

​​