Batch Normalization

Batch Normalization

BN 层是现如今深度网络中比较常用与有效的正则化方法,不仅可以减少梯度消失以及梯度爆炸的问题,还可以加速参数的优化。不过 Batch Normalization 在网络中到底做了什么,而这样做有什么意义呢?

为什么使用 BN

每一次神经网络权重 $w$ 的更新都是为了减少loss而服务的,而深度学习中,由于数据需要分成若干个mini batch,可能导致每组数据分布有着不同的差异,但机器学习理论是建立在所有样本 $iid$(独立同分布)的基础上的,而这中差异会随着网络层数的加深而变得离谱,以至于让\w不停的在适应前一层的数据分布变化而很难找到让大家都满意的方向。这种现象被 Google 称作 Internal Covariate Shift。👇(但似乎这种对于 BN 的解释被推翻了)

在深度学习中,因为网络的层数非常多,如果数据分布在某一层开始有明显的偏移,随着网络的加深这一问题会加剧(这在 BN 的文章中被称之为 Internal Covariate Shift),进而导致模型优化的难度增加,甚至不能优化。所以,归一化就是要减缓这个问题。

而 BN 的出现可以有效缓解这类问题,BN 将每层的输入经过不断更新的参数 $\gamma,\beta$ 的控制,重新放缩来达到一个近似稳定的分布,不让待更新的参数随着每个batch数据的分布来不停变换自己的状态。

如果 BatchSize 较小,有BN层的网络表现可能不是很好,这是因为较小的 batch(较少的样本抽样)并不能有效地表示样本分布,以致于不能发挥 BN 层掌握样本的分布信息,控制每层的输入分布的作用。

而 Batch Normalization 中的 Normalization 同时也可以平滑样本空间,减少维度之间的量级差异,提高优化效率。同时也提升网络的泛化能力,可以替代 Dropout 层。

通常,对于卷积网络来说,BN 层都夹在卷积层与激活函数之间。但是这个位置也没要求有特殊的固定。放在激活函数之后(卷积层之前也是可以的)。

BN 层总共分四步:

在卷积网络中,BN 是以 channel 为单位求和的,不同的 channel 会有一组不同的参数 $(\gamma^{c_i},\beta^{c_i} )$ 。由于 BN 已经对数据进行平移与放缩,那么卷积层就不需要偏执项 bias 了。

训练与预测时的 BN

训练时,均值与方差 $(\gamma^{c_i},\beta^{c_i} )$ 均来自 batch 中所有样本在每个通道 $c_i$ 的均值与方差。而预测时,我们采用整个训练样本的均值与方差,但是这些值在数据流中维护都很麻烦,于是我们在训练过程中使用滑动平滑的方法,近似求解他们的期望 $\mathbb E(\mu),\mathbb E(\sigma^2)$:

其中 $\mu_G,\sigma^2_G$ 就是我们近似得到的样本空间的均值与方差的期望, $\rho$ 是衰减参数,在 BN 层中 $\rho=0.9$。

BN 的反向传播

在研究复杂函数的反向传播时,计算图是一个很好的工具,BN的计算图如下:

假定损失函数 $L$,反向传播过程如下:

由于 $\hat y_i = \gamma\hat x_i+\beta$,则

根据计算图,

麻烦的是求解 ${\partial \hat x_i}/{\partial x_i}$

这里注意 在对均值与方差求偏导数时,均值与方差的梯度方向应该被更新 $N$ 次,故 ${\partial \hat x_i}/{\partial \mu},{\partial \hat x_i}/{\partial \sigma^2}$ 应该替代为,这里带回原式时要小心:

其中,根据 $(3)$ 式

对于 ${\partial \hat x_j}/{\partial \mu}$:

对于 ${\partial \mu}/{\partial x_i}$:

对于 ${\partial \hat x_i}/{\partial \sigma^2 }$,上上式已经求出:

对于 ${\partial \sigma^2}/{\partial x_i}$:

最终,整理得:

Inference

1