写在前面:此文只记录了下本人感觉需要注意的地方,不全且不一定准确。详细内容可以参考文中帖的链接,比较好!!!
Batch Normalization问题总结
- 为什么要加BN:
1)通常送入网络的每一个batch的数据,它们的分布都不同,分布的差异会加大网络训练的难度【送入网络的数据分布相同】;
2)深层的神经网络随着网络的加深,其数据分布会逐渐发生偏移(x = W * U + B,网络层数深,会有很多个W,导致向一个趋势偏)。一般是整体分布逐渐往非线性函数的取值区间的上下限两端靠近(对于relu函数来说,意味着激活输入值WU+B是大的正值或0),导致预测结果偏差很大。
- BN的公式、代码实现:
def BatchNorm1d(x, gamma, beta, bn_param):
"""
BN实现
:param x:
:param gamma: 缩放尺寸
:param beta: 平移变量
:param bn_param: 所存储的以前数据的均值和方差
:return: BN后的值,加上x后的均值和方差
"""
#x.shape(B,C,H,W)
mean = bn_param['mean']
var = bn_param['var']
eps = 1e-5
x_mean = np.mean(x, dim =(0,2,3), keepdims=True) #BN对通道不求
x_var = np.var(x, dim = (0,2,3), keepdims=True)
x = (x-x_mean) / np.sqrt(v_ar + eps)
result = gamma * x + beta
#更新均值与方差
bn_param['mean'] = mean *momentum + x_mean *(1-momentum)
bn_param['var'] = var * momentum + x_var * (1 - momentum)
return result
##注:这里网络可学习的参数是gamma和beta
- BN公式中gamma和beta的意义:
拿sigmoid激活函数来说,如果只做标准化,那数据会落入激活函数的非线性部分,意味着深层的线性变化没有意义了(因为多层线性网络和一层线性网络是等价的)。为了保证非线性功能的使用,对变换后的满足均值为0方差为1的x又进行了scale加上shift操作(y=scale*x+shift),每个神经元增加了两个参数scale和shift参数,这两个参数是通过训练学习到的,意思是通过scale和shift把这个值从标准正态分布左移或者右移一点并长胖一点或者变瘦一点,每个实例挪动的程度不一样,这样等价于非线性函数的值从正中心周围的线性区往非线性区动了动。核心思想是想找到一个线性和非线性的较好平衡点,既能享受非线性的较强表达能力的好处,又避免太靠非线性区两头使得网络收敛速度太慢。
- BN的优缺点:
- 优点:
1)每个batch的数据同分布,使得模型学习更容易,使得训练更快; 2)权重初始化更容易;
3)可以支持更多的激活函数(sigmoid的梯度消失、relu的神经元死亡);
4)在某些情况下增加了一些网络的噪声,起到了和dropout一样的正则化效果,可能得到更好的结果
【在什么方面增加噪声呢?计算BN的均值和方差时有moment,导致每个BN的均值和方差都在波动,从而加入了噪声】
- 缺点:
1)比较依赖当前batch的数据,如果batch size 较小,不足以代表整个数据集分布,效果提升不大;
2)每个batch数据都会计算均值和方差,对于CNN友好,但是对于文本,不定长的计算时就比较麻烦
- BN的参数量:
gama * beta * 通道数【是按channel计算均值方差的】
其他Normalization介绍
参考:BatchNormalization、LayerNormalization、InstanceNorm、GroupNorm、SwitchableNorm总结
- 归一化层,目前主要有这几个方法,Batch Normalization(2015年)、Layer Normalization(2016年)、Instance Normalization(2017年)、Group Normalization(2018年)、Switchable Normalization(2018年);
- 下图是几种归一化方式的对比。图中的立方体是三维,其中两维C和N分别表示channel和batch size,第三维表示H,W,可以理解为该维度大小是H*W,也就是拉长成一维,这样总体就可以用三维图形来表示(蓝色区域为计算均值和方差的单元)。可以看出BN的计算和batch size相关,而LN、BN和GN的计算和batch size无关。同时LN和IN都可以看作是GN的特殊情况(LN是group=1时候的GN,IN是group=C时候的GN)。
- batchNorm是在batch上,对NHW做归一化,对小batchsize效果不好;
layerNorm在通道方向上,对CHW归一化,主要对RNN作用明显;
instanceNorm在图像像素上,对HW做归一化,用在风格化迁移;
GroupNorm将channel分组,然后再做归一化;
SwitchableNorm是将BN、LN、IN结合,赋予权重,让网络自己去学习归一化层应该使用什么方法。
Group Normalization
- GN是针对BN的batch size较小时提出的改进方法,其基本思想并不复杂,针对每一个feature map,将其channels 分成 k 组(k为超参,一般取32),计算每组内部的均值和方差,其他与BN类似。引用原文的一句话:GN divides the channels into groups and computes within each group the mean and variance for normalization. GN’s computation is independent of batch sizes, and its accuracy is stable in a wide range of batch sizes.
- 伪代码:
- 总结
- 具有BN的优点的同时(也能防止过拟合?),解决了batch size问题。