美文网首页MXNET神经网络
[NL系列] 计算图的微积分——反向传播

[NL系列] 计算图的微积分——反向传播

作者: ToeKnee | 来源:发表于2016-05-17 23:24 被阅读476次

    基本上是翻译自 Calculus on Computational Graphs: Backpropagation。作者是 Chris Olah,在2012年获得了Thiel Fellowship,由PayPal共同创办人 Peter Thiel 在2010年提出的用于资助20岁以下优秀青少年的10万美元奖学金,让他们辍学去改变世界。

    简介


    反向传播 Backpropagation是使得训练深层神经网络模型在计算上易于处理的关键算法。除了在深度网络中应用之外,反向传播在其他领域(天气预报、数值计算等等)作为计算工具功能也很强大,只是在不同领域的称呼不同而已。事实上,反向传播在不同领域至少被“重新发现”过十多次(见Griewank(2010))。一般来说,其独立于领域的名称叫做 反向模式分化 (reverse-mode differentiation)
    基本上,反向传播是一种快速计算导数的方法。熟练掌握反向传播,不仅在深度学习中有所裨益,在其他更多的数值计算问题中都有很大好处。

    计算图


    计算图可以很好的描述数学表达式,比如对于


    这种计算图在函数式编程里经常会出现,概念上和 依赖图 dependency graphs 以及 调用图 call graphs 很相似。这也是当前流行的深度学习框架Theano的核心(MXnet也是如此)。
    我们可以通过给变量赋予初值,并通过从下到上的计算来给这个表达式赋值,比如当设定* a = 2, b = 1 *时

    此时表达式被赋值为6。

    计算图中的导数


    想要理解计算图中的导数,核心是要明白边上的导数是怎么回事。如果 a 变化了一点, c 会怎么变?这称之为 ca偏导数。偏导数满足加法律乘法律,即
    ![][5]
    [5]: https://latex.codecogs.com/svg.latex?\frac{\partial}{\partial&space;a}(a+b)&space;=&space;\frac{\partial&space;a}{\partial&space;a}&space;+&space;\frac{\partial&space;b}{\partial&space;a}&space;=&space;1
    ![][6]
    [6]: https://latex.codecogs.com/svg.latex?\frac{\partial}{\partial&space;u}uv&space;=&space;u\frac{\partial&space;v}{\partial&space;u}&space;+&space;v\frac{\partial&space;u}{\partial&space;u}&space;=&space;v
    下面的计算图中,每条边上都标注了偏导数。


    那要怎样理解不直接连接的节点之间的相互影响呢?我们看 e 是如何影响 a 的:假设 a 以速度1变化, c 也以速度1变化,同时,c 以速度1变化将会导致 e 以速度2变化。因此 e 以速度 2 随着 a 变化。
    一般的法则是,把从一个结点到另一个结点的所有可能路径加起来,每条路径所有经过边的偏导值相乘。比如要计算 eb 的偏导值,我们有
    ![][7]
    [7]: https://latex.codecogs.com/svg.latex?\frac{\partial&space;e}{\partial&space;b}=&space;12&space;+&space;13
    这就是 b 如何通过 cd 影响 e
    这种“把所有路径相加”的想法,其实就是链式法则的另一种思路。

    路径分解


    只用“所有路径相加”的方法带来的问题是,很容易遇到可能路径数量多到“爆炸”的情况,比如


    在这个图中, XY 有三条路,YZ 又有三条路,这样的话如果我们要计算 ZX 的偏导数,要做到“所有路径相加”,必须计算9条路径的加法。
    ![][8]
    [8]: https://latex.codecogs.com/svg.latex?\frac{\partial&space;Z}{\partial&space;X}&space;=&space;\alpha\delta&space;+&space;\alpha\epsilon&space;+&space;\alpha\zeta&space;+&space;\beta\delta&space;+&space;\beta\epsilon&space;+&space;\beta\zeta&space;+&space;\gamma\delta&space;+&space;\gamma\epsilon&space;+&space;\gamma\zeta
    这幅图里只有9条路径,但是随着图的规模增大,路径数量很容易呈指数增长爆发。
    因此,不同于只是简单的把所有路径加起来,我们应该把路径进行分解,即
    ![][9]
    [9]: https://latex.codecogs.com/svg.latex?\frac{\partial&space;Z}{\partial&space;X}&space;=&space;(\alpha&space;+&space;\beta&space;+&space;\gamma)(\delta&space;+&space;\epsilon&space;+&space;\zeta)
    这就是 前向模式分化 (forward-mode differentiation)反向模式分化 (reverse-mode differentiation) 的思想,它们通过路径分解高效的求和。不同于 显示 (explicitly) 的分开求解方式,这种思想把每个节点发出的路径合并起来。事实上,两种算法对于每条边都只用了一次。

    前向模式分化 (forward-mode differentiation) 从计算图的输入开始一直到图的末端。每个节点把指向其的所有路径加起来,每条路径代表着影响该节点的一个因素。把这些因素都加起来,我们就得到了每个节点受到输入产生的所有影响,这就是导数。
    反向模式分化 (reverse-mode differentiation) 则是从计算图的输出开始一直到图的起点。每个节点把从其发出的所有路径加起来。

    前向模式分化 (forward-mode differentiation) 跟踪了一个输入是如何影响每个节点的,而 反向模式分化 (reverse-mode differentiation) 则是跟踪了每个节点是如何影响一个输出的。在微积分里,这就指的是 前向模式分化 (forward-mode differentiation) 对每个节点都执行了 对 X 求偏导 的操作,而 反向模式分化 (reverse-mode differentiation) 对每个节点都执行了 Z 对其求偏导 的操作。

    计算的……胜利!?


    那么 反向模式分化 (reverse-mode differentiation) 的优点在哪?


    还是考虑这个例子,我们使用 前向模式分化 (forward-mode differentiation)b 开始往上传播,这样就得到了每个节点对 b 的偏导数。

    这样我们就得到了 eb 的偏导数,即计算图的输出对某一个输入的偏导数。
    如果从 e 开始一步一步向下执行 反向模式分化 (reverse-mode differentiation) 会怎么样呢?这就得到了 e 对每个节点的偏导数。

    可以看到,与 前向模式分化 (forward-mode differentiation) 只得到输出对 某一个输入 的偏导数不同的是,反向模式分化 (reverse-mode differentiation) 得到了 每一个输入 对输出的偏导数。
    对于这个图来说,这只提速了两倍(两个输入,一个输出)。然而对于一个有大量输入,却只有少量输出的复杂图来说,这个加速比就很可观了。
    在训练神经网络时,我们会考虑计算网络输出与实际的差值(也就是所谓的 代价 )对于所有网络参数的偏导数,将其用到梯度下降当中。由于一个神经网络中经常有上百万、甚至上千万个参数,那么 反向模式分化 (reverse-mode differentiation) (在神经网络中称为 反向传播 (backpropagation) )就可以带来巨大的加速比。

    这看起来好像没什么大不了的啊!?

    反向传播 (backpropagation) 其实就是链式法则,然而这也像看起来那么简单。想当年发明 反向传播 (backpropagation) 的时候,人们并没有很关注 前馈网络 的研究,也没有发现应该使用偏导数来训练网络。

    Those are only obvious once you realize you can quickly calculate derivatives. There was a circular dependency.

    结论——你应该明白的东西


    • 导数要比你想象的简单很多!
    • 反向传播 (backpropagation) 对于理解导数是如何在一个模型中传播的也很有帮助。了解了它之后你就会知道为什么会有 梯度扩散 的问题了。

    这篇只是对 反向传播 (backpropagation) 的一个简介,想要了解神经网络中如何更详细的使用请参看 Michael Nielsen’s 的文章。翻译版本在这里有。

    译完之后


    才发现这篇文章还真是很通俗的介绍了一下反向传播的概念(和优点?感觉也没有说的很全面,应该是提炼出了核心优势吧)。估计还是要继续去看Olah推荐的那篇文章才能有更深刻的理解。

    相关文章

      网友评论

      • 刀刀宁:梯度下降是GD, Backpropagation是反向传播。。。
        ToeKnee:@刀刀宁 :joy: 改过来了,脑抽了

      本文标题:[NL系列] 计算图的微积分——反向传播

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