1 深度神经网络中为什么要进行数据标准化
我以前的一篇博文《给深层网络做参数初始化的门道及其原理》中分析了深度神经网络隐层数据逐层增大的原因。文中通过公式推导,证明了隐层数据的标准差逐层增大 n \sqrt{n} n倍。同时还论证了当隐层数据尺度波动很大时,权值变量的梯度也会随之有很大的波动,从而使得训练过程中可能导致梯度爆炸或消失。起初,研究人员用精心设计的初始化方法来解决这个问题,随后研究人员用数据标准化的方法来控制隐层数据尺度的变化。
2 直观理解批标准化(Batch Normalization)
- 批标准化的提出背景
我们知道神经网络在前向传播中,前一层参数的变化会可能导致输出数据分布的改变,即数据的尺度可能增大或减小了。于是,就会导致权值参数梯度爆炸或消失,从而使得模型很难训练。为了解决这个问题,Loffe[1]等人员提出了批标准化。按字面理解,批是指一批数据,通常为mini-batch。标准化是指将数据的分布变换为均值为0、方差为1的同类型分布。
- 批标准化的具体实现
现假设输入数据只有两个维度:batch_size和feature_size,mini-batch=4,即{ x 1 \ x_{1} x1, x 2 \ x_{2} x2, x 3 \ x_{3} x3, x 4 \ x_{4} x4},每个样本包含4个特征,如图-1所示。
现在对这批数据进行标准化操作,也就是先对这批样本在特征这个维度求均值和标准差,然后将样本的每个特征值减去均值,再除以标准差。以第一个特征为例,求解过程如下所示。
(1) 求均值:
m
e
a
n
=
1.2
+
1.8
+
1.5
+
1.3
4
=
1.45
mean=\frac{1.2+1.8+1.5+1.3}{4} =1.45
mean=41.2+1.8+1.5+1.3=1.45
(2) 求标准差:
s
t
d
=
(
1.2
−
1.45
)
2
+
(
1.8
−
1.45
)
2
+
(
1.5
−
1.45
)
2
+
(
1.3
−
1.45
)
2
4
=
0.23
std=\sqrt{\frac{(1.2-1.45)^{2}+(1.8-1.45)^{2}+(1.5-1.45)^{2}+(1.3-1.45)^{2}}{4}}=0.23
std=4(1.2−1.45)2+(1.8−1.45)2+(1.5−1.45)2+(1.3−1.45)2=0.23
(3) 特征值标准化
a 1 1 ^ = 1.2 − 1.45 0.23 = − 1.09 \hat {a_{1}^{1}} =\frac{1.2-1.45}{0.23}=-1.09 a11^=0.231.2−1.45=−1.09
a 2 1 ^ = 1.8 − 1.45 0.23 = 1.52 \hat {a_{2}^{1}} =\frac{1.8-1.45}{0.23}=1.52 a21^=0.231.8−1.45=1.52
a 3 1 ^ = 1.5 − 1.45 0.23 = 0.22 \hat {a_{3}^{1}} =\frac{1.5-1.45}{0.23}=0.22 a31^=0.231.5−1.45=0.22
a 4 1 ^ = 1.3 − 1.45 0.23 = − 0.65 \hat {a_{4}^{1}} =\frac{1.3-1.45}{0.23}=-0.65 a41^=0.231.3−1.45=−0.65
a a a的上标为特征编号,下标为样本编号。标准化后,还要对 a 1 ^ \hat {a^{1}} a1^进行Affine Transform操作,也就是进行如下操作,
b 1 ^ ← γ 1 × a 1 ^ + β 1 \hat {b^{1}} \gets \gamma^{1} \times \hat {a^{1}}+\beta^{1} b1^←γ1×a1^+β1
其中, γ \gamma γ, β \beta β是可学习参数。这里,批样本中的同一特征共享 γ \gamma γ, β \beta β.
- 批标准化的形式化表示
对上述实例进一步抽象,批标准化可形式化表示为以下四步。
1) 求均值
2) 求方差
3) 标准化
其中,
ϵ
\epsilon
ϵ为分母修正项,是一个很小的正数,防止分母为0.
4) Affine Transform
- pytorch中的批标准化类
pytorch有三个实现批标准化的类,分别为BatchNorm1d、BatchNorm2d和BatchNorm3d。这三个类分别对应一维特征、二维特征和三维特征的标准化。它们的主要功能都是实现上述四步操作,不过,这里有一个细节需要注意。以BatchNorm1d为例,如下图所示。
上图中有一个momentum参数,这个参数是在估计当前时刻mini-batch的均值和方差时用到。假设上一时刻mini-batch的均值、方差的估计分别为
m
^
t
−
1
\hat m_{t-1}
m^t−1,
v
^
t
−
1
\hat v_{t-1}
v^t−1,当前时刻mini-batch计算得到的均值、方差分别为
m
t
m_{t}
mt,
v
t
v_{t}
vt,则当前时刻mini-batch的均值
m
^
t
\hat m_{t}
m^t、方差
v
^
t
\hat v_{t}
v^t的估计可用如下公式表示:
m ^ t = ( 1 − m o m e n t u m ) × m ^ t − 1 + m o m e n t u m × m t \hat m_{t}=(1-momentum) \times\hat m_{t-1}+momentum \times m_{t} m^t=(1−momentum)×m^t−1+momentum×mt
v
^
t
=
(
1
−
m
o
m
e
n
t
u
m
)
×
v
^
t
−
1
+
m
o
m
e
n
t
u
m
×
v
t
\hat v_{t}=(1-momentum) \times\hat v_{t-1}+momentum \times v_{t}
v^t=(1−momentum)×v^t−1+momentum×vt
3 直观理解层标准化(Layer Normalization)
- 层标准化的提出背景
在有些任务中,各样本包含的特征个数并不相同。例如,自然语言处理任务中,每个句子所包含的单词个数并不相同,如图-2所示。
图-2中,三个样本所包含的特征个数不同,也就无法在特征这个维度上求取均值和方差。针对这个问题,有研究人员提出了层标准化(Layer Normalization)方法。
层标准化,顾名思义就是对层内所有神经元进行标准化,也就是对层中的所有神经元求取均值和方差。由于样本所包含的特征数是动态变化的,所以层中活跃的神经元个数也是动态变化的。以三个样本为例,层标准化求取均值和方差的示意图如图-3所示。
- 层标准化与批标准化的区别
层标准化的计算步骤和批标准化基本相同,也是先求均值、方差,再进行标准化,最后再进行Affine Transform。但是,由上述可知,层标准化求均值和方差的方式与批标准化不同。层标准化是在层中所有神经元范围内求均值和方差,而批标准化是在一批样本的特征维度上求均值和方差。
由于二者求取均值和方差的维度不同,所以Affine Transform中的 γ \gamma γ和 β \beta β的设置也不同。在批标准化中,同一特征共享 γ \gamma γ和 β \beta β,而层标准化中,每个神经元均有自己的 γ \gamma γ和 β \beta β.
- 如何根据实际任务选择标准化方法
在实际任务中,如果样本所包含的特征个数相同,则优先选择批标准化,但是mini-batch样本数量不宜过小。如果样本所包含的特征个数是动态变化的,或者由于模型太大而gpu内存空间又不够,从而只能设置很小的mini-batch时,那就采用层标准化。
4 标准化后的数据是否还具有原数据的特质
上面批标准化、层标准化折腾了半天,这里还有个疑问:数据经过标准化后,是否还有保留原数据的特质?我们知道,模型学习的本质是学习数据样本的分布。那么标准化后的数据是否会改变原数据的分布?
对于这个问题,我们来对标准化公式做个简单的分析,看看能否找到答案。
标准化公式:
X
n
e
w
=
X
i
−
μ
δ
X_{new}=\frac{X_{i}-\mu }{\delta }
Xnew=δXi−μ
上式可变换为,
X
n
e
w
=
X
i
δ
−
μ
δ
X_{new}=\frac{X_{i} }{\delta }-\frac{\mu}{\delta}
Xnew=δXi−δμ
令
c
=
μ
δ
c=\frac{\mu}{\delta}
c=δμ,则有
X
n
e
w
=
X
i
δ
−
c
X_{new}=\frac{X_{i} }{\delta }-c
Xnew=δXi−c
从上式可以看出,标准化的过程是先对原数据做缩放,再做平移。而训练数据给定后,
δ
\delta
δ和
c
c
c都为常数。我们知道,数据以相同尺度缩放和平移,不会改变数据原有的顺序。也就是说,标准化后数据的分布类型与原数据的分布类型是一样的,只是均值和方差不同。即,标准化后,要给模型学习的本质东西没有丢失。
[参考文献]
[1] Ioffe S, Szegedy C. Batch normalization: Accelerating deep network training by reducing internal covariate shift[C]//International conference on machine learning. PMLR, 2015: 448-456.