梯度消失
神经网络通过反向传播来训练参数,当神经网络得层数很深的时候,如果使用 s i g m o d sigmod sigmod 函数或者 t a n h tanh tanh 函数作为激活函数,因为每次的梯度都小于1,对应权重的梯度会变得原来越小,反向传播到靠近输入层时,梯度会变得非常小,也就难以对靠前的神经网络层进行更新,这个现象称为梯度消失(Gradient vanishing problem)。
我第一次看梯度消失的时候想了半天哈哈哈哈,还是总结一下,看一看具体发生了什么事情导致了梯度消失。
假设我们的神经网络大概长这样,激活函数选择sigmoid函数:
假设每一层只有一个神经元,在每一层中 a i = σ ( h i ) = σ ( w i a i − 1 + b i ) a_i = \sigma(h_i) = \sigma(w_ia_{i-1}+b_i) ai=σ(hi)=σ(wiai−1+bi) 。
记损失函数为 L L L, 如果我们想要更新参数 w 1 w1 w1 , 需要通过求出 L 对 w1 的梯度对其进行更新:
w
1
′
=
w
1
−
η
∂
L
∂
w
1
w_1^{'}= w_1 - \eta \frac{\partial L}{\partial w_1}
w1′=w1−η∂w1∂L
∂
L
∂
w
1
=
∂
L
∂
a
3
∂
a
3
∂
a
2
∂
a
2
∂
a
1
∂
a
1
∂
w
1
(1)
\frac{\partial L}{\partial w_1} = \frac{\partial L}{\partial a_3}\frac{\partial a_3}{\partial a_2}\frac{\partial a_2}{\partial a_1}\frac{\partial a_1}{\partial w_1} \tag{1}
∂w1∂L=∂a3∂L∂a2∂a3∂a1∂a2∂w1∂a1(1)
其中:
a
3
=
σ
(
h
3
)
=
σ
(
w
3
a
2
+
b
3
)
∂
a
3
∂
a
2
=
∂
a
3
∂
h
3
∂
h
3
∂
a
2
=
σ
′
(
h
3
)
w
3
a_3 = \sigma(h_3) = \sigma(w_3a_2+b_3)\\ \frac{\partial a_3}{\partial a_2} = \frac{\partial a_3}{\partial h_3}\frac{\partial h_3}{\partial a_2} = \sigma^{'}(h_3)w_3
a3=σ(h3)=σ(w3a2+b3)∂a2∂a3=∂h3∂a3∂a2∂h3=σ′(h3)w3
因此
(
1
)
(1)
(1) 式可以写作成
∂
L
∂
w
1
=
∂
L
∂
a
3
σ
′
(
h
3
)
w
3
σ
′
(
h
2
)
w
2
σ
′
(
h
1
)
x
\frac{\partial L}{\partial w_1} = \frac{\partial L}{\partial a_3}\sigma^{'}(h_3)w_3\sigma^{'}(h_2)w_2\sigma^{'}(h_1)x
∂w1∂L=∂a3∂Lσ′(h3)w3σ′(h2)w2σ′(h1)x
σ ′ ( h 3 ) \sigma^{'}(h_3) σ′(h3) 和 σ ′ ( h 2 ) \sigma^{'}(h_2) σ′(h2)为sigmoid函数的导数在 h 3 , h 2 h_3, h_2 h3,h2 处的值,sigmod函数的导数如图所示:
import matplotlib.pyplot as plt
import numpy as np
def sigmoid(x):
return 1/(1+np.exp(-x))
def d_sigmoid(x):
return sigmoid(x)*(1-sigmoid(x))
x=np.arange(-5,5,0.01)
plt.grid()
plt.plot(sigmoid(x),label='sigmoid(x)',color='blue')
plt.plot(d_sigmoid(x),label='derivative',color='red')
plt.legend(loc='upper right')
sigmoid函数的导数范围都在 ( 0 , 0.25 ] (0 , 0.25] (0,0.25] 以内,可以看到随着网络层数越来越深,类似 ∂ L ∂ w 1 \frac{\partial L}{\partial w_1} ∂w1∂L 这样靠前的参数梯度会变得很小。这就导致了梯度消失现象的出现。
梯度爆炸
梯度消失是由于 σ ′ ( h 3 ) w 3 < 1 \sigma^{'}(h_3)w_3<1 σ′(h3)w3<1 导致的,但假如权重一开始的取值比较大,造成 σ ′ ( h 3 ) w 3 > 1 \sigma^{'}(h_3)w_3>1 σ′(h3)w3>1 就会使前几层的梯度变得非常大,这就是梯度爆炸(Gradient exploding problem)的原因。
因此,为了避免权重过大导致的梯度爆炸,权重的初始化就显得非常重要。
如有错误,欢迎批评指正。