Batch Normalization

2023-10-17 18:26:17 浏览数 (1)

Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift

ICML 2015

本文主要是对网络层的输入分布做归一化( each training mini-batch)来提高训练速度,有一定的 Dropout 效果。

1 Introduction 深度学习在各个领域进展都很快。随机梯度下降(SGD)在训练深度网络是一个有效的方法。SGD的改进版本如 momentum 和 Adagrad 也取得很好的效果。SGD 优化网络的参数,主要是通过最小化下面的损失函数:

假定整个训练样本有 N 个样本,我们在训练时是分批进行的,每批训练 m 个样本。在批训练数据上我们计算近似参数相对损失函数的梯度。为什么每批用 m 个样本而不是一个样本,主要有以下几个原因:1)随着每批数量的增加,梯度的近似越来越准确,因为我们是估计整个训练样本的梯度。2)一次计算 m 个样本,对于提供并行化计算的计算平台更高效。 尽管随机下降梯度是一个简单有效的防范,但是它很小心的调整模型的超参数,特别是学习率这个参数以及模型的初始化参数。每个网络层的输入一直在变化,因为这个输入受前面所有层参数的影响,这使得训练变得复杂化,网络参数一个小的变化都会随着网络层数的增加而被放大。 网络层的输入分布的改变导致了一个问题,因为该网络层参数需要通过调整去适应新的分布。当一个学习系统的输入分布发生变化,通常被称之为 experience covariate shift 。这通常可以通过 domain adaptation 来解决。当然我们可以把 covariate shift 这个概念应用到 整个系统中的局部或一层网络。考虑如下的网络计算

其中F1和 F2 两个任意的变换,这里 F1的输出 x 可以看做 F2的输入。梯度下降迭代公式如下:

如果训练数据和测试数据具有相同的分布,这会使得训练更高效(因为分布相同,所以我们是在学习正确的模型)。这同样适用于局部网络的训练。所以如果我们把 x 的分布固定下来,那么就不用通过改变F2的参数来适应 x 的分布改变。 固定局部网络的输入分布对该局部网络以外的网络层也有积极效果。假定一个网络层的激活函数为 z=g(Wu b), 其中 u 是网络层的输入,W和 b 是需要学习的参数,其中 g(x)=1/(1 exp(-x))。 当x的绝对值增加, g(x)梯度趋于 0 。梯度趋于0 会导致模型的训练变得很慢。因为 x 不仅受 W 和 b的影响,还受前面所有网络层参数 的影响,改变前面这些网络层的参数很可能会导致 x 进入非线性饱和区,进而梯度趋于0,降低收敛速度。随着网络层数的增加,这个效果会被放大。在实际中,对于饱和问题及梯度消失问题可以通过 引入 ReLu激活函数和更好的初始化策略来解决。但是如果我们可以确保输入分布保持不变,那么我们在训练中就不会掉进饱和区,从而加快了训练速度。 我们使用 Internal Covariate Shift 来描述一个深度网络在训练时,内部节点的分布发生改变。如果消除这个Internal Covariate Shift ,那么就可以加快训练速度。于是我们提出了一个新的机制 Batch Normalization,它可以降低 Internal Covariate Shift ,显著加快训练速度。它是通过一步归一化:固定网络层输入的均值和方差来实现的。 Batch Normalization 对于网络的梯度信息传播也有积极作用,主要是降低了参数大小及参数初始化大小的影响。这就可以让我们使用很高的学习率参数而不至于系统发散。Batch Normalization 对模型有一定镇定作用,从而降低了 对 Dropout 的需要。最后 Batch Normalization 使我们能够使用非线性饱和特性,但是又不受饱和区域的消极影响。

2 Towards Reducing Internal Covariate Shift 我们将网络参数在训练时改变导致的网络激活影响分布的改变定义为: Internal Covariate Shift。为了加快训练速度,我们需要降低 Internal Covariate Shift。在训练过程中通过固定网络层输入 x 的分布来加快训练速度。在很久以前,我们就知道对输入进行白化操作可以加快训练速度(就是通过线性变换得到0均值,单位方差,去相关性)。因为每一层的输入是前一层的输出,如果对每一层都进行白化,那么每一层输入的分布就是固定的,从而消除了 Internal Covariate Shift 的影响。 直接这么做存在问题: 计算量大(计算整个训练集的均值)以及不可导问题。我们可以在训练每个步骤或某一些阶段进行激活响应的白化,根据网络激活响应值,通过直接改变网络或者调整算法参数实现白化。 但是如果这些白化分散在优化步骤中,梯度下降可能要求参数更新这个归一化,这会降低梯度的影响。例如,假定一层的输入为 u 加上学习到的偏置 b,通过在训练数据集上减激活响应的均值来归一化: x^=x-E[x],其中 x=u b,训练集 X 上有N 个 样本 x。期望均值E[x] 即样本集的均值。如果下降梯度计算步骤忽略 b 对 E[x] 的依赖,那么 b 的迭代更新公式为 b~ b delt(b),

所以偏置 b 的更新以及随后归一化的改变对 网络层的输出和 损失函数没有改变。随着训练的进行,b 将变得无穷大,如果损失保持固定。如果不仅均值归一化,而且还方差归一化,那么问题更严重。我们在最初的实验中观察到这个现象,当归一化参数计算在梯度计算外部时,系统会崩溃。 上面的问题主要是因为梯度下降优化算法没有考虑到归一化的发生。为了解决这个问题,我们希望确保对任何参数值,网络总是产生期望的分布。这么做可以使模型参数中的梯度计算考虑到归一化。但是这种归一化是相对于整个训练数据集,这就导致计算量很大。我们希望可以找打一个计算量不太大的方法把这个事就干了。

3 Normalization via Mini-Batch Statistics

因为对于每层输入进行全白化运算量很大,而且不是处处可导。所以我们做了两个必要的简化。相对于对网络层输入输出联合的特征白化,我们对每个独立的标量特征进行归一化,使其均值为0,方差为1。对于一个网络层有 d 维的输入x,我们对每个维度进行独立的归一化。

上面公式中的期望值和方差是在整个训练数据集上计算得到的。以前的文献已经指出这样的归一化可以加快收敛速度,尽管没有对特征去除相关性处理。 注意到对网络层输入的简单归一化可能会改变网络的表达内容。例如,对 sigmoid的输入进行归一化会约束其集中于线性区域。为了保持网络非线性表达能力,我们对每个神经元引入两个参数,他们和整个网络一起学习。

我们做的第二个简化就是在 批训练数据上计算均值和方差,而不是整个训练数据集上计算均值和方差。

http://blog.csdn.net/malefactor/article/details/51476961#0-tsina-1-62851-397232819ff9a47a7b7e80a40613cfe1 这篇写的比较简单明了。

0 人点赞