简述
Normalization的根本思维其实相当直观:因为深层神经网络在做非线性变换前的激活输出值(就是那个x=WU+B,U是输出)随着网络深度加深或者在训练过程中,其散布逐步产生偏移或者变动,之所以训练收敛慢,个别是整体散布逐步往非线性函数的取值区间的上上限两端凑近(对于Sigmoid函数来说,意味着激活输出值WU+B是大的负值或正值),所以这导致反向流传时低层神经网络的梯度隐没,这是训练深层神经网络收敛越来越慢的实质起因,而Normalization就是通过肯定的规范化伎俩,把每层神经网络任意神经元这个输出值的散布强行拉回到均值为0方差为1的规范正态分布,其实就是把越来越偏的散布强制拉回比拟规范的散布,这样使得激活输出值落在非线性函数对输出比拟敏感的区域,这样输出的小变动就会导致损失函数较大的变动,意思是这样让梯度变大,防止梯度隐没问题产生,而且梯度变大意味着学习收敛速度快,能大大放慢训练速度。
简略来说:对于每个隐层神经元,把逐步向非线性函数映射后向取值区间极限饱和区聚拢的输出散布强制拉回到均值为0方差为1的比拟规范的正态分布,使得非线性变换函数的输出值落入对输出比拟敏感的区域,以此防止梯度隐没问题。因为梯度始终都能放弃比拟大的状态,所以很显著对神经网络的参数调整效率比拟高,就是变动大,就是说向损失函数最优值迈动的步子大,也就是说收敛地快。
BatchNormalization
import numpy as npdef Batchnorm(x, gamma, beta, bn_param): # x_shape:[B, C, H, W] running_mean = bn_param['running_mean'] running_var = bn_param['running_var'] results = 0. eps = 1e-5 x_mean = np.mean(x, axis=(0, 2, 3), keepdims=True) #沿着通道计算每个batch的均值u x_var = np.var(x, axis=(0, 2, 3), keepdims=True) #沿着通道计算每个batch的方差^2 x_normalized = (x - x_mean) / np.sqrt(x_var + eps) #对x做归一化,x’=(x-u)/开根号(^2+) results = gamma * x_normalized + beta #退出缩放和平移变量和 ,归一化后的值,y=x’+ # 因为在测试时是单个图片测试,这里保留训练时的均值和方差,用在前面测试时用 running_mean = momentum * running_mean + (1 - momentum) * x_mean running_var = momentum * running_var + (1 - momentum) * x_var bn_param['running_mean'] = running_mean bn_param['running_var'] = running_var return results, bn_param
退出缩放平移变量的起因是:保障每一次数据通过归一化后还保留原有学习来的特色,同时又能实现归一化操作,减速训练。 这两个参数是用来学习的参数。
Layer Normalizaiton
BN与LN的区别在于:
- LN中同层神经元输出领有雷同的均值和方差,不同的输出样本有不同的均值和方差;
- BN中则针对不同神经元输出计算均值和方差,同一个batch中的输出领有雷同的均值和方差。
所以,LN不依赖于batch的大小和输出sequence的深度,因而能够用于batchsize为1和RNN中对边长的输出sequence的normalize操作。LN用于RNN成果比拟显著,然而在CNN上,不如BN。
def ln(x, b, s): _eps = 1e-5 output = (x - x.mean(1)[:,None]) / tensor.sqrt((x.var(1)[:,None] + _eps)) output = s[None, :] * output + b[None,:] return output
Instance Normalization
BN重视对每个batch进行归一化,保障数据分布统一,因为判断模型中后果取决于数据整体散布。
然而图像风格化中,生成后果次要依赖于某个图像实例,所以对整个batch归一化不适宜图像风格化中,因此对HW做归一化。能够减速模型收敛,并且放弃每个图像实例之间的独立。Instance Normalization在图像格调迁徙畛域体现优良。
def Instancenorm(x, gamma, beta): # x_shape:[B, C, H, W] results = 0. eps = 1e-5 x_mean = np.mean(x, axis=(2, 3), keepdims=True) x_var = np.var(x, axis=(2, 3), keepdims=True0) x_normalized = (x - x_mean) / np.sqrt(x_var + eps) results = gamma * x_normalized + beta return results
Group Normalization
次要是针对Batch Normalization对小batchsize成果差,GN将channel方向分group,而后每个group内做归一化,算(C//G)HW的均值,这样与batchsize无关,不受其束缚。
def GroupNorm(x, gamma, beta, G=16): # x_shape:[B, C, H, W] results = 0. eps = 1e-5 x = np.reshape(x, (x.shape[0], G, x.shape[1]/16, x.shape[2], x.shape[3])) x_mean = np.mean(x, axis=(2, 3, 4), keepdims=True) x_var = np.var(x, axis=(2, 3, 4), keepdims=True0) x_normalized = (x - x_mean) / np.sqrt(x_var + eps) results = gamma * x_normalized + beta return results
总结
归一化层,目前次要有这几个办法,Batch Normalization(2015年)、Layer Normalization(2016年)、Instance Normalization(2017年)、Group Normalization(2018年)、Switchable Normalization(2018年);
batchNorm是在batch上,对NHW做归一化,对小batchsize成果不好;
layerNorm在通道方向上,对CHW归一化,次要对RNN作用显著;
instanceNorm在图像像素上,对HW做归一化,用在风格化迁徙;
GroupNorm将channel分组,而后再做归一化;
参考文献
1、Batch Normalization[https://arxiv.org/pdf/1502.03...]
2、Layer Normalizaiton[https://arxiv.org/pdf/1607.06...]
3、Instance Normalization[https://arxiv.org/pdf/1607.08...]
4、Group Normalization[https://arxiv.org/pdf/1803.08...]
5、https://blog.csdn.net/liuxiao...