前言
Batch Normalization 是一种数据归一化方法,针对每一批数据,在网络的非线性变化(激活函数sigmod、relu等)之前增加归一化处理(均值为 0 ,标准差为 1 ) , 将所有批数据强制在统一的数据分布下,然后再将其输入到下一层,使整个神经网络在各层的中间输出的数值更稳定。其作用可以加快模型训练时的收敛速度,使得模型训练过程更加稳定,避免梯度爆炸或者梯度消失,并且起到一定的正则化作用,几乎代替了 Dropout 。
在BN原论文中,在CNN中应用顺序为Conv-BatchNorm-activation,但是也有相关工作表示BN放在激活函数后效果好。既然意见不一致,实践中可以前后都试一试。
相关概念
内部协变量偏移(Internal Covariate Shift):
内部协变量偏移是指在训练过程中由于网络参数的变化而导致的网络激活分布的变化。
神经网络训练过程的本质是学习数据分布,如果训练数据与测试数据的分布不同将大大降低网络的泛化能力,因此我们需要在训练开始前对所有输入数据进行归一化处理。然而随着网络训练的进行,每个隐层的参数变化使得后一层的输入发生变化,从而每一批训练数据的分布也随之改变,致使网络在每次迭代中都需要拟合不同的数据分布,增大训练的复杂度以及过拟合的风险。 为了解决内部协变量偏移问题,就要使得每一个神经层的输入的分布在训练过程要保持一致。
梯度饱和
sigmoid激活函数和tanh激活函数存在梯度饱和的区域,其原因是激活函数的输入值过大或者过小,其得到的激活函数的梯度值会非常接近于0,使得网络的收敛速度减慢。传统的方法是使用不存在梯度饱和区域的激活函数,例如ReLU等。BN也可以缓解梯度饱和的问题,它的策略是在调用激活函数之前将 的值归一化到梯度值比较大的区域。假设激活函数为
,BN应在
之前使用:
批量归一化(Batch Normalization,BN)
令第 层的净输入 为
,神经元的输出为
为了减少内部协变量偏移问题,就要使得净输入 的分布一致,比如都归一化到标准正态分布。但是逐层归一化需要在中间层进行操作,要求效率比较高,因此复杂度比较高的白化方法就不太合适。为了提高归一化效率,一般使用标准归一化,将净输入
的每一维都归一到标准正态分布:
白化目的:
- 去除特征之间的相关性:独立;
- 使得所有特征具有相同的均值和方差 :同分布。
和
指当前参数下,
的每一维在整个训练集上的期望和方差。因为目前主要的训练方法是基于小批量的随机梯度下降方法,因此
的期望和方差通常用当前小批量样本集的均值和方差近似估计。(当Batch_size很小时,当前批样本不能反映样本集的均值和方差,所以BN要求batch_size不能太小)
给定一个包含 个样本的小批量样本集合,第
层神经元的净输入
的均值和方差为:
对净输入 的标准归一化会使得其取值集中在0附近,如果使用sigmoid型函数时,这个取值区间刚好接近线性变换区间,减弱了神经网络的非线性性质,而且归一化会破坏该层网络学习到的特征分布。因此,为了使得归一化不对网络的表示能力造成负面影响,我们可以通过一个附加的缩放和平移变换改变取值区间。
其中 和
分别代表缩放和平移的参数向量,当
时,
批量归一化可以看作是一个特殊的神经层,加在每一层非线性激活函数之前,即
每次小批量样本的 和方差
是净输入
的函数,而不是常量,计算参数梯度时需要考虑
和
的影响。当训练完成,在预测阶段用整个数据集上的均值
和方差
来别代替每次小批量样本的
和方差
,在实践中,
也可以用移动平均来计算。
卷积网络中的BN
BN除了可以应用在MLP上,其在CNN网络中的表现也非常好,但是在RNN上的表现并不好,具体原因后面解释,这里详细介绍BN在卷积网络中的使用方法。
卷积网络和MLP的不同点是卷积网络中每个样本的隐层节点的输出是三维(宽度,高度,维度)的,而MLP是一维的,如图2所示。
图2:卷积网络的BN示意图
在图2中,假设一个批量有 个样本,Feature Map的尺寸是
,通道数是
。在卷积网络的中,BN的操作是以Feature Map为单位的,因此一个BN要统计的数据个数为
,每个Feature Map使用一组
和
,此处需要三组。
BN的优点
- BN中的γ和β的作用:
- 保证了模型的capacity,意思就是,γ和β作为调整参数可以调整被BN刻意改变过后的输入,即能够保证能够还原成原始的输入分布。BN对每一层输入分布的调整有可能改变某层原来的输入,当然有了这两个参数,经过调整也可以不发生改变,既可以改变同时也可以保持原输入,那么模型的容纳能力(capacity)就提升了。
- 适应激活函数,如果是sigmoid函数,那么BN后的分布在0-1之间,由于sigmoid在接近0的地方趋于线性,非线性表达能力可能会降低,因此通过γ和β可以自动调整输入分布,使得非线性表达能力增强。
- 如果激活函数为ReLU,那么意味着将有一半的激活函数无法使用,那么通过β可以进行调整参与激活的数据的比例,防止dead-Relu问题。
- 解决“internal covariate shift”的问题,神经网络目的就是通过训练模型,可以让模型能够最好的拟合数据的真实分布。在训练时,训练数据经过层间操作,会出现数据分布的微小偏移,随着网络层数的加深,这种偏移量与label的差别逐渐扩大,导致模型需要学习调整样本的分布,训练效率低下。BN将每层的数据进行标准化,并通过可学习参数γ和β两个学习参数来调整这种分布。这样会缓解内部协变量偏移的问题,大大增加了训练速度。
- 避免了梯度弥散和爆炸,BN可以控制数据的分布范围,在遇到sigmoid或者tanh等激活函数时,不会使数据落在饱和区域导致梯度弥散。并且BN可以避免ReLU激活函数数据死亡的问题。
- 降低权重初始化的困难,在深度网络中,网络的最终训练效果也受到初始化的影响,初始化决定了神经网络最终会收敛到哪个局部最小值中,具有随机性。通过BN来标准化分布,可以降低初始化权重的影响。
- BN可以起到和dropout一样的正则化效果,在正则化方面,一般全连接层用dropout,卷积层用BN。
BN不足
BN是按照样本数计算归一化统计量的,当样本数很少时,比如说只有4个。这四个样本的均值和方差便不能反映全局的统计分布息,所以基于少量样本的BN的效果会变差。
层归一化(Layer Normalization,LN)
如果一个神经元的净输入分布在神经网络中是动态变化的,比如循环神经网络,那么无法应用批归一化操作。
层归一化和批归一化不同的是,层归一化是对一个中间层的所有神经元进行归一化。
令第 层神经的净输入为
,其均值和方差为:
,
为第
层神经元的数量,i为样本的不同维度。
层归一化定义为: 代表缩放和平移的参数向量,和
维数相同。
循环神经网络中的层归一化
假设在时刻t,循环神经网络的隐藏层为 ,其归一化的更新为:
,
为t时刻的输入,
为网络参数。
在标准循环神经网络中,循环神经网络的净输入一般会随着时间慢慢变大或变小,从而导致梯度爆炸或消失。而层归一化的循环神经网络可以有效地缓解这种状况。
对于 个样本的一个小批量集合
(一列为一个样本),层归一化是矩阵
对每一列进行归一化,而批量归一化是对每一行进行归一化。一般而言,批归一化是一种更好的选择,因为基于不同数据、统一特征得到的归一化特征更不容易损失信息。当小批量样本数量比较小时,可以选择层归一化。
为什么BN不适用于RNN?
如果将BN应用在RNN中,由于BN是以BN为单位统计归一化变量的,所以不同长度的样本的时间片如何计算将十分困难。在BN中我们需要根据训练数据保存两个统计量 和
,如果在测试时一组样本的长度大于训练的所有样本,那么它的后面的时间片需要的
和
没有统计。例如训练集样本最长为4,当测试集长度为8时,没有统计量
和
。

在上图中每个颜色表示一个训练样本,每个样本都有自己的长度。N为样本数,T为时间片(每个文本词的个数),C为频道(每个词的向量表示的维度)
BN归一化的是不同样本中每个词的相同的频道C(红色框),LN归一化的是一个样本的每个词的所有维度(蓝色框)。
BN是按与y轴平行的方向计算统计量(即[N,T])。由于BN中每个样本的长度都不一样,计算的 和
时就会非常不具有代表性,当t>3时,我们只能获得来自第二个样本的一个统计量,那么此时的均值和方差已经没有意义。
LN是按与x轴平行的方向做归一化(即[C,T]),这个被证明是在RNN中表现比较好的一种归一化方法,因为在每个时间片都会获得相同的数量(通道数)个数值的归一化统计量。LN中不同时间片的 和
是共享的。
参考文献:
Ioffe S, Szegedy C. Batch normalization: Accelerating deep network training by reducing internal covariate shift[J]. arXiv preprint arXiv:1502.03167, 2015.
