- 论文链接:https://arxiv.org/pdf/1502.03167.pdf
- 论文题目:Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift
这里说明一下,这篇已经是很早的paper了,但是它的非常重要,所以我重温了一下,顺便翻译了。
Batch Normalization
Abstract
训练深度神经网络是很复杂的,因为训练时随着前面层参数的变化,对应每一层的输入的分布都是在变化的。这会拖慢训练,而且需要较小的学习率和精细的参数初始化,尤其如果是训练一个带有饱和非线性的网络的话,将会非常的困难。我们将这个现象称为 interval covariate shift,然后我们可以通过对层输入进行归一化来解决。我们的方法呢,好就好在将归一化作为网络结构的一部分,对于训练的每一个mini-batch来进行归一化。BN允许我们能够使用更大的学习率,以及更加粗糙的初始化。同时,还带有一定的正则化的效果,某些情况下,可以取代Dropout。对于之前state-of-the-art的图像分类网络,BN大大减少了所需要的训练steps,同时提高了准确率。
1 Introduction
SGD已经被证明了是一种有效的训练深度网络的方法,SGD优化网络参数,是通过最小化loss
Θ
=
arg
min
Θ
1
N
∑
i
=
1
N
ℓ
(
x
i
,
Θ
)
\Theta=\arg \min_{\Theta} \frac{1}{N}\sum^N_{i=1} \ell(\mathbf x_i, \Theta)
Θ=argΘminN1i=1∑Nℓ(xi,Θ)
x
1...
N
\mathbf x_{1...N}
x1...N是训练数据集。使用SGD,每一步训练,我们都考虑使用
x
1...
m
\mathbf x_{1...m}
x1...m的一个mini-batch进行训练。该mini-batch的关于参数的损失函数梯度表示为
1
m
∂
ℓ
(
x
i
,
Θ
)
∂
Θ
.
\frac{1}{m}\frac{\partial \ell(\mathbf x_i, \Theta)}{\partial \Theta}.
m1∂Θ∂ℓ(xi,Θ).
使用mini-batch的好处,第一,损失的梯度随着mini-batch的增大越来越接近于训练集的全局梯度。第二,由于计算平台的并行性,使用mini-batch能够加快训练。
虽然SGD非常简单高效,但是它需要精细的调节超参,尤其是学习率和初始参数。训练深度网络是很复杂的,因为每一层的输入都受到所有前面层的影响,尤其是网络越来越深,即使是微小的变化也会被放大。
每一层输入的分布的变化会迫使该层不断尝试学习这个新的分布,该层就经历着covariate shift。该问题可以通过 domain adaptation来解决。然而,covariate shift的概念可以延伸出整个学习系统,着眼于更小的部分,比如子网络或者就是单一层。考虑整个网络在计算
ℓ
=
F
2
(
F
1
(
u
,
Θ
1
)
,
Θ
2
)
\ell =F_2(F_1(\mathbf u, \Theta_1), \Theta_2)
ℓ=F2(F1(u,Θ1),Θ2)
这里
F
F
F表征任意的变换,
Θ
\Theta
Θ指代参数。学习参数来最小化loss。学习
Θ
2
\Theta_2
Θ2可以被视为将
x
=
F
1
(
u
,
Θ
1
)
\mathbf x=F_1(\mathbf u, \Theta_1)
x=F1(u,Θ1)输入进子网络
ℓ
=
F
2
(
x
,
Θ
2
)
.
\ell =F_2(\mathbf x, \Theta_2).
ℓ=F2(x,Θ2).
那么,梯度下降就是
Θ
2
←
Θ
2
−
α
m
∑
i
=
1
m
∂
F
2
(
x
i
,
Θ
2
)
∂
Θ
2
\Theta_2 \leftarrow \Theta_2-\frac{\alpha}{m}\sum^m_{i=1}\frac{\partial F_2(\mathbf x_i,\Theta_2)}{\partial \Theta_2}
Θ2←Θ2−mαi=1∑m∂Θ2∂F2(xi,Θ2)
这里
m
m
m表示batch大小,
α
\alpha
α表示学习率。上式完全等价于一个单独的
F
2
F_2
F2网络,输入为
x
\mathbf x
x。因此,对于训练有益的输入分布的性质(训练和测试数据具有相同分布),同样适用于这个子网络。正因如此,如果输入的分布能够固定的话将有助于训练。这样
Θ
2
\Theta_2
Θ2就不需要反复调整来补偿
x
\mathbf x
x分布的变化。
同样,固定子网络的输入分布对于子网络以外的层来说也是有益的。考虑一个带sigmoid激励的层
z
=
g
(
W
u
+
b
)
\mathbf z=g(W\mathbf u+\mathbf b)
z=g(Wu+b)。只有当
x
=
W
u
+
b
\mathbf x=W\mathbf u+\mathbf b
x=Wu+b位于中心附近时,才有较大的梯度,位于两侧的话,就会引发梯度弥散的问题,导致训练变慢。然而,因为
x
\mathbf x
x是受
W
W
W和
b
\mathbf b
b以及之前层的参数影响的,所以训练中这些参数的变化都很大可能地将
x
x
x的大部分维度都移动到非线性饱和区,从而减缓训练。该影响会随着深度增加而加剧。实际中,饱和问题和梯度弥散问题通常是由ReLU,初始化和小的学习率来解决的。如果我们能够确保非线性输入的分布在训练的时候稳定的话,优化器就不太可能陷入到饱和区,就能加速训练。
我们将在训练时,深度网络的中间节点分布的变化称为Internal Covariate Shift。消除这个问题,能够加速训练。我们提出一种新的机制,叫做BN,来减小该现象,从而极大的提高了深度网络的训练效率。同时BN,还有助于网络中梯度的传递,减小了梯度对于参数大小或者初始值的依赖。这就允许我们使用较大的学习率。BN还带有泛化能力。最后BN使得即使使用非线性饱和激励,也不会陷入饱和区。
2 Toward Reducing Internal Covariate Shift
通过固定训练时层输入的分布,我们期望提高训练速度。我们知道,网络的训练会收敛的很快,如果输入的经过白化的,比如经过线性变换使得满足零均值,单位方差,且不相关。因为每一层观测到的输入是由前面层产生的,如果对于每一层的输入我们都能进行白化,那么对于训练可能是有帮助的。通过对每一层的输入进行白化,我们就向固定输入分布迈出了一步,这会有助于移除 Internal covariate shift。
我们可以考虑在每个训练步或者间隔训练步进行白化激活,或者直接改变网络,再或者根据网络激活值来改变优化算法的参数。然而,如果这些修改之间穿插着优化的话,梯度下降将会根据归一化的更新需要来进行更新,这就将减小梯度的效果。比如,考虑一个带有输入
u
u
u的层,然后加上一个学习过的偏置
b
b
b,然后通过减去训练数据激活值的均值来进行归一化:
x
^
=
x
−
E
[
x
]
\widehat x = x - E[x]
x
=x−E[x],这里
x
=
u
+
b
x=u+b
x=u+b,
X
=
x
1...
N
\mathcal X={x_{1...N}}
X=x1...N是训练集合,
E
[
x
]
=
1
N
∑
i
=
1
N
x
i
E[x]=\frac{1}{N}\sum^N_{i=1}x_i
E[x]=N1∑i=1Nxi。如果梯度下降步骤忽略了
E
[
x
]
E[x]
E[x]和
b
b
b的相关性,那么
b
←
b
+
Δ
b
b\leftarrow b+\Delta b
b←b+Δb,
Δ
b
∝
−
∂
ℓ
/
∂
x
^
\Delta b \propto -\partial \ell/\partial \widehat x
Δb∝−∂ℓ/∂x
。然后有
u
+
(
b
+
Δ
b
)
−
E
[
u
+
(
b
+
Δ
b
)
]
=
u
+
b
−
E
[
u
+
b
]
u+(b+\Delta b)-E[u+(b+\Delta b)]=u+b-E[u+b]
u+(b+Δb)−E[u+(b+Δb)]=u+b−E[u+b]。因此,结合
b
b
b的更新以及后续归一化的改变,将使得网络输出和loss都不会发生改变。随着训练的进行,
b
b
b将会没有限制的变化,而loss却依然不变。如果我们不仅仅是减均值,还对激活值进行缩放的话,这个问题会更加严重。我们在实验中观察到了这个现象,当归一化参数是在梯度下降步骤外计算的时候,模型会爆炸。
上面方法的问题在于梯度下降优化并没有考虑到归一化发生的这一事实。为了解决这个问题,我们要确保,对于任何的参数值,网络总是生成一个理想的激活分布。这样做就能够保证loss的梯度考虑到了所有经过归一化的模型参数,以及模型参数
Θ
\Theta
Θ间的相关性。再次将
x
\mathbf x
x作为层输入,是一个向量,
X
\mathcal X
X为训练数据集。归一化可以写作:
x
^
=
Norm
(
x
,
X
)
\widehat \mathbf x = \text{Norm}(\mathbf x, \mathcal X)
x
=Norm(x,X)
不仅仅跟当前的训练数据
x
\mathbf x
x有关,还涉及到所有的样本
X
\mathcal X
X,对于反传,我们需要计算雅克比行列式
∂
Norm
(
x
,
X
)
∂
x
and
∂
Norm
(
x
,
X
)
∂
X
,
\frac{\partial \text{Norm}(\mathbf x, \mathcal X)}{\partial \mathbf x} \text{ and } \frac{\partial \text{Norm}(\mathbf x, \mathcal X)}{\partial \mathcal X},
∂x∂Norm(x,X) and ∂X∂Norm(x,X),
忽略后面一项会导致模型爆炸,这个上面的例子提到了。在这个框架里,对输入层进行白化是很昂贵的,因为需要计算协方差矩阵
Cov
[
x
]
=
E
x
∈
X
[
x
x
T
]
−
E
[
x
]
E
[
x
]
T
\text{Cov}[\mathbf x]=\text E_{\mathbf x \in \mathcal X}[\mathbf x \mathbf x^T]-\text E[\mathbf x]\text E[\mathbf x]^T
Cov[x]=Ex∈X[xxT]−E[x]E[x]T,和它们的平方根的倒数,来得到白化激活
Cov
[
x
]
−
1
/
2
(
x
−
E
[
x
]
)
\text{Cov}[\mathbf x]^{-1/2}(\mathbf x - \text E[\mathbf x])
Cov[x]−1/2(x−E[x]),以及在反传时这些变换的倒数。这就驱使我们去寻找一种可以代替的方法来进行输入归一化,且该方法可微,且不需要在每次参数更新后对整个训练集进行解析。
一些之前的方法是使用对于单个训练样本的统计数据,或者在图像网路中,对不同特征图的给定位置的统计信息。然而,这丢失了激活函数带来的尺度,改变了网络的表达能力。我们想要通过对训练样本的激活值相对于整个训练数据的统计信息进行归一化来在网络中保存这些信息。
3 Normalization via Mini-Batch Statistics
因为对每一层的输入进行完整的白化是非常昂贵且并不是处处可微的,我们做了两个必要的简化。第一,并不对网络层的输入输出特征进行联合归一化,我们将单独对每一个标量特征进行归一化,使它们拥有零均值,单位方差。对于一个
d
d
d维的输入
x
=
(
x
(
1
)
.
.
.
x
(
d
)
)
\mathbf x=(x^{(1)}...x^{(d)})
x=(x(1)...x(d)),我们对每个维度进行归一化
x
^
(
k
)
=
x
(
k
)
−
E
[
x
(
k
)
]
Var
[
x
(
k
)
]
\widehat x^{(k)}=\frac{x^{(k)}-\text E[x^{(k)}]}{\sqrt{\text{Var}[x^{(k)}]}}
x
(k)=Var[x(k)]x(k)−E[x(k)]
这里期望和方差是对于训练数据集的。这样的归一化能够加快收敛,甚至当特征不是不相关的时候。
注意到简单地对网络层的每一个输入进行归一化是会改变网络层的表达的。比如,对一个sigmoid层的输入进行归一化,那么这会将输出限制在线性区域。为了解决这个问题,我们确保嵌入到网络中的变换可以代表相同的变换。为了完成这个,对于每个激活
x
(
k
)
x^{(k)}
x(k),我们引入一对参数
γ
(
k
)
,
β
(
k
)
\gamma^{(k)},\beta^{(k)}
γ(k),β(k),这是对归一化后的参数进行缩放,平移:
y
(
k
)
=
γ
(
k
)
x
^
(
k
)
+
β
(
k
)
.
y^{(k)}=\gamma^{(k)}\widehat x^{(k)}+\beta^{(k)}.
y(k)=γ(k)x
(k)+β(k).
这些参数跟着原来的模型参数一起学习,来恢复网络的表达能力。如果设置
γ
(
k
)
=
Var
[
x
(
k
)
]
\gamma^{(k)}=\sqrt{\text{Var}[x^{(k)}]}
γ(k)=Var[x(k)],
β
(
k
)
=
E
[
x
(
k
)
]
\beta^{(k)}=\text E[x^{(k)}]
β(k)=E[x(k)],我们可以完全复原原来的激活值,如果这是最优决策的话。
在batch的设定上,每次训练迭代我们使用整个训练集来归一化我们的激活值。然而,在使用SGD的时候这是不现实的。因此我们做出第二个简化:因为在SGD中,我们使用到了mini-batch,所以就使用每个mini-batch来生成每个激活值的对于均值和方差的估计。这样,用于归一化的统计数据就能完全的参与到梯度反传中。注意,使用mini-batch是通过计算每个维度的方差而不是联合协方差来实现的;在联合的情况下,需要进行正则化,因为mini-batch的大小很可能小于要白化的激活数量,这就会导致奇异协方差矩阵。
考虑mini-batch
B
\mathcal B
B的大小为
m
m
m。因为归一化是单独对每个激活元进行操作的,所以我们集中注意一个
x
(
k
)
x^{(k)}
x(k),为了方便我们省略掉
k
k
k。对于这个激活元,在mini-batch里,我们有
m
m
m个值,
B
=
{
x
1...
m
}
.
\mathcal B = \{x_{1...m}\}.
B={x1...m}.
归一化后的值为
x
^
1...
m
\widehat x_{1...m}
x
1...m,然后它们的线性变换为
y
1...
m
y_{1...m}
y1...m。我们将下式
BN
γ
,
β
:
x
1...
m
→
y
1...
m
\text{BN}_{\gamma,\beta}:x_{1...m} \rightarrow y_{1...m}
BNγ,β:x1...m→y1...m
称为 Batch Normalizing Transform。BN变换详情见算法1。算法里
ϵ
\epsilon
ϵ 表示一个很小的常量。
算法1: Batch Normalizing Transform
BN变换可以添加到网络中对任何激活元进行操作。在公式
y
=
BN
γ
,
β
(
x
)
y=\text{BN}_{\gamma,\beta}(x)
y=BNγ,β(x)中,我们指出了
γ
,
β
\gamma,\beta
γ,β是需要学习的,但是需要注意的是,BN变换并不是单独对每个训练样本的激活元进行处理的。而是,
BN
γ
,
β
(
x
)
\text{BN}_{\gamma,\beta}(x)
BNγ,β(x)是取决于训练样本和mini-batch中的其他样本的。经过缩放平移后的值
y
y
y 被传递到网络的其他层中。经过归一化的激活
x
^
\widehat x
x
是我们变换的一个中间结果,但是它们的存在是非常重要的。只要每个mini-batch的元素是从相同分布中抽样出来的,那么任一
x
^
\widehat x
x
的值的分布都是零均值,单位方差。每一个经过归一化的激活元
x
^
(
k
)
\widehat x^{(k)}
x
(k) 被视为后续包含线性变换
y
(
k
)
=
γ
(
k
)
x
^
(
k
)
+
β
(
k
)
y^{(k)}=\gamma^{(k)}\widehat x^{(k)}+\beta^{(k)}
y(k)=γ(k)x
(k)+β(k)的子网络的一个输入。这些子网络的输入都拥有固定的均值和方差,尽管这些经过归一化的
x
^
(
k
)
\widehat x^{(k)}
x
(k) 的联合分布是会随着训练的进程变化的,但是我们期望归一化输入的引入能够加快子网络的训练,进而加快整个网络的训练。
在训练时,我们需要反传损失函数经过这个变换的梯度,同时也要计算对于BN变换的参数的梯度。我们使用链式法则(简化之前):
因此,BN变换是可微变换,它将归一化激活元引入到网络中。这就保证了当模型在训练时,网络可以持续的在输入的分布上进行学习,避免了Internal covariate shift,加快了训练。而且,应用到归一化激活元上的学习到的仿射变换使得BN变换可以表达同样的变换,进而保存网络的容量。
3.1 Training and Inference with Batch-Normalized Networks
为了 Batch-Normalize 一个网络,我们根据算法1,插入了BN变换。所以层之前接收
x
x
x 作为输入,现在接收的是
BN
(
x
)
\text{BN}(x)
BN(x)。一个带有BN的模型可以使用batch GD或者
m
>
1
m>1
m>1 SGD,或者其他变体,比如Adagrad等。使用带mini-batch的方案呢,可以使训练更加有效,但是在infer的时候,这并不是一种理想的方式,或者说没必要这样做;我们想要输出仅仅由输入来决定。因此,一旦网络训练完成,我们使用归一化
x
^
=
x
−
E
[
x
]
Var
[
x
]
+
ϵ
\widehat x = \frac{x-\text{E}[x]}{\sqrt{\text{Var}[x]+\epsilon}}
x
=Var[x]+ϵx−E[x]
使用总体的统计数据,而不是一个mini-batch。忽略掉常量,这些归一化的激活值在训练时都拥有相同的零均值和单位方差。我们使用无偏方差估计
Var
[
x
]
=
m
m
−
1
⋅
E
B
[
σ
B
2
]
\text{Var}[x]=\frac{m}{m-1}\cdot\text E_{\mathcal B}[\sigma^2_{\mathcal B}]
Var[x]=m−1m⋅EB[σB2],其中期望是针对
m
m
m 大小的mini-batch得到的,然后
σ
B
2
\sigma^2_{\mathcal B}
σB2是这些样本的方差。使用这些值的滑动平均,我们可以在模型训练的时候,跟踪它的准确率。因为在infer的时候均值和方差是固定的,所以归一化只是简单的对每个激活元施加一个线性变换。然后再进行一次缩放和平移来。算法2对训练BN网络的过程进行了总结。
算法2:训练BN网络
3.2 Batch-Normalized Convolutional Networks
BN可以应用到网络的任何激活中。这里我们着重关注带有仿射变换和逐元素非线性的变换:
z
=
g
(
W
u
+
b
)
\text z=g(W\text u + \text b)
z=g(Wu+b)
这里
W
,
b
W,\text b
W,b 是模型的可学习参数,
g
g
g 代表非线性激活函数。这个方程涵盖了全连接和卷积层。我们在非线性前面加上BN来归一化
x
=
W
u
+
b
\text x=W\text u + \text b
x=Wu+b。我们也可以归一化层输入
u
\text u
u,但是因为
u
u
u 可能是另一个非线性的输出,它的分布的形状在训练过程中很可能改变,限制它的一阶矩和二阶矩将不能消除 covariate shift。相反,
W
u
+
b
W\text u + \text b
Wu+b就很可能拥有对称的,非稀疏的分布,更加“高斯”;对它进行归一化更加可能生成一个稳定的分布。
注意到,因为我们归一化
W
u
+
b
W\text u + \text b
Wu+b,偏置项会因为减均值这一步被忽略(偏置项的角色将由
β
\beta
β来代替),因此
z
=
g
(
W
u
+
b
)
\text z=g(W\text u + \text b)
z=g(Wu+b)变成
z
=
g
(
BN
(
W
u
)
)
\text z=g(\text{BN}(W\text u))
z=g(BN(Wu))
BN变换是单独的对
x
=
W
u
\text x=W\text u
x=Wu的每一个维度进行操作的,对于每个维度,我们都有一组学习参数
γ
(
k
)
,
β
(
k
)
\gamma^{(k)}, \beta^{(k)}
γ(k),β(k)。
对于卷积层,我们还希望归一化能够遵守卷积的性质,所以对于同一个特征图的不同位置的不同元素,我们使用同样的方式进行归一化。为了满足这个,我们在一个mini-batch里对所有位置的所有激活元进行联合归一化。在算法1中,我们让
B
\mathcal B
B 是特征图里横跨mini-batch和空间位置的所有值的集合,那么对于
m
m
m 大小的mini-batch和
p
×
q
p\times q
p×q的特征图,我们的有效mini-batch 大小为
m
′
=
∣
B
∣
=
m
⋅
p
q
m'=|\mathcal B| = m\cdot pq
m′=∣B∣=m⋅pq。对于每个特征图,我们学习一组参数
γ
(
k
)
,
β
(
k
)
\gamma^{(k)},\beta^{(k)}
γ(k),β(k) ,而不是对于每个激活元。算法2也进行相应的修改,这样在infer的时候,BN变换同样对于给定的特征图的每一个激活元施加相同的线性变换。
3.3 Batch Normalization enables higher learning rates
在传统的深度网络中,太高的学习率会导致梯度的爆炸或弥散,同时还会使系统困在一个糟糕的局部最优点。BN帮助解决了这个问题。通过对网络的激活元进行归一化,它防止了参数小的变化被放大以及梯度过程中的激活元的次优变化;比如,它防止了训练被困在非线性的饱和区域。
BN同时让训练对于参数的尺度变化的韧性更高。一般来说,大的学习率会增加网络层参数的尺寸,这会进而增大反传的梯度,导致模型爆炸。然而,有了BN,反传过程中,BN层不会受到参数尺度的影响。对于标量
a
a
a,
BN
(
W
u
)
=
BN
(
(
a
W
)
u
)
\text{BN}(W\text u)=\text{BN}((aW)\text u)
BN(Wu)=BN((aW)u)
我们可以发现
∂
BN
(
(
a
W
)
u
)
∂
u
=
∂
BN
(
W
u
)
∂
u
∂
BN
(
(
a
W
)
u
)
∂
(
a
W
)
=
1
a
⋅
∂
BN
(
W
u
)
∂
W
\begin{aligned} \frac{\partial \text{BN}((a W)\text u)}{\partial \text u}=\frac{\partial \text{BN}(W\text u)}{\partial \text u} \\ \frac{\partial \text{BN}((a W)\text u)}{\partial (aW)}=\frac{1}{a} \cdot \frac{\partial\text{BN}(W\text u)}{\partial W} \end{aligned}
∂u∂BN((aW)u)=∂u∂BN(Wu)∂(aW)∂BN((aW)u)=a1⋅∂W∂BN(Wu)
缩放并不影响网络层的雅克比行列式,也不影响反传的梯度。而且,越大的权重会导致越小的梯度,BN会稳定参数的增长。
3.4 Batch Normalization regularizes the model
当使用BN进行训练时,一个训练样本会和mini-batch里其他样本一起被使用,那么对于给定的训练样本,网络将不再产生固定的值。在实验中,我们发现BN对网络泛化有一定的效果。