Batch Normalization: Accelerating Deep Network Training b y Reducing Internal Covariate Shift

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dreamer_on_air/article/details/78075908

挖个坟,最近才看了batch normalize的原始paper,是Christian Szegedy(googlenet作者)的工作,已经在实际工作里用的很多了,再看这个paper还是能感受到作者很深厚的理论基础以及实现能力。

Motivation:

深度学习刚出来的时候我们就会遇到这样的问题,如果学习率比较大那么训练会不收敛或者直接nan飞掉,而且初始化参数的分布也十分重要,设置的不好就会导致没法收敛。从数学上分析这个问题的原因在于每个layer的输入和输出的分布是比较随机的,也就是所谓的有internal covariate shift,一个模型要去拟合一个不标准化的分布要比去拟合一个0均值1方差的分布要来的困难(高斯分布貌似是更容易被拟合的)。所以有些传统的方式来解决输入输出的分布问题,比如data augment的时候会做白化,变成一个0均值1方差的分布,或者用LRN(local response normalization)来对不同channel的feature map做normalize。但是白化一般仅对输入原始图像做处理,并不能保证每个feature map的分布,并且计算量比较大不保证可导;LRN已经很早就没什么人用,从原理上来说相邻feature map的对应位置去做normalize也不太合理。因此我们需要一种方法能够对每个feature map都用单独的一组参数做normalize。

具体做法:

变成0均值1方差是比较简单的,公式如下:就是对所有样本的x减均值再除以标准差

但是这样做之后,改变原有输入feature的分布会使得在经过激活函数后得不到我们想要的结果,比如在sigmoid之前的输入如果被限制在【-1,1】之间那么基本就处于先行区了,非线性就消失了。所以作者认为应该有参数可以使得BN去学习得到原始的输入:当r和b分别是标准差和均值的时候BN的输出就和原始的一样了,至于会不会变成和原始的一样,这件事情就让网络自己去学习

那么在加入这样的layer之后,该层做FP的算法如下。这里面做了个近似,用minibatch的均值和方差代替所有样本的均值和方差,因为后者在实际训练时是没有办法高效计算出来的。

BP的公式推导如下:

整个训练和预测过程如下:其中全局的方差使用了无偏估计m/m-1,具体的解释参考https://www.zhihu.com/question/38185998。对于cnn中的卷积层,normalize的范围是所有样本的每个feature map,输入个数为m'=m*w*h,其中m是minibatch的样本个数,w、h是feature map的size。但是r和b是针对每个feature map的。

为什么BN会有效?

前面解释了直观意义上bn让每个层的输出符合0均值1方差的分布,这样对拟合是比较容易,那么数学上的原因是什么呢?本质上是因为BN解决了原本的梯度传播依赖网络参数w的scale(或者理解为模)的问题。原本的gradient计算时公式里有个Wi的乘项,,这就会使得w的大小会导致梯度消失或者梯度爆炸。那么加入了BN之后,对于任意scale=a的一个W,因为做了normalize,所以BN(Wu) = BN((aW)u)。那么对于输入和W的求导如下:,可以看到对BP的计算a没有起到作用,对于w的gradient,a越大gradient越小,这样也比较好的保持w在一个稳定的范围之内。

实验结果:

实验就不详细说了,总之就是又快又好,一般把BN加在neuron前面,这里还有个小trick是可以把BN的参数提前算好直接放到前面的conv层(都是固定的值数学上等价),这样可以节省BN层计算的时间。

没有更多推荐了,返回首页