BN(Batch Normalization)总结--Accelerating Deep Network Training by Reducing Internal Covariate Shift

来源:互联网 发布:js插件和组件的区别 编辑:程序博客网 时间:2024/06/06 03:33

BN(batch normalization)总结

论文:《Batch Normalization: Accelerating Deep Network Training by ReducingInternal Covariate Shift》

小菜这里也是看了许多前辈的博客总结的,这里也感谢前辈的无私。。。。。

1.      概述

核心:

Ø  加入特殊归一化层BN层

此论文是Google在2015年基于之前的Googlenet提出又一篇非常好的论文,论文提出的算法使得网络的train过程得到加速,而且在识别中的准确率有所提高能达到4.9%。此论文的网络架构使用了2014年Google网络的inception结构,加入了特殊的归一化层

这里介绍一个术语InternalCovariate Shift

由于在训练时某一层的参数的更新改变后,会导致该层网络的输出(下一层的输入)的分布是变化的,这样使得训练DNN很复杂。这使得我们必须使用较小的学习率及较好的权重初值,这样会导致训练很慢,同时也导致使用saturating nonlinearities 激活函数(如sigmoid,正负两边都会饱和)时训练很困难。这种现象我们称为“internal covariate shift”,解决这种问题我们normalizing网络层的输入。

大家应该都知道,我们一般在训练网络的时会将输入减去均值,还有些人甚至会对输入做白化等操作,目的是为了加快训练。为什么减均值、白化可以加快训练呢,这里做一个简单地说明:

首先,图像数据是高度相关的,假设其分布如下图a所示(简化为2维)。由于初始化的时候,我们的参数一般都是0均值的,因此开始的拟合y=Wx+b,基本过原点附近,如图b红色虚线。因此,网络需要经过多次学习才能逐步达到如紫色实线的拟合,即收敛的比较慢。如果我们对输入数据先作减均值操作,如图c,显然可以加快学习。更进一步的,我们对数据再进行去相关操作,使得数据更加容易区分,这样又会加快训练,如图d。 

图1 数据分析比较

白化的方式有好几种,常用的有PCA白化

即对数据进行PCA降维操作之后,在进行方差归一化。这样数据基本满足0均值、单位方差、弱相关性。如果考虑对每一层数据都使用白化操作,但分析认为这是不可取的。因为白化需要计算协方差矩阵、求逆等操作,计算量很大,此外,反向传播时,白化操作不一定处处可导

我们知道网络一旦train起来,那么参数就要发生更新,除了图像数据输入层的数据外(因为输入层数据,我们已经人为的为每个样本归一化),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练的时候,前面层训练参数的更新将导致后面层输入数据分布的变化。以网络第二层为例:网络的第二层输入,是由第一层的参数和input计算得到的,而第一层的参数在整个训练过程中一直在变化,因此必然会引起后面每一层输入数据分布的改变。我们把网络中间层在训练过程中,数据分布的改变就是前面提到的“Internal Covariate Shift”术语。Paper所提出的BN算法,就是要解决在训练过程中,中间层数据分布发生改变的情况,于是就有了Batch Normalization,这个牛逼算法的诞生。

2.      BN算法优点

1) 可以选择较大的初始学习率,从而加速了train速度,以前train过程还要调整学习率,现在有了较大的学习率,学习率的衰减速度也很大,因为BN算法收敛很快。

2) BN算法可以不用去考虑过拟合中dropoutL2正则项参数的选择问题,归一化后使得更多的权重分界面落在了数据中,降低了overfit的可能性,因此一些防止overfit但会降低速度的方法,例如dropout和权重衰减就可以不使用或者降低其权重。

3) 它让卡在饱和区域的概率降低,以便可以使用saturating nonlinearities激活函数了(如sigmoid函数)。

4) 也让梯度计算受参数及其初值影响的减小。

3.      BN算法描述

经过前面简单介绍,这个时候可能我们会想当然的以为:算法好像很简单的样子,不就是在网络中间层数据做一个归一化处理嘛,这么简单的想法,为什么之前没人用呢?然而其实实现起来并不是那么简单的。其实如果是仅仅使用上面的归一化公式,对网络某一层A的输出数据做归一化,然后送入网络下一层B,这样是会影响到本层网络A所学习到的特征的。打个比方,比如我网络中间某一层学习到特征数据本身就分布在S型激活函数的两侧,你强制把它给我归一化处理、标准差也限制在了1,把数据变换成分布于s函数的中间部分,这样就相当于我这一层网络所学习到的特征分布被你搞坏了,这可怎么办?于是文献使出了一招惊天地泣鬼神的招式:变换重构,引入了可学习参数γ、β,这就是算法关键之处:

其中有:

通过此操作是可以恢复出原始的某一层所学习的特征的。所以论文中引入了这个可学习的参数γ、β,让网络可以学习恢复出原始网络所要学习的特征分布。如图2所示就是BN的算法流程。

图2 算法流程图1

4.      后期训练和应用

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

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


其算法流程图如图3所示,暂时还有完全理解此算法的流程

图3 算法流程图2

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

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

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

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

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

 

1 0
原创粉丝点击