60023

大白话5分钟带你走进人工智能-第37节神经网络之反向传播详细案例及解释(5)

<p id="main-toc">目录

<p id="1%E3%80%81%E5%8F%8D%E5%90%91%E4%BC%A0%E6%92%AD%E5%89%8D%E8%BF%B0-toc" style="margin-left: 0px;">1、反向传播前述:

<p id="2%E3%80%81%E7%AC%AC%E4%B8%80%E4%B8%AA%E6%A1%88%E4%BE%8B%E8%A7%A3%E8%AF%B4%E5%8F%8D%E5%90%91%E4%BC%A0%E6%92%AD-toc" style="margin-left: 0px;">2、第一个案例解说反向传播:

<p id="3%E3%80%81%E9%80%9A%E7%94%A8%E6%A1%88%E4%BE%8B%E5%BD%A2%E5%BC%8F%EF%BC%9A-toc" style="margin-left: 0px;">3、通用案例形式:

<p id="4%E3%80%81%E9%80%BB%E8%BE%91%E5%9B%9E%E5%BD%92%E6%A1%88%E4%BE%8B-toc" style="margin-left: 0px;">4、逻辑回归案例:

<p id="5%E3%80%81%E6%80%BB%E7%BB%93%EF%BC%9A-toc" style="margin-left: 0px;">5、总结:

<hr id="hr-toc" /><h1 id="1%E3%80%81%E5%8F%8D%E5%90%91%E4%BC%A0%E6%92%AD%E5%89%8D%E8%BF%B0" style="margin-left: 0cm;">1、反向传播前述:

<p style="margin-left: 0cm;">我们知道正向传播就是把x拿下来一层层的和w乘,然后经过function非线性变化,最后得到一个y输出结果。反向传播(reverse-mode autodiff)就是反过来,从最后的y到x,反向的自动求导。前向传播是make predictions,去预测ŷ,然后计算出误差,再计算出每个神经节点对误差的贡献。这里的求贡献就是反向传播过程,首先根据前向传播的误差来求梯度,梯度越大贡献越大。然后根据梯度调整原来的权重。总结下来反向传播就是求导、求梯度,然后根据梯度在迭代里面调整w的一个过程。

<p style="margin-left: 0cm;">反向自动求导是tensorflow实现的方案,首先,它执行图的前向阶段,从输入到输出,去计算节点值;然后反向阶段,从输出到输入去计算所有变量的偏导。

<p style="margin-left: 0cm;">什么是偏导数:在数学中,一个多变量的函数的偏导数,就是它关于其中一个变量的导数而保持其他变量恒定(相对于全导数,在其中所有变量都允许变化)。偏导数在向量分析和微分几何中是很有用的。

<p style="margin-left: 0cm;">说白了就是假如f对x求偏导:∂f*∂x。就是把除x以外的自变量当成常数,然后再进行正常的求导即可。

<h1 id="2%E3%80%81%E7%AC%AC%E4%B8%80%E4%B8%AA%E6%A1%88%E4%BE%8B%E8%A7%A3%E8%AF%B4%E5%8F%8D%E5%90%91%E4%BC%A0%E6%92%AD" style="margin-left: 0cm;">2、第一个案例解说反向传播:

<p style="margin-left: 0cm;">比如

<p style="margin-left: 0cm;">                                                                                 

<p style="margin-left: 0cm;">这个计算逻辑,即这个算法。可以用如图来表达正向传播和反向传播逻辑。图中红色虚线表示正向传播,黑色实线是反向传播。

<p class="cke_widget_element" style="text-align: center;" data-cke-widget-data="{&quot;hasCaption&quot;:false,&quot;src&quot;:&quot;https://img-blog.csdnimg.cn/20190806225250956.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xIV29ybGRCbG9n,size_16,color_FFFFFF,t_70&quot;,&quot;alt&quot;:&quot;&quot;,&quot;width&quot;:&quot;550&quot;,&quot;height&quot;:&quot;400&quot;,&quot;lock&quot;:true,&quot;align&quot;:&quot;center&quot;,&quot;classes&quot;:{&quot;has&quot;:1}}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="image">​

<p style="margin-left: 0cm;">如果x=3,y=4,正向传播之后,结果为42,体现在n7节点上。

<p style="margin-left: 0cm;">那反向传播是做什么事情呢?怎样传播? 如何计算每根线上面的梯度呢?

<p style="margin-left: 0cm;">这里依赖反向自动求导(reverse-mode autodiff),求解的想法是逐渐的从上往下,来计算f(x,y)的偏导,使用每一个中间连续的节点,直到我们达到变量节点,这里严重依赖链式求导法则

<p style="margin-left: 0cm;">链式求导法则,就是x不能直接连接f,我们通过一个中间的节点,比如ni,如果ni可以连接f,就可以让f对ni求偏导;然后x可以连接ni,ni对xi求偏导,然后根据链式求导法则相乘,得到的就是f对x求偏导的一个值。

<p style="margin-left: 0cm;">                                                                                       

<p style="margin-left: 0cm;">比如上图中的算法逻辑我们最终的f对x来求偏的, f是最后节点出现的结果,x是第一个节点,中间有好长的路要走。所以如果对x求偏导的话,得把每一步节点输出对x求偏导。n1节点没有直接连上n7节点, n1节点也没有直接连上n5节点,但是n1节点可以连上n4节点;n4节点连不上n7节点,但是能连接n5节点。那么我们可以让xn1通过n4去连接n5,然后再通过n5连接到n7,它就成为一条链,求这条链上面的导数,最后就可以把n7对n1也就是f对x偏导求出来。

<p style="margin-left: 0cm;">因为最后的function,对x求偏导,不能直接对x求导,我们倒过来一点点来推,所以它叫反向传播,反过来一点点的去传播梯度。

<p style="margin-left: 0cm;">接下来我们一层一层的解释。

<p style="margin-left: 0cm;">对于f来说,f就是n7的结果,所以f对n7求导。因为是对本身求导,相当于f(x)=x这种情况下,对x求导,结果就变成前面的一个系数,等于1。

<p class="cke_widget_element" style="text-align: center;" data-cke-widget-data="{&quot;hasCaption&quot;:false,&quot;src&quot;:&quot;https://img-blog.csdnimg.cn/2019080623125354.png&quot;,&quot;alt&quot;:&quot;&quot;,&quot;width&quot;:&quot;100&quot;,&quot;height&quot;:&quot;64&quot;,&quot;lock&quot;:true,&quot;align&quot;:&quot;center&quot;,&quot;classes&quot;:{&quot;has&quot;:1}}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="image">​

<p style="margin-left: 0cm;">下一层,我们要求图中红色这根线上所对应的梯度

<p class="cke_widget_element" style="text-align: center;" data-cke-widget-data="{&quot;hasCaption&quot;:false,&quot;src&quot;:&quot;https://img-blog.csdnimg.cn/20190807213549688.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xIV29ybGRCbG9n,size_16,color_FFFFFF,t_70&quot;,&quot;alt&quot;:&quot;&quot;,&quot;width&quot;:&quot;300&quot;,&quot;height&quot;:&quot;146&quot;,&quot;lock&quot;:true,&quot;align&quot;:&quot;center&quot;,&quot;classes&quot;:{&quot;has&quot;:1}}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="image">​

<p style="margin-left: 0cm;">这根线的输出是n5节点,所以就要求一下n7对n5节点function的一个偏导,根据链式法则,如图,把它俩的结果相乘。f对n7这一部分已经得到了结果,n7节点的function是加和,n7=n5+n6,如果n7对n5求偏导,结果就是1。可以这样理解这一步,比如f(x)=ax+by,对x求导,那跟b、y没有关系,只用看x前面所对应的斜率,就等于a,这里同样只看n5前面的系数即为1。记住:

<p style="margin-left: 0cm;">对谁求偏导,就把谁看做未知数。其他的都是常数!

<p style="margin-left: 0cm;">∂f/∂n5=∂f*∂n7*∂n7/∂n5,就是1*1=1,所以图中这根红线上的梯度就是1。此时我们有一个中间结果,

<p style="margin-left: 0cm;">接下来再往下来传播。求如下红色线的梯度:

<p class="cke_widget_element" style="text-align: center;" data-cke-widget-data="{&quot;hasCaption&quot;:false,&quot;src&quot;:&quot;https://img-blog.csdnimg.cn/20190807214302522.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xIV29ybGRCbG9n,size_16,color_FFFFFF,t_70&quot;,&quot;alt&quot;:&quot;&quot;,&quot;width&quot;:&quot;300&quot;,&quot;height&quot;:&quot;186&quot;,&quot;lock&quot;:true,&quot;align&quot;:&quot;center&quot;,&quot;classes&quot;:{&quot;has&quot;:1}}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="image">​

<p style="margin-left: 0cm;">即求∂f/∂n4,等于∂f/∂n5*∂n5/∂n4,上一步求出来的∂f/∂n5=1,接着计算∂n5/∂n4,n5的计算节点的function是,乘法。n5=n4*n2,对n4求偏导,把n4当做未知数,n2为系数,所以结果是n2。同理,反过来,对n2求偏导结果n4。然后把n2节点的数值4代进来,即∂f/∂n4=1*4=4。

<p style="margin-left: 0cm;">再往下传播:求图中红色线梯度

<p class="cke_widget_element" style="text-align: center;" data-cke-widget-data="{&quot;hasCaption&quot;:false,&quot;src&quot;:&quot;https://img-blog.csdnimg.cn/20190807214532986.png&quot;,&quot;alt&quot;:&quot;&quot;,&quot;width&quot;:&quot;200&quot;,&quot;height&quot;:&quot;184&quot;,&quot;lock&quot;:true,&quot;align&quot;:&quot;center&quot;,&quot;classes&quot;:{&quot;has&quot;:1}}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="image">​

<p style="margin-left: 0cm;">即∂f/∂x,这里有两根线,根据上面传播下来的梯度,那∂f/∂x=∂f/∂n4*∂n4/∂n1,∂f/∂n4已经根据前面算出来的逻辑,∂f/∂n4=4,下面求∂n4/∂n1,∂n4/∂n1看n4节点的function逻辑。此时n4=n1*n1=n1^2。因为(x^2)'=2x,所以∂n4/∂n1=2n1=6。所以∂f/∂x=∂f/∂n4*∂n4/∂n1=4*6=24。

<p style="margin-left: 0cm;">下面求f对y的梯度,y就是n2,如图,因为y是有两条线连接,先求下图左边的梯度:

<p class="cke_widget_element" style="text-align: center;" data-cke-widget-data="{&quot;hasCaption&quot;:false,&quot;src&quot;:&quot;https://img-blog.csdnimg.cn/20190807215234858.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xIV29ybGRCbG9n,size_16,color_FFFFFF,t_70&quot;,&quot;alt&quot;:&quot;&quot;,&quot;width&quot;:&quot;450&quot;,&quot;height&quot;:&quot;246&quot;,&quot;lock&quot;:true,&quot;align&quot;:&quot;center&quot;,&quot;classes&quot;:{&quot;has&quot;:1}}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="image">​

<p style="margin-left: 0cm;">n2上面连接n5,那么梯度∂f/∂n2=∂f/∂n5*∂n5/∂n2,∂f/∂n5=1(上面已经求出),∂n5/∂n2这部分看n5的逻辑是n5=n4*n2,对n2求偏导结果为n4。n4不用算,因为在正向传播的时候,每个节点的值已经算出来了,所以n4是3^2=9。即∂n5/∂n2=9。所以∂f/∂n2=∂f/∂n2=∂f/∂n5*∂n5/∂n2=1*9=9。

<p style="margin-left: 0cm;">然后再求y连线的右半部分如图:

<p class="cke_widget_element" style="text-align: center;" data-cke-widget-data="{&quot;hasCaption&quot;:false,&quot;src&quot;:&quot;https://img-blog.csdnimg.cn/2019080722024886.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xIV29ybGRCbG9n,size_16,color_FFFFFF,t_70&quot;,&quot;alt&quot;:&quot;&quot;,&quot;width&quot;:&quot;280&quot;,&quot;height&quot;:&quot;296&quot;,&quot;lock&quot;:true,&quot;align&quot;:&quot;center&quot;,&quot;classes&quot;:{&quot;has&quot;:1}}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="image">​

<p style="margin-left: 0cm;">n7经过n6再连接n2,那么∂n7/∂n2=∂n7/∂n6*∂n6/∂n2,∂n7/∂n6看n7的逻辑n7=n5+n6,对n6求偏导结果为1;∂n6/∂n2看n6的逻辑n6=n2+n3,对n2求偏导也是1。所以∂n7/∂n2=1*1=1。

<p style="margin-left: 0cm;">所以最后∂f/∂y=∂f/∂n2+∂nf/∂n2=1+9=10。

<p style="margin-left: 0cm;">我们再看下f对n3的梯度:

<p class="cke_widget_element" style="text-align: center;" data-cke-widget-data="{&quot;hasCaption&quot;:false,&quot;src&quot;:&quot;https://img-blog.csdnimg.cn/20190807220712365.png&quot;,&quot;alt&quot;:&quot;&quot;,&quot;width&quot;:&quot;180&quot;,&quot;height&quot;:&quot;233&quot;,&quot;lock&quot;:true,&quot;align&quot;:&quot;center&quot;,&quot;classes&quot;:{&quot;has&quot;:1}}" data-cke-widget-upcasted="1" data-cke-widget-keep-attr="0" data-widget="image">​

<p style="margin-left: 0cm;">其实我们也不用算这根线,换成机器学习的角度去看,n1是第一个维度x1,n2是第而个维度x2,n3是截距,对截距求偏导,把n3看做未知数,前面系数恒为1 。所以对截距求偏导结果恒为1。

<p style="margin-left: 0cm;">反向传播,如果想求每根线上所对应的梯度,得从后面往前,反着一层层的推出来,才能推出来。这样沿着图一路向下,我们可以计算出所有连线梯度,最后就能计算出

Recommend