一.神经网络如何传播?
1.1 正向传播
如下图所示,两个输入值
X
1
X_1
X1和
X
2
X_2
X2,以第一层的第一个神经元
f
1
(
e
)
f_1(e)
f1(e)为例。
正向传播先经过线性变换
e
=
x
1
w
1
+
x
2
w
2
e=x_1w_1+x_2w_2
e=x1w1+x2w2,再经过一个激励函数
f
f
f(不知道什么是激励函数的同学可自行查看),最终获得输出值
y
y
y。同时
y
y
y作为下一层的输入值继续相同操作。
在这里我们可以抽象的将神经元表示为net和out两部分组成,net表示线性变换得到的值
e
=
x
1
w
1
+
x
2
w
2
e=x_1w_1+x_2w_2
e=x1w1+x2w2,out表示经过激励函数后得到的值
y
=
f
(
e
)
y=f(e)
y=f(e)。
在正向传播过程中,输入信息通过输入层经隐含层,逐层处理并传向输出层。如果在输出层得不到期望的输出值,则取输出与期望的误差的平方和作为目标函数,转入反向传播,逐层求出目标函数对各神经元权值的偏导数,构成目标函数对权值向量的梯量,作为修改权值的依据,网络的学习在权值修改过程中完成。误差达到所期望值时,网络学习结束。
计算得出的输出y和训练集和的真实结果z有一定的误差,这个误差就叫做误差信号。用误差信号反向传递给前面的各层,来调整网络参数。如下图所示:
1.2 反向传播
为了方便理解反向传播,假设我们有3层的网络,并且全部是一层, 选取sigmoid为激活函数
反向传播的最终目标是根据误差值不断修改 W i W_i Wi的值,让最终的输出值接近于我们预期值。
-
更新 W 3 W_3 W3的值 :
根据上文中提到的,我们可以把一个神经元分成 n e t net net和 o u t out out两部分,所以Output可以分成 n e t O net_O netO和 o u t O out_O outO两部分。要想知道如何更新 W 3 W_3 W3的值,就要知道 W 3 W_3 W3对总误差值 E t o t a l E_{total} Etotal做了多少贡献,也就是说1单位 W 3 W_3 W3的变化会引起多少单位 E t o t a l E_{total} Etotal的变化,即 ∂ E t o t a l ∂ W 3 \frac{\partial E_{total}}{\partial W_3} ∂W3∂Etotal。 根据链式法则,我们 W 3 W_3 W3的变化会引起 n e t O net_O netO的变化,而 n e t O net_O netO的变化会引起 o u t O out_O outO的变化,最终 o u t O out_O outO的变化才会引起 E t o t a l E_{total} Etotal的变化,所以我们可以将这一连串变化表示成公式: ∂ n e t O ∂ W 3 ∗ ∂ o u t O ∂ n e t O ∗ ∂ E t o t a l ∂ o u t O = ∂ E t o t a l ∂ W 3 \frac{\partial net_O}{{\partial W_3}} * \frac{\partial out_O}{{\partial net_O}} * \frac{\partial E_{total}}{{\partial out_O}} = \frac{\partial E_{total}}{{\partial W_3}} ∂W3∂netO∗∂netO∂outO∗∂outO∂Etotal=∂W3∂Etotal
W 3 + = W 3 − η ∗ ∂ E t o t a l ∂ W 3 W_3^+ = W_3 - \eta*\frac{\partial E_{total}}{{\partial W_3}} W3+=W3−η∗∂W3∂Etotal
其中, η \eta η是学习效率 -
更新 W 2 W_2 W2和 W 1 W_1 W1的值:
2.1 更新 W 2 W_2 W2: ∂ n e t 2 ∂ W 2 ∗ ∂ o u t 2 ∂ n e t 2 ∗ ∂ n e t O ∂ o u t 2 ∗ ∂ o u t O ∂ n e t O ∗ ∂ E t o t a l ∂ o u t O = ∂ E t o t a l ∂ W 2 \frac{\partial net_2}{{\partial W_2}} * \frac{\partial out_2}{{\partial net_2}} * \frac{\partial net_O}{{\partial out_2}} * \frac{\partial out_O}{{\partial net_O}} * \frac{\partial E_{total}}{{\partial out_O}} = \frac{\partial E_{total}}{{\partial W_2}} ∂W2∂net2∗∂net2∂out2∗∂out2∂netO∗∂netO∂outO∗∂outO∂Etotal=∂W2∂Etotal
W 2 + = W 2 − η ∗ ∂ E t o t a l ∂ W 2 W_2^+ = W_2 - \eta*\frac{\partial E_{total}}{{\partial W_2}} W2+=W2−η∗∂W2∂Etotal
2.2 更新
W
1
W_1
W1:
∂
n
e
t
1
∂
X
1
∗
∂
o
u
t
1
∂
n
e
t
1
∗
∂
n
e
t
2
∂
o
u
t
1
∗
∂
o
u
t
2
∂
n
e
t
2
∗
∂
n
e
t
O
∂
o
u
t
2
∗
∂
o
u
t
O
∂
n
e
t
O
∗
∂
E
t
o
t
a
l
∂
o
u
t
O
=
∂
E
t
o
t
a
l
∂
W
1
\frac{\partial net_1}{{\partial X_1}} * \frac{\partial out_1}{{\partial net_1}}*\frac{\partial net_2}{{\partial out_1}} *\frac{\partial out_2}{{\partial net_2}} * \frac{\partial net_O}{{\partial out_2}} * \frac{\partial out_O}{{\partial net_O}} * \frac{\partial E_{total}}{{\partial out_O}} = \frac{\partial E_{total}}{{\partial W_1}}
∂X1∂net1∗∂net1∂out1∗∂out1∂net2∗∂net2∂out2∗∂out2∂netO∗∂netO∂outO∗∂outO∂Etotal=∂W1∂Etotal
W
1
+
=
W
1
−
η
∗
∂
E
t
o
t
a
l
∂
W
1
W_1^+ = W_1 - \eta*\frac{\partial E_{total}}{{\partial W_1}}
W1+=W1−η∗∂W1∂Etotal
二.梯度消失如何产生?
2.1 数学角度
-
o
u
t
i
=
s
i
g
m
o
i
d
(
n
e
t
i
)
=
1
1
+
e
−
n
e
t
o
out_i = sigmoid(net_i) = \frac{1}{1+ e^{-net_o}}
outi=sigmoid(neti)=1+e−neto1
例如: o u t 2 = s i g m o i d ( n e t 2 ) = 1 1 + e − n e t 2 out_2 = sigmoid(net_2)=\frac{1}{1+ e^{-net_2}} out2=sigmoid(net2)=1+e−net21,相当于 o u t 2 out_2 out2 是由 n e t 2 net_2 net2通过sigmoid激活函数后得到的。 -
n
e
t
i
=
o
u
t
i
−
1
∗
W
i
−
1
net_i = out_{i-1} * W_{i-1}
neti=outi−1∗Wi−1
例如: n e t 2 = o u t 1 ∗ W 1 net_2 = out1 * W_1 net2=out1∗W1,相当于 n e t 2 net_2 net2 是由上一层经过激活函数输出的值 o u t 1 out_1 out1与权值 W 1 W_1 W1相乘得来的。
因此,对sigmoid函数求导可得:
∂
o
u
t
i
∂
n
e
t
i
=
o
u
t
i
∗
(
1
−
o
u
t
i
)
\frac {\partial out_i}{\partial net_i}= out_i *(1-out_i)
∂neti∂outi=outi∗(1−outi)
同理,对
n
e
t
i
=
o
u
t
i
−
1
∗
W
i
−
1
net_i = out_{i-1} * W_{i-1}
neti=outi−1∗Wi−1求导可得:
∂
n
e
t
i
∂
o
u
t
i
−
1
=
W
i
−
1
\frac {\partial net_i}{\partial out_{i-1}}= W_{i-1}
∂outi−1∂neti=Wi−1
其中,
i
−
1
i-1
i−1是上一层的意思。
同理,
∂
E
t
o
t
a
l
∂
o
u
t
O
=
−
1
2
∗
(
t
a
r
g
e
t
−
o
u
t
o
)
\frac{\partial E_{total}}{{\partial out_O}}= - \frac{1}{2}*(target - out_o)
∂outO∂Etotal=−21∗(target−outo)
其中,target表示最后结果期望的值, 下文中我们把该结果用X表示,因为这是一个常数。
所以可以将上文中更新
W
1
W_1
W1的公式简化为:
W
1
∗
o
u
t
1
∗
(
1
−
o
u
t
1
)
∗
W
2
∗
o
u
t
2
∗
(
1
−
o
u
t
2
)
∗
W
3
∗
o
u
t
3
∗
(
1
−
o
u
t
3
)
∗
−
X
W_1 * out_1*(1-out_1) * W_2 * out_2*(1-out_2) * W_3 * out_3*(1-out_3)*- X
W1∗out1∗(1−out1)∗W2∗out2∗(1−out2)∗W3∗out3∗(1−out3)∗−X
我们把结果分成两部分:
W部分:
W
1
∗
W
2
∗
W
3
W_1*W_2*W_3
W1∗W2∗W3
o
u
t
i
out_i
outi部分:
o
u
t
1
∗
(
1
−
o
u
t
1
)
∗
o
u
t
2
∗
(
1
−
o
u
t
2
)
∗
o
u
t
3
∗
(
1
−
o
u
t
3
)
out_1*(1-out_1) *out_2*(1-out_2) *out_3*(1-out_3)
out1∗(1−out1)∗out2∗(1−out2)∗out3∗(1−out3)
然而,sigmoid函数是[0,1]的函数,如果多次相乘很快 η ∗ ∂ E t o t a l ∂ W 1 \eta*\frac{\partial E_{total}}{{\partial W_1}} η∗∂W1∂Etotal就会变成一个很小很小的数字,也就是对于这个公式 W 1 + = W 1 − η ∗ ∂ E t o t a l ∂ W 1 W_1^+ = W_1 - \eta*\frac{\partial E_{total}}{{\partial W_1}} W1+=W1−η∗∂W1∂Etotal每次减去的数字越来越小,趋近于0。导致更新速率越来越慢,接近无法更新W,导致无法完成神经网络的训练。
2.2 激活函数角度
其实也注意到了,上文中提到计算权值更新信息的时候需要计算前层偏导信息,因此如果激活函数选择不合适,比如使用sigmoid,梯度消失就会很明显了,原因看下图,左图是sigmoid的损失函数图,右边是其导数的图像,如果使用sigmoid作为损失函数,其梯度是不可能超过0.25的,这样经过链式求导之后,很容易发生梯度消失。
三.结论
sigmoid函数不适合作为复杂神经网络的激活函数,sigmoid函数也不适合用来做反向传播。
但是也有sigmoid函数也有优点:
- 便于求导的平滑函数;
- 能压缩数据,保证数据幅度不会有问题;
- 适合用于前向传播。