0x01 初识
随机梯度下降法及其变种已经成为训练神经网络的有效方法,但是它们有个通病:
我们需要人为选择参数,比如学习率、参数初始化、权重衰减系数、Dropout等。这些参数的选择对训练结果至关重要,以至于机器学习中人工的成分占比较多。
Batch normalization则减少了刻意调参的工作量。
0x02 原理
讲解算法前,先来思考一个问题:
在神经网络训练开始前,一般都要对输入数据做一个归一化处理。那么为什么需要这么做呢?归一化的好处是什么呢?
-
一种说法认为,神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;
-
此外,一旦每批训练数据的分布各不相同(batch 梯度下降的时候完全可能选择到不同的分布),那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度。
-
另外一种说法是,数值数量级差距很大的分布可能造成待优化的曲面变得十分陡峭且扭曲,这并不适合随机梯度下降之类的优化算法做优化。
综上所述,为了规范每一层输入数据的分布,我们使用BatchNormalization进行每一层数据的预处理。
需要注意的是,这里的数据输入分布差距大不仅指神经网络输入层(即喂数据的那一层),它可能存在在每一层神经网络的输入中。
以网络第二层为例:网络的第二层输入,是由第一层的参数和input计算得到的,而第一层的参数在整个训练过程中一直在变化,因此必然会引起后面每一层输入数据分布的改变。我们把网络中间层在训练过程中,数据分布的改变称之为Internal Covariate Shift。
Batch Normalization就是要解决在训练过程中,中间层数据分布发生改变的情况。
BN概述
就像激活函数层、卷积层、全连接层、池化层一样,BN(Batch Normalization)也属于网络的一层。
前面我们说过,每一层的输入都可能因为参数的不断变化,从而得到一个狰狞的数据分布。
这个时候我们可能就会想,如果在每一层输入的时候都加个预处理操作该多好啊。比如网络第三层输入数据,在喂入神经元之前我们先把它们归一化至均值0、方差为1,这样我们就可以解决前面所提到的“Internal Covariate Shift”的问题了。
而事实上,Batch Normalization算法本质原理就是这样:在网络的每一层输入的时候,又插入了一个归一化层,也就是先做一个归一化处理,然后再进入网络的下一层。
不过其归一化层不像我们想象的那么简单,它是一个可学习、有参数的网络层。既然说到数据预处理,下面就先来复习一下最强的预处理方法:白化。
白化
白在统计学里指不相关。比如高斯白噪声,指前后不相关的服从正态分布的信号。
白化处理之后的数据集有下面的特征:
- 特征之间相关性较低;
- 特征归一化,即均值0方差1。
但是如果数据特征维数比较大,要使用PCA进行相关性去除,也就是实现白化的第1个要求,是需要计算特征向量的,这项运算开销较大。因此,我们直接忽略1,进行2。
而且,在这一步做1可以,但是没必要,因为神经网络还是可以处理相关性强的数据的。
在实际使用的时候我们都会用small batch做随机梯度下降,因此在归一化的时候,均值和方差实际上是small batch中样本的均值和方差。
0x03 实现
batch normalization似乎很naive啊
训练
这东西实现起来并不是那么简单的。
其实如果是仅仅使用上面的归一化公式,对网络某一层A的输出数据做归一化,然后送入网络下一层B,这样其实是会影响到本层网络A所学习到的特征的。
正常来理解的话,这一通归一化的操作会把我们上一层好不容易总结出来的特征直接破坏了。
Batch Normalization (BN) 就被添加在每一个全连接和激励函数之间。首先,我们进行归一化。然后,引入变换重构,引入可学习参数
γ
\gamma
γ,
β
\beta
β:
y
(
k
)
=
γ
(
k
)
x
^
(
k
)
+
β
(
k
)
y^{(k)} = \gamma^{(k)} \hat{x}^{(k)} + \beta^{(k)}
y(k)=γ(k)x^(k)+β(k)
每一个神经元 x ( k ) x^{(k)} x(k)都会有一对这样的参数 γ ( k ) \gamma^{(k)} γ(k), β ( k ) \beta^{(k)} β(k)。
概括地说,Batch Normalization在激活之前,先做了一个归一化操作,然后再对归一化操作之后的参数做一次线性变换,这个线性变换的参数是可以学习的,学习成什么样由神经网络决定,当然也可能恢复原来的特征。
上述的 γ \gamma γ和 β \beta β可以通过反向传播的方式来学习。
测试
测试时,神经网络里所有的可调参数(比如神经网络的权值和上文的 γ ( k ) \gamma^{(k)} γ(k), β ( k ) \beta^{(k)} β(k))都是固定住的。
因为测试时也传入batch,我们可以用每个batch里各维度数据的均值、方差的无偏估计作为归一化使用的均值和方差。