斯坦福CS231N深度学习与计算机视觉第五弹:反向传播与它的直观理解

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

斯坦福CS231N深度学习与计算机视觉第五弹:反向传播与它的直观理解本文为斯坦福大学CS231N课程的中文版内容笔记,已获得斯坦福大学课程AndrejKarpathy教授的授权翻译与发表。大数据文摘作品,未经授权禁止转载,转载具体要求见文末。报名啦机器学习培训报名开始啦!顶级讲师课程设计理论结合实际更有四大福利提供详细介绍,长按文末二维码大数据文摘编译作品,转载具体要求见文末翻译:寒小阳&龙心尘编者按:本期文章是我们为读者带来斯坦福课程文章第二个系列的【斯坦福深度学习与计算机视觉课程】第五期。文章内容为斯坦福CS231N系列,供有兴趣的读者感受、学习。本课程的视频翻译也在同时进行,将在近期发布,敬请期待!大数据文摘将陆续发布译文和视频,免费分享给各位读者。我们欢迎更多感兴趣的志愿者加入我们,一起交流学习。所有译者均为志愿者,如果你和我们一样,是有能力、愿分享的朋友,请加入我们。在大数据文摘后台回复“志愿者”,了解更多。斯坦福大学CS231N课程是深度学习与计算机视觉方面的经典教程,业界评价很高。之前也有国内朋友做一些零星的翻译,为了与更多读者分享高品质内容,大数据文摘对其进行了系统全面的翻译,后续内容将陆续推出。由于微信后台的代码编辑无法实现,我们采用了图片插入的方式展示代码,点击图片可查看更清晰的图片。同时,大数据文摘之前已获得授权的斯坦福课程第一个系列斯坦福大学CS224d课程【机器学习与自然语言处理】已经完成了八个课时,我们将在每个周三继续推送后续笔记及课程视频,敬请关注。回复“斯坦福”下载CS231N笔记PDF版本及相关视频资料同时获得斯坦福另一个系列课程CS224d深度学习与自然语言处理的相关资料此外,对于有兴趣进一步学习交流的读者,我们将通过QQ群(鉴于微信人数限制问题)组织进行学习交流。长按以下二维码将直接跳转至QQ加群或者通过群号码564538990进群1.引言其实一开始要讲这部分内容,我是拒绝的,原因是我觉得有一种写高数课总结的感觉。而一般直观上理解反向传播算法就是求导的一个链式法则而已。但是偏偏理解这部分和其中的细节对于神经网络的设计和调整优化又是有用的,所以硬着头皮写写吧。问题描述与动机:2.高数梯度/偏导基础3.复杂函数偏导的链式法则考虑一个麻烦一点的函数,比如当然,这个表达式其实还没那么复杂,也可以直接求偏导。但是我们用一个非直接的思路去求解一下偏导,以帮助我们直观理解反向传播中。如果我们用换元法,把原函数拆成两个部分对于这两个部分,我们知道怎么求解它们变量上的偏导:,当然q是我们自己设定的一个变量,我们对他的偏导完全不感兴趣。那『链式法则』告诉我们一个对上述偏导公式『串联』的方式,得到我们感兴趣的偏导数:看个例子:x=-2;y=5;z=-4#前向计算q=x+y#qbecomes3f=q*z#fbecomes-12#类反向传播:#先算到了f=q*zdfdz=q#df/dz=qdfdq=z#df/dq=z#再算到了q=x+ydfdx=1.0*dfdq#dq/dx=1恩,链式法则dfdy=1.0*dfdq#dq/dy=1链式法则的结果是,只剩下我们感兴趣的[dfdx,dfdy,dfdz],也就是原函数在x,y,z上的偏导。这是一个简单的例子,之后的程序里面我们为了简洁,不会完整写出dfdq,而是用dq代替。以下是这个计算的示意图:4.反向传播的直观理解一句话概括:反向传播的过程,实际上是一个由局部到全部的精妙过程。比如上面的电路图中,其实每一个『门』在拿到输入之后,都能计算2个东西:输出值对应输入和输出的局部梯度而且很明显,每个门在进行这个计算的时候是完全独立的,不需要对电路图中其他的结构有了解。然而,在整个前向传输过程结束之后,在反向传播过程中,每个门却能逐步累积计算出它在整个电路输出上的梯度。『链式法则』告诉我们每一个门接收到后向传来的梯度,同时用它乘以自己算出的对每个输入的局部梯度,接着往后传。以上面的图为例,来解释一下这个过程。加法门接收到输入[-2,5]同时输出结果3。因为加法操作对两个输入的偏导都应该是1。电路后续的乘法部分算出最终结果-12。在反向传播过程中,链式法则是这样做的:加法操作的输出3,在最后的乘法操作中,获得的梯度为-4,如果把整个网络拟人化,我们可以认为这代表着网络『想要』加法操作的结果小一点,而且是以4*的强度来减小。加法操作的门获得这个梯度-4以后,把它分别乘以本地的两个梯度(加法的偏导都是1),1*-4=-4。如果输入x减小,那加法门的输出也会减小,这样乘法输出会相应的增加。反向传播,可以看做网络中门与门之间的『关联对话』,它们『想要』自己的输出更大还是更小(以多大的幅度),从而让最后的输出结果更大。5.Sigmoid例子上面举的例子其实在实际应用中很少见,我们很多时候见到的网络和门函数更复杂,但是不论它是什么样的,反向传播都是可以使用的,唯一的区别就是可能网络拆解出来的门函数布局更复杂一些。我们以之前的逻辑回归为例:这个看似复杂的函数,其实可以看做一些基础函数的组合,这些基础函数及他们的偏导如下:上述每一个基础函数都可以看做一个门,如此简单的初等函数组合在一块儿却能够完成逻辑回归中映射函数的复杂功能。下面我们画出神经网络,并给出具体输入输出和参数的数值:这个图中,[x0,x1]是输入,[w0,w1,w2]为可调参数,所以它做的事情是对输入做了一个线性计算(x和w的内积),同时把结果放入sigmoid函数中,从而映射到(0,1)之间的数。上面的例子中,w与x之间的内积分解为一长串的小函数连接完成,而后接的是sigmoid函,有趣的是sigmoid函数看似复杂,求解倒是的时候却是有技巧的,如下:你看,它的导数可以用自己很简单的重新表示出来。所以在计算导数的时候非常方便,比如sigmoid函数接收到的输入是1.0,输出结果是-0.73。那么我们可以非常方便地计算得到它的偏导为(1-0.73)*0.73~=0.2。我们看看在这个sigmoid函数部分反向传播的计算代码:w=[2,-3,-3]#我们随机给定一组权重x=[-1,-2]#前向传播dot=w[0]*x[0]+w[1]*x[1]+w[2]f=1.0/(1+math.exp(-dot))#sigmoid函数#反向传播经过该sigmoid神经元ddot=(1-f)*f#sigmoid函数偏导dx=[w[0]*ddot,w[1]*ddot]#在x这条路径上的反向传播dw=[x[0]*ddot,x[1]*ddot,1.0*ddot]#在w这条路径上的反向传播#yes!就酱紫算完了!是不是很简单?5.1工程实现小提示回过头看看上头的代码,你会发现,实际写代码实现的时候,有一个技巧能帮助我们很容易地实现反向传播,我们会把前向传播的过程分解成反向传播很容易追溯回来的部分。6.反向传播实战:复杂函数我们看一个稍复杂一些的函数:插一句,这个函数没有任何实际的意义。我们提到它,仅仅是想举个例子来说明复杂函数的反向传播怎么使用。如果直接对这个函数求x或者y的偏导的话,你会得到一个很复杂的形式。但是如果你用反向传播去求解具体的梯度值的话,却完全没有这个烦恼。我们把这个函数分解成小部分,进行前向和反向传播计算,即可得到结果,前向传播计算的代码如下:x=3#例子y=-4#前向传播sigy=1.0/(1+math.exp(-y))#单值上的sigmoid函数num=x+sigysigx=1.0/(1+math.exp(-x))xpy=x+yxpysqr=xpy**2den=sigx+xpysqrinvden=1.0/denf=num*invden#完成!注意到我们并没有一次性把前向传播最后结果算出来,而是刻意留出了很多中间变量,它们都是我们可以直接求解局部梯度的简单表达式。因此,计算反向传播就变得简单了:我们从最后结果往前看,前向运算中的每一个中间变量sigy,num,sigx,xpy,xpysqr,den,invden我们都会用到,只不过后向传回的偏导值乘以它们,得到反向传播的偏导值。反向传播计算的代码如下:#局部函数表达式为f=num*invdendnum=invdendinvden=num#局部函数表达式为invden=1.0/dendden=(-1.0/(den**2))*dinvden#局部函数表达式为den=sigx+xpysqrdsigx=(1)*ddendxpysqr=(1)*dden#局部函数表达式为xpysqr=xpy**2dxpy=(2*xpy)*dxpysqr#(5)#局部函数表达式为xpy=x+ydx=(1)*dxpydy=(1)*dxpy#局部函数表达式为sigx=1.0/(1+math.exp(-x))dx+=((1-sigx)*sigx)*dsigx#注意到这里用的是+=!!#局部函数表达式为num=x+sigydx+=(1)*dnumdsigy=(1)*dnum#局部函数表达式为sigy=1.0/(1+math.exp(-y))dy+=((1-sigy)*sigy)*dsigy#完事!实际编程实现的时候,需要注意一下:前向传播计算的时候注意保留部分中间变量:在反向传播计算的时候,会再次用到前向传播计算中的部分结果。这在反向传播计算的回溯时可大大加速。6.1反向传播计算中的常见模式即使因为搭建的神经网络结构形式和使用的神经元都不同,但是大多数情况下,后向计算中的梯度计算可以归到几种常见的模式上。比如,最常见的三种简单运算门(加、乘、最大),他们在反向传播运算中的作用是非常简单和直接的。我们一起看看下面这个简单的神经网:上图里有我们提到的三种门add,max和multiply。加运算门在反向传播运算中,不管输入值是多少,取得它output传回的梯度(gradient)然后均匀地分给两条输入路径。因为加法运算的偏导都是+1.0。max(取最大)门不像加法门,在反向传播计算中,它只会把传回的梯度回传给一条输入路径。因为max(x,y)只对x和y中较大的那个数,偏导为+1.0,而另一个数上的偏导是0。乘法门就更好理解了,因为x*y对x的偏导为y,而对y的偏导为x,因此在上图中x的梯度是-8.0,即-4.0*2.0因为梯度回传的原因,神经网络对输入非常敏感。我们拿乘法门来举例,如果输入全都变成原来1000倍,而权重w不变,那么在反向传播计算的时候,x路径上获得的回传梯度不变,而w上的梯度则会变大1000倍,这使得你不得不降低学习速率(learningrate)成原来的1/1000以维持平衡。因此在很多神经网络的问题中,输入数据的预处理也是非常重要的。6.2向量化的梯度运算上面所有的部分都是在单变量的函数上做的处理和运算,实际我们在处理很多数据(比如图像数据)的时候,维度都比较高,这时候我们就需要把单变量的函数反向传播扩展到向量化的梯度运算上,需要特别注意的是矩阵运算的每个矩阵维度,以及转置操作。我们通过简单的矩阵运算来拓展前向和反向传播运算,示例代码如下:#前向传播运算W=np.random.randn(5,10)X=np.random.randn(10,3)D=W.dot(X)#假如我们现在已经拿到了回传到D上的梯度dDdD=np.random.randn(*D.shape)#和D同维度dW=dD.dot(X.T)#.T操作计算转置,dW为W路径上的梯度dX=W.T.dot(dD)#dX为X路径上的梯度7.总结直观地理解,反向传播可以看做图解求导的链式法则。最后我们用一组图来说明实际优化过程中的正向传播与反向残差传播:关于转载

1 / 10
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功