Normalization的基本思想
首页 专栏 神经网络 文章详情
0

Normalization的基本思想

anie 发布于 3 月 14 日

简述

Normalization的基本思想其实相当直观:因为深层神经网络在做非线性变换前的激活输入值(就是那个x=WU+B,U是输入)随着网络深度加深或者在训练过程中,其分布逐渐发生偏移或者变动,之所以训练收敛慢,一般是整体分布逐渐往非线性函数的取值区间的上下限两端靠近(对于Sigmoid函数来说,意味着激活输入值WU+B是大的负值或正值),所以这导致反向传播时低层神经网络的梯度消失,这是训练深层神经网络收敛越来越慢的本质原因,而Normalization就是通过一定的规范化手段,把每层神经网络任意神经元这个输入值的分布强行拉回到均值为0方差为1的标准正态分布,其实就是把越来越偏的分布强制拉回比较标准的分布,这样使得激活输入值落在非线性函数对输入比较敏感的区域,这样输入的小变化就会导致损失函数较大的变化,意思是这样让梯度变大,避免梯度消失问题产生,而且梯度变大意味着学习收敛速度快,能大大加快训练速度

简单来说:对于每个隐层神经元,把逐渐向非线性函数映射后向取值区间极限饱和区靠拢的输入分布强制拉回到均值为0方差为1的比较标准的正态分布,使得非线性变换函数的输入值落入对输入比较敏感的区域,以此避免梯度消失问题。因为梯度一直都能保持比较大的状态,所以很明显对神经网络的参数调整效率比较高,就是变动大,就是说向损失函数最优值迈动的步子大,也就是说收敛地快。

BatchNormalization

import numpy as np def 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...

神经网络
阅读 91 更新于 3 月 14 日
收藏
分享
本作品系原创, 采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议
avatar
anie
声望
0 粉丝
关注作者
0 条评论
得票数 最新
提交评论
你知道吗?

注册登录
avatar
anie
声望
0 粉丝
关注作者
宣传栏
目录

简述

Normalization的基本思想其实相当直观:因为深层神经网络在做非线性变换前的激活输入值(就是那个x=WU+B,U是输入)随着网络深度加深或者在训练过程中,其分布逐渐发生偏移或者变动,之所以训练收敛慢,一般是整体分布逐渐往非线性函数的取值区间的上下限两端靠近(对于Sigmoid函数来说,意味着激活输入值WU+B是大的负值或正值),所以这导致反向传播时低层神经网络的梯度消失,这是训练深层神经网络收敛越来越慢的本质原因,而Normalization就是通过一定的规范化手段,把每层神经网络任意神经元这个输入值的分布强行拉回到均值为0方差为1的标准正态分布,其实就是把越来越偏的分布强制拉回比较标准的分布,这样使得激活输入值落在非线性函数对输入比较敏感的区域,这样输入的小变化就会导致损失函数较大的变化,意思是这样让梯度变大,避免梯度消失问题产生,而且梯度变大意味着学习收敛速度快,能大大加快训练速度

简单来说:对于每个隐层神经元,把逐渐向非线性函数映射后向取值区间极限饱和区靠拢的输入分布强制拉回到均值为0方差为1的比较标准的正态分布,使得非线性变换函数的输入值落入对输入比较敏感的区域,以此避免梯度消失问题。因为梯度一直都能保持比较大的状态,所以很明显对神经网络的参数调整效率比较高,就是变动大,就是说向损失函数最优值迈动的步子大,也就是说收敛地快。

BatchNormalization

import numpy as np def 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...