Batch Normalization详解

博客:blog.shinelee.me | 博客园 | CSDNgit

动机

在博文《为何要作特征归一化/标准化? 博客园 | csdn | blog》中,咱们介绍了对输入进行Standardization后,梯度降低算法更容易选择到合适的(较大的)学习率,降低过程会更加稳定。github

在博文《网络权重初始化方法总结(下):Lecun、Xavier与He Kaiming 博客园 | csdn | blog》中,咱们介绍了如何经过权重初始化让网络在训练之初保持激活层的输出(输入)为zero mean unit variance分布,以减轻梯度消失和梯度爆炸。算法

但在训练过程当中,权重在不断更新,致使激活层输出(输入)的分布会一直变化,可能没法一直保持zero mean unit variance分布,仍是有梯度消失和梯度爆炸的可能,直觉上感到,这多是个问题。下面具体分析。网络

单层视角

http://gradientscience.org/batchnorm/

神经网络能够当作是上图形式,对于中间的某一层,其前面的层能够当作是对输入的处理,后面的层能够当作是损失函数。一次反向传播过程会同时更新全部层的权重\(W_1, W_2, \dots, W_L\),前面层权重的更新会改变当前层输入的分布,而跟据反向传播的计算方式,咱们知道,对\(W_k\)的更新是在假定其输入不变的状况下进行的。若是假定第\(k\)层的输入节点只有2个,对第\(k\)层的某个输出节点而言,至关于一个线性模型\(y = w_1 x_1 + w_2 x_2 + b\),以下图所示,app

https://wiki2.org/en/Linear_classifier#/media/File:Svm_separating_hyperplanes.png

假定当前输入\(x_1\)\(x_2\)的分布如图中圆点所示,本次更新的方向是将直线\(H_1\)更新成\(H_2\),本觉得切分得不错,可是当前面层的权重更新完毕,当前层输入的分布换成了另一番样子,直线相对输入分布的位置可能变成了\(H_3\),下一次更新又要根据新的分布从新调整。直线调整了位置,输入分布又在发生变化,直线再调整位置,就像是直线和分布之间的“追逐游戏”。对于浅层模型,好比SVM,输入特征的分布是固定的,即便拆分红不一样的batch,每一个batch的统计特性也是相近的,所以只需调整直线位置来适应输入分布,显然要容易得多。而深层模型,每层输入的分布和权重在同时变化,训练相对困难。框架

多层视角

上面是从网络中单拿出一层分析,下面看一下多层的状况。在反向传播过程当中,每层权重的更新是在假定其余权重不变的状况下,向损失函数下降的方向调整本身。问题在于,在一次反向传播过程当中,全部的权重会同时更新,致使层间配合“缺少默契”,每层都在进行上节所说的“追逐游戏”,并且层数越多,相互配合越困难,文中把这个现象称之为 Internal Covariate Shift,示意图以下。为了不过于震荡,学习率不得不设置得足够小,足够小就意味着学习缓慢。机器学习

https://gab41.lab41.org/batch-normalization-what-the-hey-d480039a9e3b

为此,但愿对每层输入的分布有所控制,因而就有了Batch Normalization,其出发点是对每层的输入作Normalization,只有一个数据是谈不上Normalization的,因此是对一个batch的数据进行Normalization。ide

什么是Batch Normalization

Batch Normalization,简称BatchNorm或BN,翻译为“批归一化”,是神经网络中一种特殊的层,现在已经是各类流行网络的标配。在原paper中,BN被建议插入在(每一个)ReLU激活层前面,以下所示,函数

http://gradientscience.org/batchnorm/

若是batch size为\(m\),则在前向传播过程当中,网络中每一个节点都有\(m\)个输出,所谓的Batch Normalization,就是对该层每一个节点的这\(m\)个输出进行归一化再输出,具体计算方式以下,

Batch Normalization Transform

其操做能够分红2步,

  1. Standardization:首先对\(m\)\(x\)进行 Standardization,获得 zero mean unit variance的分布\(\hat{x}\)
  2. scale and shift:而后再对\(\hat{x}\)进行scale and shift,缩放并平移到新的分布\(y\),具备新的均值\(\beta\)方差\(\gamma\)

假设BN层有\(d\)个输入节点,则\(x\)可构成\(d \times m\)大小的矩阵\(X\),BN层至关于经过行操做将其映射为另外一个\(d\times m\)大小的矩阵\(Y\),以下所示,

Batch Normalization将2个过程写在一个公式里以下,
\[ y_i^{(b)} = BN\left(x_{i}\right)^{(b)}=\gamma \cdot\left(\frac{x_{i}^{(b)}-\mu\left(x_{i}\right)}{\sqrt{\sigma\left(x_{i}\right)^2 + \epsilon}}\right)+\beta \]
其中,\(x_i^{(b)}\)表示输入当前batch的\(b\)-th样本时该层\(i\)-th输入节点的值,\(x_i\)\([x_i^{(1)}, x_i^{(2)}, \dots, x_i^{(m)}]\)构成的行向量,长度为batch size \(m\)\(\mu\)\(\sigma\)为该行的均值和标准差,\(\epsilon\)为防止除零引入的极小量(可忽略),\(\gamma\)\(\beta\)为该行的scale和shift参数,可知

  • \(\mu\)\(\sigma\)为当前行的统计量,不可学习。
  • \(\gamma\)\(\beta\)为待学习的scale和shift参数,用于控制\(y_i\)的方差和均值。
  • BN层中,\(x_i\)\(x_j\)之间不存在信息交流\((i \neq j)\)

可见,不管\(x_i\)本来的均值和方差是多少,经过BatchNorm后其均值和方差分别变为待学习的\(\beta\)\(\gamma\)

Batch Normalization的反向传播

对于目前的神经网络计算框架,一个层要想加入到网络中,要保证其是可微的,便可以求梯度。BatchNorm的梯度该如何求取?

反向传播求梯度只需抓住一个关键点,若是一个变量对另外一个变量有影响,那么他们之间就存在偏导数,找到直接相关的变量,再配合链式法则,公式就很容易写出了。
\[ \begin{array}{l}{\frac{\partial \ell}{\partial \gamma}=\sum_{i=1}^{m} \frac{\partial \ell}{\partial y_{i}} \cdot \widehat{x}_{i}} \\ {\frac{\partial \ell}{\partial \beta}=\sum_{i=1}^{m} \frac{\partial \ell}{\partial y_{i}}} \\{\frac{\partial \ell}{\partial \widehat{x}_{i}}=\frac{\partial \ell}{\partial y_{i}} \cdot \gamma} \\ {\frac{\partial \ell}{\partial \sigma_{B}^{2}}=\sum_{i=1}^{m} \frac{\partial \ell}{\partial \widehat{x}_{i}} \cdot\left(x_{i}-\mu_{\mathcal{B}}\right) \cdot \frac{-1}{2}\left(\sigma_{\mathcal{B}}^{2}+\epsilon\right)^{-3 / 2}} \\ {\frac{\partial \ell}{\partial \mu_{\mathcal{B}}}=\left(\sum_{i=1}^{m} \frac{\partial \ell}{\partial \widehat{x}_{i}} \cdot \frac{-1}{\sqrt{\sigma_{\mathcal{B}}^{2}+\epsilon}}\right)+\frac{\partial \ell}{\partial \sigma_{\mathcal{B}}^{2}} \cdot \frac{\sum_{i=1}^{m}-2\left(x_{i}-\mu_{\mathcal{B}}\right)}{m}} \\ {\frac{\partial \ell}{\partial x_{i}} = \frac{\partial \ell}{\partial \widehat{x}_{i}} \cdot \frac{1}{\sqrt{\sigma_{\mathcal{B}}^{2}+\epsilon}} + \frac{\partial \ell}{\partial \sigma_{\mathcal{B}}^{2}} \cdot \frac{2\left(x_{i}-\mu_{\mathcal{B}}\right)}{m} + \frac{\partial \ell}{\partial \mu_{\mathcal{B}}} \cdot \frac{1}{m}} \\ \end{array} \]
根据反向传播的顺序,首先求取损失\(\ell\)对BN层输出\(y_i\)的偏导\(\frac{\partial \ell}{\partial y_{i}}\),而后是对可学习参数的偏导\(\frac{\partial \ell}{\partial \gamma}\)\(\frac{\partial \ell}{\partial \beta}\),用于对参数进行更新,想继续回传的话还须要求对输入 \(x\)偏导,因而引出对变量\(\mu\)\(\sigma^2\)\(\hat{x}\)的偏导,根据链式法则再求这些变量对\(x\)的偏导。

在实际实现时,一般以矩阵或向量运算方式进行,好比逐元素相乘、沿某个axis求和、矩阵乘法等操做,具体能够参见Understanding the backward pass through Batch Normalization LayerBatchNorm in Caffe

Batch Normalization的预测阶段

在预测阶段,全部参数的取值是固定的,对BN层而言,意味着\(\mu\)\(\sigma\)\(\gamma\)\(\beta\)都是固定值。

\(\gamma\)\(\beta\)比较好理解,随着训练结束,二者最终收敛,预测阶段使用训练结束时的值便可。

对于\(\mu\)\(\sigma\),在训练阶段,它们为当前mini batch的统计量,随着输入batch的不一样,\(\mu\)\(\sigma\)一直在变化。在预测阶段,输入数据可能只有1条,该使用哪一个\(\mu\)\(\sigma\),或者说,每一个BN层的\(\mu\)\(\sigma\)该如何取值?能够采用训练收敛最后几批mini batch的 \(\mu\)\(\sigma\)的指望,做为预测阶段的\(\mu\)\(\sigma\)以下所示,

Training a Batch-Normalized Network

由于Standardization和scale and shift均为线性变换,在预测阶段全部参数均固定的状况下,参数能够合并成\(y=kx+b\)的形式,如上图中行号11所示。

Batch Normalization的做用

使用Batch Normalization,能够得到以下好处,

  • 可使用更大的学习率,训练过程更加稳定,极大提升了训练速度。
  • 能够将bias置为0,由于Batch Normalization的Standardization过程会移除直流份量,因此再也不须要bias。
  • 对权重初始化再也不敏感,一般权重采样自0均值某方差的高斯分布,以往对高斯分布的方差设置十分重要,有了Batch Normalization后,对与同一个输出节点相连的权重进行放缩,其标准差\(\sigma\)也会放缩一样的倍数,相除抵消。
  • 对权重的尺度再也不敏感,理由同上,尺度统一由\(\gamma\)参数控制,在训练中决定。
  • 深层网络可使用sigmoid和tanh了,理由同上,BN抑制了梯度消失。
  • Batch Normalization具备某种正则做用,不须要太依赖dropout,减小过拟合

几个问题

卷积层如何使用BatchNorm?

For convolutional layers, we additionally want the normalization to obey the convolutional property – so that different elements of the same feature map, at different locations, are normalized in the same way. To achieve this, we jointly normalize all the activations in a mini-batch, over all locations.

...

so for a mini-batch of size m and feature maps of size p × q, we use the effective mini-batch of size m′

= |B| = m · pq. We learn a pair of parameters γ(k) and β(k) per feature map, rather than per activation.

—— Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift

1个卷积核产生1个feature map,1个feature map有1对\(\gamma\)\(\beta\)参数,同一batch同channel的feature map共享同一对\(\gamma\)\(\beta\)参数,若卷积层有\(n\)个卷积核,则有\(n\)\(\gamma\)\(\beta\)参数。

没有scale and shift过程可不能够?

BatchNorm有两个过程,Standardization和scale and shift,前者是机器学习经常使用的数据预处理技术,在浅层模型中,只需对数据进行Standardization便可,Batch Normalization可不能够只有Standardization呢?

答案是能够,但网络的表达能力会降低。

直觉上理解,浅层模型中,只须要模型适应数据分布便可。对深度神经网络,每层的输入分布和权重要相互协调,强制把分布限制在zero mean unit variance并不见得是最好的选择,加入参数\(\gamma\)\(\beta\),对输入进行scale and shift,有利于分布与权重的相互协调,特别地,令\(\gamma=1, \beta = 0\)等价于只用Standardization,令\(\gamma=\sigma, \beta=\mu\)等价于没有BN层,scale and shift涵盖了这2种特殊状况,在训练过程当中决定什么样的分布是适合的,因此使用scale and shift加强了网络的表达能力。

表达能力更强,在实践中性能就会更好吗?并不见得,就像曾经参数越多不见得性能越好同样。caffenet-benchmark-batchnorm中,做者实验发现没有scale and shift性能可能还更好一些,图见下一小节。

BN层放在ReLU前面仍是后面?

paper建议将BN层放置在ReLU前,由于ReLU激活函数的输出非负,不能近似为高斯分布。

The goal of Batch Normalization is to achieve a stable distribution of activation values throughout training, and in our experiments we apply it before the nonlinearity since that is where matching the first and second moments is more likely to result in a stable distribution.

—— Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift

可是,在caffenet-benchmark-batchnorm中,做者基于caffenet在ImageNet2012上作了以下对比实验,

https://github.com/ducha-aiki/caffenet-benchmark/blob/master/batchnorm.md

实验代表,放在先后的差别彷佛不大,甚至放在ReLU后还好一些。

放在ReLU后至关于直接对每层的输入进行归一化,以下图所示,这与浅层模型的Standardization是一致的。

https://www.microsoft.com/en-us/research/video/how-does-batch-normalization-help-optimization/

caffenet-benchmark-batchnorm中,还有BN层与不一样激活函数、不一样初始化方法、dropout等排列组合的对比实验,能够看看。

因此,BN究竟应该放在激活的前面仍是后面?以及,BN与其余变量,如激活函数、初始化方法、dropout等,如何组合才是最优?可能只有直觉和经验性的指导意见,具体问题的具体答案可能仍是得实验说了算(微笑)。

BN层为何有效?

BN层的有效性已有目共睹,但为何有效可能还须要进一步研究,这里有一些解释,

  • BN层让损失函数更平滑。论文How Does Batch Normalization Help Optimization中,经过分析训练过程当中每步梯度方向上步长变化引发的损失变化范围、梯度幅值的变化范围、光滑度的变化,认为添加BN层后,损失函数的landscape(loss surface)变得更平滑,相比高低不平上下起伏的loss surface,平滑loss surface的梯度预测性更好,能够选取较大的步长。以下图所示,

    https://arxiv.org/abs/1805.11604

  • BN更有利于梯度降低。论文An empirical analysis of the optimization of deep network loss surfaces中,绘制了VGG和NIN网络在有无BN层的状况下,loss surface的差别,包含初始点位置以及不一样优化算法最终收敛到的local minima位置,以下图所示。没有BN层的,其loss surface存在较大的高原,有BN层的则没有高原,而是山峰,所以更容易降低。

    https://arxiv.org/abs/1612.04010

  • 这里再提供一个直觉上的理解,没有BN层的状况下,网络没办法直接控制每层输入的分布,其分布前面层的权重共同决定,或者说分布的均值和方差“隐藏”在前面层的每一个权重中,网络若想调整其分布,须要经过复杂的反向传播过程调整前面的每一个权重实现,BN层的存在至关于将分布的均值和方差从权重中剥离了出来,只需调整\(\gamma\)\(\beta\)两个参数就能够直接调整分布,让分布和权重的配合变得更加容易。

这里多说一句,论文How Does Batch Normalization Help Optimization中对比了标准VGG以及加了BN层的VGG每层分布随训练过程的变化,发现二者并没有明显差别,认为BatchNorm并无改善 Internal Covariate Shift但这里有个问题是,二者的训练均可以收敛,对于不能收敛或者训练过程十分震荡的模型呢,其分布变化是怎样的?我也不知道,没作过实验(微笑)。

以上。

参考

相关文章
相关标签/搜索