前一阵子在网上发现一篇很清楚的说明反向传播的文章,所以放到自己博客上分享一下。
原文链接如下:https://mattmazur.com/2015/03/17/a-step-by-step-backpropagation-example/ (by Matt Mazur)
这里使用一个具体的例子看反向传播方法中是如何根据均方误差函数来调整权重的。
从左至右分别是输入层(input:i1、i2),隐含层(hidden:h1、h2)和输出层(output:o1、o2),以及下方的两个偏置(bias:这里两个bias取值皆为1);中间的w1~w8则分别是每层节点之间的权重。
我们的目标是让输出层的输出结果(o1、o2)跟实际应该得到的结果(target1、target2)尽量相同,也是就是target和output之间的差(error)尽可能的小。
即,我们希望(target-output)=0.为了衡量target-output的大小,就采用了一个均方误差函数来计算,希望这个误差函数的结果尽可能的小,于是有:
(Error_{total}=E_{total}=E_{o1}+E_{o2}=frac{1}{2}(o1_{target}-o1_{output})^2+frac{1}{2}(o2_{target}-o2_{output})^2)
这里出现的1/2的作用是在之后对该公式计算偏导数的时候,和得到的2相乘,最后相互抵消掉,暂时可以不用管它。
我们假定实际需要得到的输出应该是(o1_{target}=0.01),(o2_{target}=0.99)(如上图所示)
那么这个简单的神经网络自己计算得到的output1和output2分别是多少呢,我们从左往右以output1为例开始一步步计算。
先看输入:(i1_{input}=0.05),(i2_{input}=0.10);
此时,隐含层h1分别接受来自i1和i2的输入,分别乘以其权重(w1、w2)外加数值为1的偏置(其权重为b1),即
(h1_{input}=w1*i1+w2*i2+b1*1=0.15*0.05+0.2*0.1+0.35*1=0.3775)
所以0.3775是隐含层神经元h1从输入神经元i1和i2得到的输入,h1本身再对这个输入进行一定计算,然后将结果传到下一层(输出层),他的计算方式是采用一个logistic函数,即,
(h1_{output}=frac{1}{1+e^{-h1_{input}}}=frac{1}{1+e^{-0.3775}}=0.593269992)
(这里之所以选择logistic函数也全是为了之后计算偏导数的方便)因为,
如果(y=frac{1}{1+e^x})那么(frac{dy}{dx}=y(1-y))
同理得到(h2_{output}=0.596884378)
输出层o1和o2分别得到来自隐含层h1和h2的输入(即分别是h1的输出以及h2的输出)加上bias,即
(o1_{input}=w5*h1_{output}+w7*h2_{output}+b2*1=0.4*0.593269992+0.45*0.596884378+0.6*1=1.105905967)
然后,o1也是对它的输入进行一次logistic函数的计算后再输出
(o1_{output}=frac{1}{1+e^{-o1_{input}}}=frac{1}{1+e^{-o1_{1.105905967}}}=0.75136507)
同理得到(o2_{output}=0.772928465)
再回来计算(E_{o1}=frac{1}{2}(target_{o1}-output_{o1})^2=frac{1}{2}(0.01-0.75136507)^2=0.274811083)
同理得到(E_{o2}=0.023560026)
最终(E_{total}=E_{o1}+E_{o2}=0.298371109)
我们需要的就是降低上述这个值。为了降低它,我们需要知道这个值本身是如何被权重w所影响的,即误差的变化和权重变化的比例关系。在知道了这个比例后,通过将权重增加或减小,来将误差尽可能地调整为0.我们需要调整所有w1到w8的权重,暂时这里先以w5为例进行计算,让Total Error对它求偏导数(梯度)
(frac{partial E_{total}}{partial w5}=frac{partial E_{total}}{partial o1_{output}}*frac{partial o1_{output}}{partial o1_{input}}*frac{partial o1_{input}}{partial w5})
下面分别计算等式右边的三项,因为
(E_{total}=E_{o1}+E_{o2}=frac{1}{2}(o1_{target}-o1_{output})^2+frac{1}{2}(o2_{target}-o2_{output})^2)
所以
(frac{partial E_{total}}{partial o1_{output}}=2*frac{1}{2}*(o1_{target}-o1_{output})^{2-1}*(-1)+0=-(o1_{target}-o1_{output})=-(0.01-0.75136507)=0.74136507)
又因为
(o1_{output}=frac{1}{1+e^{-o1_{input}}})
所以
(frac{partial o1_{output}}{partial o1_{input}}=o1_{output}*(1-o1_{output})=0.75136507(1-0.75136507)=0.186815602)
另外
(o1_{input}=w5*h1_{output}+w6*h2_{output}+b2*1)
所以
(frac{partial o1_{input}}{partial w5}=1*w5^(1-1)*h1_{output}+0+0=h1_{output}=0.593269992)
最后将上述三项的数值相乘,得到(frac{partial E_{total}}{partial w5})为0.082167041
我们使用这个偏导数的结果来对权重w5进行更新,从而降低误差,
(w5_{new}=w5-(LearningRate)*frac{partial E_{total}}{partial w5}=0.4-0.5*0.082167041=0.35891648) (这里我们暂设学习率-LearningRate为0.5)
w5是从隐含层h1到输出层o1的权重,那么对于输入层i1到隐含层h1的权重w1,我们类似得使用下式求得偏导数,然后对它进行更新。
(frac{partial E_{total}}{partial w1}=frac{partial E_{total}}{partial h1_{output}}*frac{partial h1_{output}}{partial h1_{input}}*frac{partial h1_{input}}{partial w1})
因为(E_{o1},E_{o2})同时受到(h1_{output})的影响,所以这里
(frac{partial E_{total}}{partial h1_{output}}=frac{partial E_{o1}}{partial h1_{output}}+frac{partial E_{o2}}{partial h1_{output}})
接下来的具体推导步骤可以参看原博文。根据这些偏导数的结果对所有权重w1~w8的数值进行更新,即完成了利用梯度进行反向传播,修改权重,从而减少预测整体误差的过程。