一.神经网络如何传播?
1.1 正向传播
如下图所示,两个输入值X1和X2,以第一层的第一个神经元f1(e)为例。
正向传播先经过线性变换e=x1w1+x2w2,再经过一个激励函数f(不知道什么是激励函数的同学可自行查看),最终获得输出值y。同时y作为下一层的输入值继续相同操作。



在这里我们可以抽象的将神经元表示为net和out两部分组成,net表示线性变换得到的值e=x1w1+x2w2,out表示经过激励函数后得到的值y=f(e)。
在正向传播过程中,输入信息通过输入层经隐含层,逐层处理并传向输出层。如果在输出层得不到期望的输出值,则取输出与期望的误差的平方和作为目标函数,转入反向传播,逐层求出目标函数对各神经元权值的偏导数,构成目标函数对权值向量的梯量,作为修改权值的依据,网络的学习在权值修改过程中完成。误差达到所期望值时,网络学习结束。
计算得出的输出y和训练集和的真实结果z有一定的误差,这个误差就叫做误差信号。用误差信号反向传递给前面的各层,来调整网络参数。如下图所示:

1.2 反向传播
为了方便理解反向传播,假设我们有3层的网络,并且全部是一层, 选取sigmoid为**函数

反向传播的最终目标是根据误差值不断修改Wi的值,让最终的输出值接近于我们预期值。
-
更新W3的值 :
根据上文中提到的,我们可以把一个神经元分成net和out两部分,所以Output可以分成netO和outO两部分。要想知道如何更新W3的值,就要知道W3对总误差值Etotal做了多少贡献,也就是说1单位W3的变化会引起多少单位Etotal的变化,即∂W3∂Etotal。 根据链式法则,我们W3的变化会引起netO的变化,而netO的变化会引起outO的变化,最终outO的变化才会引起Etotal的变化,所以我们可以将这一连串变化表示成公式: ∂W3∂netO∗∂netO∂outO∗∂outO∂Etotal=∂W3∂Etotal
W3+=W3−η∗∂W3∂Etotal
其中,η是学习效率
-
更新W2和W1的值:
2.1 更新W2: ∂W2∂net2∗∂net2∂out2∗∂out2∂netO∗∂netO∂outO∗∂outO∂Etotal=∂W2∂Etotal
W2+=W2−η∗∂W2∂Etotal
2.2 更新W1:∂X1∂net1∗∂net1∂out1∗∂out1∂net2∗∂net2∂out2∗∂out2∂netO∗∂netO∂outO∗∂outO∂Etotal=∂W1∂Etotal
W1+=W1−η∗∂W1∂Etotal
二.梯度消失如何产生?
2.1 数学角度
-
outi=sigmoid(neti)=1+e−neto1
例如:out2=sigmoid(net2)=1+e−net21,相当于out2 是由 net2通过sigmoid**函数后得到的。
-
neti=outi−1∗Wi−1
例如:net2=out1∗W1,相当于net2 是由上一层经过**函数输出的值out1与权值W1相乘得来的。
因此,对sigmoid函数求导可得:
∂neti∂outi=outi∗(1−outi)
同理,对neti=outi−1∗Wi−1求导可得:
∂outi−1∂neti=Wi−1
其中,i−1是上一层的意思。
同理,∂outO∂Etotal=−21∗(target−outo)
其中,target表示最后结果期望的值, 下文中我们把该结果用X表示,因为这是一个常数。
所以可以将上文中更新W1的公式简化为:
W1∗out1∗(1−out1)∗W2∗out2∗(1−out2)∗W3∗out3∗(1−out3)∗−X
我们把结果分成两部分:
W部分:W1∗W2∗W3
outi部分: out1∗(1−out1)∗out2∗(1−out2)∗out3∗(1−out3)
然而,sigmoid函数是[0,1]的函数,如果多次相乘很快η∗∂W1∂Etotal就会变成一个很小很小的数字,也就是对于这个公式W1+=W1−η∗∂W1∂Etotal每次减去的数字越来越小,趋近于0。导致更新速率越来越慢,接近无法更新W,导致无法完成神经网络的训练。
2.2 **函数角度

其实也注意到了,上文中提到计算权值更新信息的时候需要计算前层偏导信息,因此如果**函数选择不合适,比如使用sigmoid,梯度消失就会很明显了,原因看下图,左图是sigmoid的损失函数图,右边是其导数的图像,如果使用sigmoid作为损失函数,其梯度是不可能超过0.25的,这样经过链式求导之后,很容易发生梯度消失。
三.结论
sigmoid函数不适合作为复杂神经网络的**函数,sigmoid函数也不适合用来做反向传播。
但是也有sigmoid函数也有优点:
- 便于求导的平滑函数;
- 能压缩数据,保证数据幅度不会有问题;
- 适合用于前向传播。