一文搞懂反向传播算法

作者: 张小磊啊 | 来源:发表于2017-08-31 11:59 被阅读9923次

    一、前言

    这是一场以误差(Error)为主导的反向传播(Back Propagation)运动,旨在得到最优的全局参数矩阵,进而将多层神经网络应用到分类或者回归任务中去。

    前向传递输入信号直至输出产生误差,反向传播误差信息更新权重矩阵。这两句话很好的形容了信息的流动方向,权重得以在信息双向流动中得到优化,这让我想到了北京城的夜景,车辆川流不息,车水马龙,你来我往(* ॑꒳ ॑* )⋆*。

    至于为什么会提出反向传播算法,我直接应用梯度下降(Gradient Descent)不行吗?想必大家肯定有过这样的疑问。答案肯定是不行的,纵然梯度下降神通广大,但却不是万能的。梯度下降可以应对带有明确求导函数的情况,或者说可以应对那些可以求出误差的情况,比如逻辑回归(Logistic Regression),我们可以把它看做没有隐层的网络;但对于多隐层的神经网络,输出层可以直接求出误差来更新参数,但其中隐层的误差是不存在的,因此不能对它直接应用梯度下降,而是先将误差反向传播至隐层,然后再应用梯度下降,其中将误差从末层往前传递的过程需要链式法则(Chain Rule)的帮助,因此反向传播算法可以说是梯度下降在链式法则中的应用。

    二、举个栗子

    为了帮助较好的理解反向传播概念,对它有一个直观的理解,接下来就拿猜数字游戏举个栗子。

    2.1 两人猜数字

    这一过程类比没有隐层的神经网络,比如逻辑回归,其中小黄帽代表输出层节点,左侧接受输入信号,右侧产生输出结果,小蓝猫则代表了误差,指导参数往更优的方向调整。由于小蓝猫可以直接将误差反馈给小黄帽,同时只有一个参数矩阵和小黄帽直接相连,所以可以直接通过误差进行参数优化(实纵线),迭代几轮,误差会降低到最小。

    2.2 三人猜数字

    这一过程类比带有一个隐层的三层神经网络,其中小女孩代表隐藏层节点,小黄帽依然代表输出层节点,小女孩左侧接受输入信号,经过隐层节点产生输出结果,小蓝猫代表了误差,指导参数往更优的方向调整。由于小蓝猫可以直接将误差反馈给小黄帽,所以与小黄帽直接相连的左侧参数矩阵可以直接通过误差进行参数优化(实纵线);而与小女孩直接相连的左侧参数矩阵由于不能得到小蓝猫的直接反馈而不能直接被优化(虚棕线)。但由于反向传播算法使得小蓝猫的反馈可以被传递到小女孩那进而产生间接误差,所以与小女孩直接相连的左侧权重矩阵可以通过间接误差得到权重更新,迭代几轮,误差会降低到最小。

    三、完整流程

    上边的栗子从直观角度了解了反向传播,接下来就详细的介绍其中两个流程前向传播与反向传播,在介绍之前先统一一下标记。

    3.1 数学标记

    3.2 前向传播

    如何将输入层的信号传输至隐藏层呢,以隐藏层节点c为例,站在节点c上往后看(输入层的方向),可以看到有两个箭头指向节点c,因此a,b节点的信息将传递给c,同时每个箭头有一定的权重,因此对于c节点来说,输入信号为:


    同理,节点d的输入信号为:


    由于计算机善于做带有循环的任务,因此我们可以用矩阵相乘来表示:


    所以,隐藏层节点经过非线性变换后的输出表示如下:


    同理,输出层的输入信号表示为权重矩阵乘以上一层的输出:


    同样,输出层节点经过非线性映射后的最终输出表示为:


    输入信号在权重矩阵们的帮助下,得到每一层的输出,最终到达输出层。可见,权重矩阵在前向传播信号的过程中扮演着运输兵的作用,起到承上启下的功能。

    3.3 反向传播

    既然梯度下降需要每一层都有明确的误差才能更新参数,所以接下来的重点是如何将输出层的误差反向传播给隐藏层。


    其中输出层、隐藏层节点的误差如图所示,输出层误差已知,接下来对隐藏层第一个节点c作误差分析。还是站在节点c上,不同的是这次是往前看(输出层的方向),可以看到指向c节点的两个蓝色粗箭头是从节点e和节点f开始的,因此对于节点c的误差肯定是和输出层的节点e和f有关。

    不难发现,输出层的节点e有箭头分别指向了隐藏层的节点c和d,因此对于隐藏节点e的误差不能被隐藏节点c霸为己有,而是要服从按劳分配的原则(按权重分配),同理节点f的误差也需服从这样的原则,因此对于隐藏层节点c的误差为:


    同理,对于隐藏层节点d的误差为:


    为了减少工作量,我们还是乐意写成矩阵相乘的形式:


    你会发现这个矩阵比较繁琐,如果能够简化到前向传播那样的形式就更好了。实际上我们可以这么来做,只要不破坏它们的比例就好,因此我们可以忽略掉分母部分,所以重新成矩阵形式为:


    仔细观察,你会发现这个权重矩阵,其实是前向传播时权重矩阵w的转置,因此简写形式如下:


    不难发现,输出层误差在转置权重矩阵的帮助下,传递到了隐藏层,这样我们就可以利用间接误差来更新与隐藏层相连的权重矩阵。可见,权重矩阵在反向传播的过程中同样扮演着运输兵的作用,只不过这次是搬运的输出误差,而不是输入信号(我们不生产误差,只是误差的搬运工(っ̯ -。))。

    四、链式求导

    第三部分大致介绍了输入信息的前向传播与输出误差的后向传播,接下来就根据求得的误差来更新参数。


    首先对隐藏层的w11进行参数更新,更新之前让我们从后往前推导,直到预见w11为止:


    因此误差对w11求偏导如下:


    求导得如下公式(所有值已知):


    同理,误差对于w12的偏导如下:


    同样,求导得w12的求值公式:


    同理,误差对于偏置求偏导如下:


    带入上述公式为:


    接着对输入层的w11进行参数更新,更新之前我们依然从后往前推导,直到预见第一层的w11为止(只不过这次需要往前推的更久一些):


    因此误差对输入层的w11求偏导如下:


    求导得如下公式(有点长(ฅ́˘ฅ̀)):

    同理,输入层的其他三个参数按照同样的方法即可求出各自的偏导,在这不再赘述。

    在每个参数偏导数明确的情况下,带入梯度下降公式即可(不在重点介绍):


    至此,利用链式法则来对每层参数进行更新的任务已经完成。

    五、引入delta

    利用链式法则来更新权重你会发现其实这个方法简单,但过于冗长。由于更新的过程可以看做是从网络的输入层到输出层从前往后更新,每次更新的时候都需要重新计算节点的误差,因此会存在一些不必要的重复计算。其实对于已经计算完毕的节点我们完全可以直接拿来用,因此我们可以重新看待这个问题,从后往前更新。先更新后边的权重,之后再在此基础上利用更新后边的权重产生的中间值来更新较靠前的参数。这个中间变量就是下文要介绍的delta变量,一来简化公式,二来减少计算量,有点动态规划的赶脚。

    接下来用事实说话,大家仔细观察一下在第四部分链式求导部分误差对于输出层的w11以及隐藏层的w11求偏导以及偏置的求偏导的过程,你会发现,三个公式存在相同的部分,同时隐藏层参数求偏导的过程会用到输出层参数求偏导的部分公式,这正是引入了中间变量delta的原因(其实红框的公式就是delta的定义)。


    大家看一下经典书籍《神经网络与深度学习》中对于delta的描述为在第l层第j个神经元上的误差,定义为误差对于当前带权输入求偏导,数学公式如下:


    因此输出层的误差可以表示为(上图红色框公式):


    隐藏层的误差可以表示为(上图蓝色框公式):


    同时对于权重更新的表示为(上图绿色框公式):


    其实对于偏置的更新表示为(上图红色框):


    上述4个公式其实就是《神经网络与深度学习》书中传说的反向传播4大公式(详细推导证明可移步此书):


    仔细观察,你会发现BP1与BP2相结合就能发挥出最大功效,可以计算出任意层的误差,只要首先利用BP1公式计算出输出层误差,然后利用BP2层层传递,就无敌了,这也正是误差反向传播算法的缘由吧。同时对于权重w以及偏置b我们就可以通过BP3和BP4公式来计算了。

    至此,我们介绍了反向传播的相关知识,一开始看反向传播资料的时候总觉得相对独立,这个教材这么讲,另一篇博客又换一个讲法,始终不能很好的理解其中的含义,到目前为止,思路相对清晰。我们先从大致流程上介绍了反向传播的来龙去脉,接着用链式求导法则来计算权重以及偏置的偏导,进而我们推出了跟经典著作一样样儿的结论,因此本人觉得较为详细,应该对初学者有一定的借鉴意义,希望对大家有所帮助。

    更多文章见我的知乎 张小磊
    我的GitHub 张小磊

    ========这是一条求赞的分割线======

    码字作图插公式不易,收藏表忘点赞 ೖ(⑅σ̑ᴗσ̑)ೖ

    Nielsen M A. Neural networks and deep learning[M]. 2015.

    Rashid T. Make your own neural network[M]. CreateSpace IndependentPublishing Platform, 2016.

    相关文章

      网友评论

      • KagaYaku:你很不错,小老弟
        张小磊啊:@KagaYaku :joy: 谢谢夸奖
      • 柿_58d6:BP2的公式中的W是第l层的吧?
      • d22880ff18eb:编者你写得真好,可以转载一下吗,我会声明作者和来源的
        张小磊啊:@Lxhnnn 哈哈,客气,也欢迎你关注我的知乎-张小磊:smile:
        d22880ff18eb:谢谢你
        张小磊啊:@Lxhnnn 当然,谢谢支持哈😀
      • yudw15:“只要不破坏它们的比例就好,因此我们可以忽略掉分母部分” 数学原理是什么?
        张小磊啊:@yudw15 在这可以这样理解,至于他的结论是从链式法则推出来的
      • 张小磊啊:@磊_1051 谢谢磊老板赞赏,又有动力写总结性的文章啦:blush:
      • 躺在稻田里的小白菜:原理阐述的很清楚,就是参数标记错了,让我费解了好久
        张小磊啊:@一只小蜗牛ustc 抱歉哈,等我抽空改一下,最近比较忙
      • 大橘为重_c49b:问下大神,3.3 反向传播的最后得到的反向误差有什么用处呢?我见后面链式求导等也没有用到。谢谢
        张小磊啊:@大橘为重_c49b 抱歉前段时间比较忙,没及时回复,对,利用链式法则求导可以更新,其实在利用链式法则求导的过程中就利用到了反向传播的误差。
        大橘为重_c49b:@张小磊啊 您好,前层的参数不是利用第四节链式求导法则来对每层参数进行更新的吗?通过代价函数e01对每个参数求偏导不是直接就更新了。我见也不用到这个反向误差。谢谢~
        张小磊啊:@大橘为重_c49b 你好,误差(往前层)反向传播就是为了更新前层的参数的。如果该层的参数没有误差就不能进行更新啦
      • 飞_翼:化繁为简,是一种能力。为作者点赞。:+1:
        张小磊啊:@飞_翼 :blush:
      • a9be856b6cd5:文中没有说明权重矩阵W的转置和偏导数的关系,在第三段和第四段思路过度的有点勉强。建议作者还是补上两者传递关系
        张小磊啊:感谢提供的宝贵意见,再接下来的文章我会认真考虑各部分的衔接关系的:smile:
      • 小岳读书:大牛,我来拜读了,收下我的膝盖吧
        张小磊啊:@小岳读书 小牛,你的拜读,我的荣幸。
      • 就叫沙滩上的石头:同样,输出层节点经过非线性映射后的最终输出表示为:A3 = sigmoid(Z3),这里不懂,能解释下吗
        d3a5809a099f:感谢作者,讲得很好!
        张小磊啊:@就叫沙滩上的石头 就是上一层的输出结果经过加权之后作为本层的输入,经过一个sigmoid非线性函数进行映射
      • d6dab09b3856:w定义就错了,按你公式的用法,应该定义成:第l+1层的j,第l层的k
        可以改变的:应该是l层的第j个神经元和(l+1)层的第k个神经元吧?
        张小磊啊:@槑宝包 感谢你提出的意见
      • 89c478518481:你的W下标错了。
        日月_8772:w权重的下标写错了吧w12写成了w21
        张小磊啊:@2B考试专用橡皮Chris 感谢你提出的意见。
      • 918c52a9c73e:您好,今天看了您的文章,有几个问题问下您,感觉这个定义有一些不清楚。首先输出层是层3还是层2,用a表示第l层,后面有了a3,那我理解输出层是第三层,但是看权重w,上标又全都是2,表示的是第l层和l-1层的权重,这么看输出层又是第二层,希望您解答一下。
        还有就是c点的误差和e以及f有关,我觉得e点前面的那个权重的分子按您的意思应该是c->e的w,分母是c-e的w加上d-e的w,但是按您的定义w21应该是c-f的w

        认真看了您的文章,写的很好,这两点我都有点疑惑,希望您能解答
        张小磊啊:@徐亨如_d383 确实下标容易搞混,谢谢你仔细阅读了我的文章,对于你提出的问题我会认真修改哒
      • JW费心思:如此好的文章没人评论?
        有一点想不通,请教下大神:这一段“其中输出层、隐藏层节点的误差如图所示,输出层误差已知,接下来对隐藏层第一个节点c作误差分析。还是站在节点c上,不同的是这次是往前看(输出层的方向),可以看到指向c节点的两个蓝色粗箭头是从节点e和节点f开始的,因此对于节点c的误差肯定是和输出层的节点e和f有关。”

        为什么c的误差=d的误差×w11+f的误差×w21, w11不是c节点到d节点的权重吗?为啥反过来计算时,不是除法而是乘法呢?
        张小磊啊:你好,大神算不上,只是最近想搞清楚这块,希望以后可以互相学习。
        你是不是打错了,c的误差是跟e和f有关,而不是d。文中也提到了,原始情况是按照比例来算的,但你会发现表示起来比较繁琐,如果能够简化到前向传播那样的形式就更好了。只要不破坏它们的比例就好,因此我们可以忽略掉分母部分,这样其实看着跟乘起来差不多,但实际上他们是都要除以分母的。

      本文标题:一文搞懂反向传播算法

      本文链接:https://www.haomeiwen.com/subject/kkhqjxtx.html