卷积神经网络之BN层

BN层,即所谓的Batch Normalization,现已经成为神经网络种的标配,它有什么样的魅力以致人们对它如此青睐呢?就让我们一起来看看BN的前因后世吧。欢迎大家一起交流~~~

提出的背景:

随机梯度下降法训练网络的缺点:

1、需要人为的去选择合适的参数,比如学习率、参数初始化、权重衰减系数、Dropout等

2、网络在训练时,存在梯度消失和梯度爆炸的问题:

梯度消失:以sigmoid函数为例

卷积神经网络之BN层

卷积神经网络之BN层

sigmoid激活函数使得输出值在[0,1]之间,如果输入很大,其对应的斜率就很小;而梯度(斜率)在反向传播中时权值学习速率,所以在深度网络中,如果网络激活输出很大,其梯度就很小,学习速率就很慢。假设每层的梯度都小于最大值0.25,网络由n层,因为链式求导的原因,第一层的梯度小于0.25的n次方,所以学习速率很小,对应最后一层只需要对自身求导一次,梯度就大,学习速率就快。这就导致浅层基本不学习,后面几层一直在学习,失去了深层的意义。

梯度爆炸:

第一层偏移量的梯度=激活层斜率1*权值1*激活层斜率2*...激活层斜率(n-1)*权值(n-1)*激活层斜率n;假设激活层的斜率均为最大值0.25,所有层的权值为100,这样梯度就会指数增加。

Why为什么在神经网络训练开始之前,都要对输入数据做一个归一化处理:

神经网络的本质就是学习数据的分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也就大大降低;另外一个方面,一旦每批训练数据的分布各不相同(batch的梯度不同),那么网络每次迭代都要去学习适应不同的分布,这样会大大降低网络徐熙的训练速度;而归一化可以使得训练数据和测试数据的分布趋于相同。

对于深度网络的训练是一个复杂的过程,只要网络的前面几层发生微小的改变,那么后面几层就会被累积放大下去。一旦网络某一层的输入数据的分布发生改变,那么这一层网络就需要去适应学习这个新的数据分布,所以如果训练过程中,训练数据的分布一直在发生变化,那么将会影响网络的训练速度。

网络中间层在训练过程中,数据分布的改变称之为“Internal Covariate Shift”。Paper所提出的算法,就是要解决在训练过程中,中间层数据分布发生改变的情况,于是就有了Batch Normalization,这个算法的诞生。

BN层的优势:

1、网络学习的收敛速度大幅上升,可以选择比较大的初始学习率

2、BN层可以提高网络的泛化能力,采用BN算法后,可以在网络中去除过拟合中的dropout层和L2的正则化参数的选择问题

3、不需要再使用局部响应归一化层(AlexNet所提出的)

BN概述:

BN(Batch Normalization)也属于网络的一层, 算法本质原理:在网络的每一层输入的时候,又插入了一个归一化层,也就是先做一个归一化处理,然后再进入网络的下一层。不过文献归一化层,可不像我们想象的那么简单,它是一个可学习、有参数的网络层。

常见的归一化处理:白化

卷积神经网络之BN层

如果是仅仅使用上面的归一化公式,对网络某一层A的输出数据做归一化,然后送入网络下一层B,这样会影响到本层网络A所学习到的特征的。比如网络中间某一层学习到特征数据,本身就分布在S型激活函数的两侧,你强制把它归一化处理、标准差也限制在了1,等同于把数据变换成分布于s函数的中间部分;这相当于该层网络所学习到的特征分布被你搞坏了,这可怎么办?于是文献使出了一招惊天地泣鬼神的招式:

变换重构,引入了可学习参数γ、β,这就是算法关键之处:

卷积神经网络之BN层

每一个神经元xk都会有一对这样的参数γ、β。 这样其实当:

卷积神经网络之BN层

我们是可以恢复出原始的某一层所学到的特征的。因此引入了这个可学习重构参数γ、β,让网络可以学习恢复出原始网络所要学习的特征分布。最后Batch Normalization网络层的前向传导过程公式就是:

卷积神经网络之BN层

BN层源码的实现:

卷积神经网络之BN层

实际使用:

1、一个网络一旦训练结束,就没有了min-batch这个概念了。测试阶段一般只输入一个测试样本。因此测试样本,前向传导的时候,上面的均值u、标准差σ,哪里来?其实网络一旦训练完毕,参数都是固定的,这个时候即使是每批训练样本进入网络,那么BN层计算的均值u、和标准差都是固定不变的。我们可以采用这些数值来作为测试样本所需要的均值、标准差,于是最后测试阶段的u和σ计算公式如下:

卷积神经网络之BN层

对于均值来说直接计算所有batch u值的平均值;然后对于标准偏差采用每个batch,σB的无偏估计。最后测试阶段,BN的使用公式就是:

卷积神经网络之BN层

2、BN可以应用于一个神经网络的任何神经元上。文献主要是把BN变换,置于网络激活函数层的前面。在没有采用BN的时候,激活函数层是这样的:

z=g(Wu+b)

也就是我们希望一个激活函数,比如s型函数s(x)的自变量x是经过BN处理后的结果。因此前向传导的计算公式就应该是:

z=g(BN(Wu+b))

其实因为偏置参数b经过BN层后其实是没有用的,最后也会被均值归一化,当然BN层后面还有个β参数作为偏置项,所以b这个参数就可以不用了。因此最后把BN层+激活函数层就变成了:

z=g(BN(Wu))

Batch Normalization在CNN中的使用:

BN层是对于每个神经元做归一化处理,而不是对一整层网络的神经元进行归一化。既然BN是对单个神经元的运算,那么在CNN中卷积层上要怎么运算?假如某一层卷积层有6个特征图,每个特征图的大小是100*100,这样就相当于这一层网络有6*100*100个神经元,如果采用BN,就会有6*100*100个参数γ、β。因此卷积层上的BN使用,其实也是使用了类似权值共享的策略,把一整张特征图当做一个神经元进行处理。

卷积神经网络经过卷积后得到的是一系列的特征图,如果网络某一层输入数据可以表示为四维矩阵(m,f,p,q),m为min-batch sizes,f为特征图个数,p、q分别为特征图的宽高。在cnn中,可以把每个特征图看成是一个特征处理(一个神经元),因此在使用Batch Normalization,mini-batch size 的大小就是:m*p*q,于是对于每个特征图都只有一对可学习参数:γ、β。这就是相当于求所有样本所对应的一个特征图的所有神经元的平均值、方差,然后对这个特征图神经元做归一化。

阅读paper的难点主要在两个:

1.为什么通过归一化,减少内部斜变量转移就可以减少梯度消失,加快收敛速度呢?

大神们发现内部斜变量转移(也就是激活值随着参数的变化分布发生变化)会使得输出层的分布趋近激活函数的非线性饱和区域,如sigmoid函数的两端,这样会使得梯度趋于0,从而无法训练网络,LeCun在文章Gradient based learning applied to document recognition中提出过如果输入数据白化可加速网络训练。于是BN的提出者就想出能不能将每一层的激活值归一化,将他们拉回到均值为0,方差为1的分布区域,这样大部分数据都从梯度趋近于0的区域变换至激活函数中梯度较大的区域,从而加快收敛速度。

2.归一化后又引入了两个新的参数 gamma与beta,而这两个参数最极端的情况是把分布拉回到原分布,这是为啥?

这是因为归一化后会影响原始网络输出层的表达能力,因此引入两个参数进行调整,而这两个参数是网络自己学习的,因为在归一化后大部分数据都集中分布在激活函数中间的线性区域,但对于深层网络来说多层线性激活等价于一层没有意义,因此需要在非线性和梯度较大这两个点之间做个权衡,人为设定可能不合适,因此由网络自行学习去衡量激活值的位置。


分享到:


相關文章: