0%

深度学习中的 Batch Normalization

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 方法

(2)Log 函数转换

(3)atan 转换

(4)Z-score 转换

以上是几种常用的数据标准化的方法。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 使得激活函数的激活值以很大的概率落在线性区;

BN 对输入数据的每一维做标准化:

xxx 表示输入数据,x(k)x(k)x^{(k)}表示输入数据的第 kkk 维。假设网络中的各层的激活值分布如下图所示:

经过 BN 之后,网络各层的输入满足下面的正态分布:

这意味着 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)