BatchNormallization
是神经网络中的一个正则化技术,可以加速网络的收敛,并且在一定程度上解决深度网络“梯度弥散”的问题。它本是数据预处理的一种方法,google
的研究人员将它应用在了神经网络中。论文地址
详解
在这里,只探究其具体运算过程,我们假设在网络中间经过某些卷积操作之后的输出的feature map
的尺寸为4×3×2×2
4为batch
的大小,3为channel
的数目,2×2为feature map
的长宽
整个BN
层的运算过程如下图:
上图中,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)
输出值:
咦,怎么不一样,貌似差了一个小数点,可能与BN
层的momentum
变量有关系,在生命batch normalization
层的时候将momentum
设置为1试一试。
m.momentum=1
输出结果: