1 背景说明
本文是同组中一位同学的组内技术分享,觉得很有意思,就暂且拿过来总结一下。涉及到的可能并不止 Batch Normalization(下文简称 BN),而是以 BN 为代表的深度学习中的网络标准化方法。
为什么深度学习网络需要标准化呢?主要原因在于输入数据的不确定性,随着训练过程的进行,导致参数震荡。网络标准化的好处主要体现在以下两个方面:
- 加快模型的收敛速度
- 提升模型的精度:在涉及到计算距离的算法时效果显著(距离计算如果不做标准化,就没法保证度量单位的一致性)
2 深度学习中的网络标准化
2.1 归一化
归一化的定义:将数据按比例缩放,使之落入一个特定区间,去除数据的单位限制,将其转化为无量纲的纯数值,使得数据之间具有可比性。举一个简单的例子来说明:
上图中 x1x1x_1 表示尺寸,x2x2x_2 表示 bedrooms 个数,如果不做标准化,J(θ)J(θ)J(\theta)等高线如左图,做了标准化之后 J(θ)J(θ)J(\theta)等高线如右图;很显然,在后续寻找梯度时,右图能更快找到最优点。
2.2 常用的归一化方法
ML/DL 中常用的数据标准化方法有以下几种:
(1)min-max 方法
以上是几种常用的数据标准化的方法。BN 其实也是在这几种方法的基础上演进而来的。
2.3 Batch Normalization
BN 主要用来解决深度学习中的层级网络输入不一致的问题。一般情况下,深度学习优化的目标函数为:
其中 ΘΘ\Theta 表示参数空间集合。考虑到计算量的问题,一般采用 mini-batch SGD 做参数更新,效果与 mini-batch 的大小成正比,mmm 为 mini-batch 大小:
如果保证 F2F2F_2 的输入分布一致,网络不用因为每一次都去适应新的分布而导致学习缓慢,话句话说就是 Θ2Θ2\Theta_2 不会剧烈震荡。
这就是 BN 提出的背景,本文提出的 BN 方法可以解决以下问题:
- 使得各层输入的分布一致,从而加快学习过程;
- 降低了梯度下降过程中梯度对于参数取值范围或者初始值的依赖,这将使得我们可以使用很大的学习率并且不用担心不收敛;
- 可以去除使用 dropout 的必要;
- 可以使用非线性饱和函数,因为 BN 使得激活函数的激活值以很大的概率落在线性区;
xxx 表示输入数据,x(k)x(k)x^{(k)}表示输入数据的第 kkk 维。假设网络中的各层的激活值分布如下图所示:
这意味着 95% 的参数分布在 [-2, 2] 之间,对于 sigmoid 来讲,落入线性区的可能性更大:
以上便是 BN 的基本原理和解释。
3 总结
现在 BN 越来越流行,特别是随着数据量越来越大,在不损失模型性能的情况下,提高模型的收敛速度也就变得越来越重要了。另外,tensorflow 中目前已经提供了对 BN 的支持,使用的也比较简单:
1 2 3 4 5 6 7 | from tensorflow.contrib.layers.python.layers import batch_norm as batch_norm # ...... bn_train = batch_norm(x, decay=self.decay, center=True, scale=True, updates_collections=None, is_training=True, reuse=None, trainable=True, scope=scope_bn) bn_inference = batch_norm(x, decay=self.decay, center=True, scale=True, updates_collections=None, is_training=False, reuse=True, trainable=True, scope=scope_bn) |