一.神经网络如何传播?

1.1 正向传播

如下图所示,两个输入值X1X_1X2X_2,以第一层的第一个神经元f1(e)f_1(e)为例。
正向传播先经过线性变换e=x1w1+x2w2e=x_1w_1+x_2w_2,再经过一个激励函数ff(不知道什么是激励函数的同学可自行查看),最终获得输出值yy。同时yy作为下一层的输入值继续相同操作。
对反向传播中梯度消失的全面理解对反向传播中梯度消失的全面理解

对反向传播中梯度消失的全面理解
在这里我们可以抽象的将神经元表示为net和out两部分组成,net表示线性变换得到的值e=x1w1+x2w2e=x_1w_1+x_2w_2,out表示经过激励函数后得到的值y=f(e)y=f(e)对反向传播中梯度消失的全面理解

在正向传播过程中,输入信息通过输入层经隐含层,逐层处理并传向输出层。如果在输出层得不到期望的输出值,则取输出与期望的误差的平方和作为目标函数,转入反向传播,逐层求出目标函数对各神经元权值的偏导数,构成目标函数对权值向量的梯量,作为修改权值的依据,网络的学习在权值修改过程中完成。误差达到所期望值时,网络学习结束。

计算得出的输出y和训练集和的真实结果z有一定的误差,这个误差就叫做误差信号。用误差信号反向传递给前面的各层,来调整网络参数。如下图所示:
对反向传播中梯度消失的全面理解

1.2 反向传播

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

反向传播的最终目标是根据误差值不断修改WiW_i的值,让最终的输出值接近于我们预期值。

  1. 更新W3W_3的值 :
    根据上文中提到的,我们可以把一个神经元分成netnetoutout两部分,所以Output可以分成netOnet_OoutOout_O两部分。要想知道如何更新W3W_3的值,就要知道W3W_3对总误差值EtotalE_{total}做了多少贡献,也就是说1单位W3W_3的变化会引起多少单位EtotalE_{total}的变化,即EtotalW3\frac{\partial E_{total}}{\partial W_3} 根据链式法则,我们W3W_3的变化会引起netOnet_O的变化,而netOnet_O的变化会引起outOout_O的变化,最终outOout_O的变化才会引起EtotalE_{total}的变化,所以我们可以将这一连串变化表示成公式: netOW3outOnetOEtotaloutO=EtotalW3\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+=W3ηEtotalW3W_3^+ = W_3 - \eta*\frac{\partial E_{total}}{{\partial W_3}}
    其中,η\eta是学习效率

  2. 更新W2W_2W1W_1的值:
    2.1 更新W2W_2net2W2out2net2netOout2outOnetOEtotaloutO=EtotalW2\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+=W2ηEtotalW2W_2^+ = W_2 - \eta*\frac{\partial E_{total}}{{\partial W_2}}

2.2 更新W1W_1net1X1out1net1net2out1out2net2netOout2outOnetOEtotaloutO=EtotalW1\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}}
W1+=W1ηEtotalW1W_1^+ = W_1 - \eta*\frac{\partial E_{total}}{{\partial W_1}}

二.梯度消失如何产生?

2.1 数学角度

  • outi=sigmoid(neti)=11+enetoout_i = sigmoid(net_i) = \frac{1}{1+ e^{-net_o}}
    例如:out2=sigmoid(net2)=11+enet2out_2 = sigmoid(net_2)=\frac{1}{1+ e^{-net_2}},相当于out2out_2 是由 net2net_2通过sigmoid**函数后得到的。
  • neti=outi1Wi1net_i = out_{i-1} * W_{i-1}
    例如:net2=out1W1net_2 = out1 * W_1,相当于net2net_2 是由上一层经过**函数输出的值out1out_1与权值W1W_1相乘得来的。

因此,对sigmoid函数求导可得:

outineti=outi(1outi)\frac {\partial out_i}{\partial net_i}= out_i *(1-out_i)
同理,对neti=outi1Wi1net_i = out_{i-1} * W_{i-1}求导可得:
netiouti1=Wi1\frac {\partial net_i}{\partial out_{i-1}}= W_{i-1}
其中,i1i-1是上一层的意思。
同理EtotaloutO=12(targetouto)\frac{\partial E_{total}}{{\partial out_O}}= - \frac{1}{2}*(target - out_o)
其中,target表示最后结果期望的值, 下文中我们把该结果用X表示,因为这是一个常数。

所以可以将上文中更新W1W_1的公式简化为:
W1out1(1out1)W2out2(1out2)W3out3(1out3)XW_1 * out_1*(1-out_1) * W_2 * out_2*(1-out_2) * W_3 * out_3*(1-out_3)*- X
我们把结果分成两部分:
W部分:W1W2W3W_1*W_2*W_3
outiout_i部分: out1(1out1)out2(1out2)out3(1out3)out_1*(1-out_1) *out_2*(1-out_2) *out_3*(1-out_3)

然而,sigmoid函数是[0,1]的函数,如果多次相乘很快ηEtotalW1\eta*\frac{\partial E_{total}}{{\partial W_1}}就会变成一个很小很小的数字,也就是对于这个公式W1+=W1ηEtotalW1W_1^+ = W_1 - \eta*\frac{\partial E_{total}}{{\partial W_1}}每次减去的数字越来越小,趋近于0。导致更新速率越来越慢,接近无法更新W,导致无法完成神经网络的训练。

2.2 **函数角度

对反向传播中梯度消失的全面理解

其实也注意到了,上文中提到计算权值更新信息的时候需要计算前层偏导信息,因此如果**函数选择不合适,比如使用sigmoid,梯度消失就会很明显了,原因看下图,左图是sigmoid的损失函数图,右边是其导数的图像,如果使用sigmoid作为损失函数,其梯度是不可能超过0.25的,这样经过链式求导之后,很容易发生梯度消失。

三.结论

sigmoid函数不适合作为复杂神经网络的**函数,sigmoid函数也不适合用来做反向传播。
但是也有sigmoid函数也有优点:

  1. 便于求导的平滑函数;
  2. 能压缩数据,保证数据幅度不会有问题;
  3. 适合用于前向传播。

相关文章:

  • 2022-12-23
  • 2021-04-03
  • 2021-04-10
  • 2021-08-23
  • 2022-01-05
猜你喜欢
  • 2021-05-18
  • 2022-12-23
  • 2021-07-26
  • 2021-11-06
  • 2021-11-18
  • 2021-08-22
  • 2021-04-11
相关资源
相似解决方案