一、数值稳定性
由于链式法则的存在,在神经网络中进行反向传播时,深层的神经网络会使得梯度值在反向传播时出现梯度爆炸或梯度消失的问题。
以多层感知机为例,对于隐藏层
h
t
h^t
ht,存在激活函数
σ
\sigma
σ,该层的输入为
h
t
−
1
h^{t-1}
ht−1满足如下:
h
t
=
f
t
(
h
t
−
1
)
=
σ
(
W
t
h
t
−
1
)
h^t=f_t(h^{t-1})=\sigma(W^th^{t-1})
ht=ft(ht−1)=σ(Wtht−1)
对上述进行求导,
σ
\sigma
σ激活函数求导后,对所得向量对角化,变为对角矩阵:
∂
h
t
∂
h
t
−
1
=
d
i
a
g
(
σ
′
(
W
t
h
t
−
1
)
)
W
t
\frac{\partial h^t}{\partial h^{t-1}}=diag(\sigma'(W^th^{t-1}))W^t
∂ht−1∂ht=diag(σ′(Wtht−1))Wt
假设 h t h^t ht为 n n n维向量, h t − 1 h^{t-1} ht−1为 m m m维向量,则权重矩阵 W t W^t Wt维度必须为 ( n ∗ m ) (n*m) (n∗m)
h t h^t ht对 h t − 1 h^{t-1} ht−1求导,采用分子布局,所得结果应该为 n ∗ m n*m n∗m维矩阵(雅可比矩阵)
又因为 W t W^t Wt为 n ∗ m n*m n∗m维矩阵, W t ⋅ h t − 1 W^t \cdot h^{t-1} Wt⋅ht−1为 n n n维向量,为了使得结果满足 n ∗ m n*m n∗m维矩阵
因此需要对向量 W t ⋅ h t − 1 W^t \cdot h^{t-1} Wt⋅ht−1进行对角化,转为 n ∗ n n*n n∗n维对角矩阵,即 ( n ∗ n ) ∗ ( n ∗ m ) = ( n ∗ m ) (n*n)*(n*m)=(n*m) (n∗n)∗(n∗m)=(n∗m)
在整个反向传播过程中,会出现梯度累乘:
∏
i
=
t
d
−
1
∂
h
i
+
1
∂
h
i
=
∏
i
=
t
d
−
1
d
i
a
g
(
σ
′
(
W
i
h
i
−
1
)
)
W
i
\prod_{i=t}^{d-1}\frac{\partial h^{i+1}}{\partial h^i}=\prod_{i=t}^{d-1}diag(\sigma'(W^ih^{i-1}))W^i
∏i=td−1∂hi∂hi+1=∏i=td−1diag(σ′(Wihi−1))Wi
若使用ReLU做激活函数,当
x
>
0
x>0
x>0时,梯度为
1
1
1,否则梯度为
0
0
0。此时对角矩阵内为
1
1
1或
0
0
0,此时
∏
i
=
t
d
−
1
∂
h
i
+
1
∂
h
i
\prod_{i=t}^{d-1}\frac{\partial h^{i+1}}{\partial h^i}
∏i=td−1∂hi∂hi+1中的部分值会来自
∏
i
=
t
d
−
1
W
i
\prod_{i=t}^{d-1}W^i
∏i=td−1Wi,另一些值为
0
0
0,此时当网络比较深的时候,若
W
i
>
1
W^i>1
Wi>1,累乘后靠近输入层的梯度值会变得非常大,出现梯度爆炸现象。
梯度爆炸的存在,会使得:
- 梯度值超出值域,尤其是对于16位浮点数,其值域仅为(6e-5,6e4),很容易因梯度爆炸发生越界
- 导致网络不稳定,最好的结果是无法从训练数据中收敛,最坏的结果是由于权重值为NaN而无法更新权重。
梯度值对学习率很敏感:
- 学习率太大,会带来很大的权重参数,从而在反向传播时带来更大的梯度,如此循环往复,很容易导致梯度爆炸
- 学习率太小,会使得模型在训练时的收敛非常缓慢,导致训练无进展
- 可以在训练时,动态的调整学习率。
与梯度爆炸原理相同,在反向传播过程中,若梯度值小于
1
1
1,在不断的累乘过程中会使得梯度信息随层数增加不断衰减,最终出现梯度消失现象,以Sigmoid激活函数为例:
σ
(
x
)
=
1
1
+
e
−
x
σ
′
(
x
)
=
σ
(
x
)
(
1
−
σ
(
x
)
)
\sigma(x)=\frac{1}{1+e^{-x}} \quad \sigma'(x)=\sigma(x)(1-\sigma(x))
σ(x)=1+e−x1σ′(x)=σ(x)(1−σ(x))
从上图可以看出,
x
x
x值稍大或稍小时,激活函数的梯度趋近于
0
0
0,多次累乘后,出现梯度消失现象。
对于16位浮点数,很小的浮点值,例如
5
e
−
4
5e^{-4}
5e−4,基本可以当作
0
0
0来看待,很容易出现梯度消失现象。
梯度消失现象的存在,会使得:
- 训练无进展,不论如何设计学习率,梯度为0时,乘上学习率都为0,导致训练无进展。
- 对深层网络的底部层(接近输入层)处尤为严重,使得神经网络与浅层无异,无法更深。
总结: 梯度爆炸/消失通常由模型层数过深或激活函数选择不当所导致,应尽量避免梯度过大或者过小。
二、模型初始化与激活函数
训练时的梯度爆炸和梯度消失问题都会导致模型训练不稳定,解决该问题的目标是使得模型的梯度在训练时一直保持在合理范围内,为此可以采用以下几种方法:
- 乘法变加法:修改模型结构,采用ResNet或者LSTM等模型
- 归一化:对梯度进行裁剪,或者归一化处理
- 设置合理的权重初始化以及激活函数
本节内容主要针对第三点进行展开,理想状态下,我们希望模型每层的输出和梯度都是一个随机变量,其均值和方差保持一致,并均为常数:
在这种情况下,模型不管加多深,我们都可以认为,其每一层的输出和梯度,均值为0,方差为一个固定常数项。从而避免梯度爆炸或梯度消失现象。
权重初始化
之前所采用的均值为0,方差为0.01的正态分布
N
(
0
,
0.01
)
N(0,0.01)
N(0,0.01)对权重进行初始化的方法,针对多层感知机等小型神经网络可能没太多问题,但并不适用于深度神经网络。
我们希望在初始化时可以在合理的区间内随机初始参数,因为在训练开始时,很容易出现数值不稳定的现象,尤其是当初始化的参数远离最优解时,为了使得下降更快,梯度值会变得非常大,导致在训练更新时可能出现梯度爆炸的现象;而在最优解附近时,梯度下降缓慢,可能会在更新时梯度变成0,出现梯度消失现象。
以多层感知机为例:
假设权重
w
i
,
j
t
w_{i,j}^t
wi,jt满足独立同分布,其期望满足
E
[
w
i
,
j
t
]
=
0
\mathbb E [w_{i,j}^t]=0
E[wi,jt]=0,方差
V
a
r
[
w
i
,
j
t
]
=
γ
t
Var[w_{i,j}^t]=\gamma_t
Var[wi,jt]=γt,
h
i
t
−
1
h_i^{t-1}
hit−1与
w
i
,
j
t
w_{i,j}^t
wi,jt独立。
当不存在激活函数时,满足
h
t
=
W
t
h
t
−
1
h^t=W^th^{t-1}
ht=Wtht−1,其正向输出的均值与方差为:
E
[
h
i
t
]
=
E
[
∑
j
w
i
,
j
t
h
j
t
−
1
]
=
∑
j
E
[
w
i
,
j
t
]
E
[
h
j
t
−
1
]
=
0
\mathbb E[h^t_i]=\mathbb E\Bigg[\sum_jw_{i,j}^th_j^{t-1}\Bigg]=\sum_j \mathbb E[w^t_{i,j}]\mathbb E[h_j^{t-1}]=0
E[hit]=E[∑jwi,jthjt−1]=∑jE[wi,jt]E[hjt−1]=0
V
a
r
[
h
i
t
]
=
E
[
(
h
i
t
)
2
]
−
E
[
h
i
t
]
2
=
E
[
(
∑
j
w
i
,
j
t
h
j
t
−
1
)
2
]
=
∑
j
V
a
r
[
w
i
,
j
t
]
V
a
r
[
h
j
t
−
1
]
=
n
t
−
1
γ
t
V
a
r
[
h
j
t
−
1
]
Var[h^t_i]=\mathbb E[(h_i^t)^2]-\mathbb E[h_i^t]^2 = \mathbb E \Bigg[\Bigg(\sum_jw_{i,j}^th^{t-1}_j \Bigg)^2 \Bigg]=\sum_jVar[w^t_{i,j}]Var[h_j^{t-1}]=n_{t-1}\gamma_tVar[h_j^{t-1}]
Var[hit]=E[(hit)2]−E[hit]2=E[(∑jwi,jthjt−1)2]=∑jVar[wi,jt]Var[hjt−1]=nt−1γtVar[hjt−1]
当满足
n
t
−
1
γ
t
=
1
n_{t-1}\gamma_t=1
nt−1γt=1时,输入与输出的方差相等。
反向传播的梯度均值与方差与正向传播类似,满足
E
[
∂
l
∂
h
i
t
−
1
]
=
0
V
a
r
[
∂
l
∂
h
j
t
−
1
]
=
n
y
γ
t
V
a
r
[
∂
l
∂
h
j
t
]
\mathbb E\Bigg[\frac{\partial l}{\partial h_i^{t-1}}\Bigg]=0 \qquad Var \Bigg[\frac{\partial l}{\partial h_j^{t-1}}\Bigg]=n_y\gamma_t Var\Bigg[\frac{\partial l}{\partial h_j^t}\Bigg]
E[∂hit−1∂l]=0Var[∂hjt−1∂l]=nyγtVar[∂hjt∂l]
同样当满足
n
t
γ
t
=
1
n_t\gamma_t=1
ntγt=1时,前后梯度方差相等。
综上,为了满足前向输出和反向梯度的期望与方差均满足上述假设,需要满足
n
t
−
1
γ
t
=
1
n_{t-1}\gamma_t=1
nt−1γt=1和
n
t
γ
t
=
1
n_t\gamma_t=1
ntγt=1,这两个条件很难同时满足,因为我们无法控制
n
t
n_t
nt与
n
t
−
1
n_{t-1}
nt−1。
为此我们采用Xavier初始化方法,使得
γ
t
(
n
t
−
1
+
n
t
)
/
2
=
1
→
γ
t
=
2
/
(
n
t
−
1
+
n
t
)
\gamma_t(n_{t-1}+n_t)/2=1 \rightarrow \gamma_t=2/(n_{t-1}+n_t)
γt(nt−1+nt)/2=1→γt=2/(nt−1+nt),此时可采用下述分布进行初始化:
- 正态分布: N ( 0 , 2 / ( n t − 1 + n t ) ) N\bigg(0,\sqrt {2/(n_{t-1}+n_t)}\bigg) N(0,2/(nt−1+nt))
- 均匀分布: U ( − 6 / ( n t − 1 + n t ) , 6 / ( n t − 1 + n t ) ) U\bigg(-\sqrt{6/(n_{t-1}+n_t)},\sqrt{6/(n_{t-1}+n_t)}\bigg) U(−6/(nt−1+nt),6/(nt−1+nt)),均匀分布 U [ − a , a ] U[-a,a] U[−a,a]的方差为 a 2 / 3 a^2/3 a2/3
对于激活函数
σ
(
x
)
=
α
x
+
β
\sigma(x)=\alpha x+\beta
σ(x)=αx+β,存在
h
′
=
W
t
h
t
−
1
,
h
t
=
σ
(
h
′
)
h'=W^th^{t-1},h^t=\sigma(h')
h′=Wtht−1,ht=σ(h′),满足输入输出不变时,存在:
E
[
h
i
t
]
=
E
[
α
h
t
′
+
β
]
=
β
→
β
=
0
\mathbb E[h^t_i]=\mathbb E[\alpha h'_t+\beta]=\beta \rightarrow \beta=0
E[hit]=E[αht′+β]=β→β=0
V
a
r
[
h
i
t
]
=
a
2
V
a
r
[
h
i
′
]
→
α
=
1
Var[h_i^t]=a^2Var[h'_i] \rightarrow \alpha=1
Var[hit]=a2Var[hi′]→α=1
反向同理,因此在采用激活函数时,若想满足期望方差不变,必须满足
α
=
1
,
β
=
0
\alpha=1,\beta=0
α=1,β=0,即激活函数等于变量本身,满足
σ
(
x
)
=
x
\sigma(x)=x
σ(x)=x。
总结: 越拟合
f
(
x
)
=
x
f(x)=x
f(x)=x的激活函数效果越好,可以对Sigmoid激活函数改为
4
×
s
i
g
m
o
i
d
(
x
)
−
2
4 \times sigmoid(x)-2
4×sigmoid(x)−2,效果要比原始Sigmoid函数好很多。
ReLU激活函数的泰勒展开为
r
e
l
u
(
x
)
=
0
+
x
f
o
r
x
≥
0
relu(x)=0+x \quad for \ x \geq 0
relu(x)=0+xfor x≥0,因此现在常采用ReLU作为激活函数。