• 自动求导 (Automatic Differentiation, AD)


    2021-03-04

    作者:董鑫
    链接:https://www.zhihu.com/question/66200879/answer/870023448
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    自动求导 (Automatic Differentiation, AD) 的课程 (CS207),正好来回答一下。 其实不只是 TensorFlow,Pytorch 这些为深度学习设计的库用到 AD,很多物理,化学等基础科学计算软件也在大量的使用 AD。而且,其实TensorFlow、Pytorch 也并非只能用于deep learning,本质上他们是一种

    Tensor computation built on a tape-based autograd system --引自Pytorch

     

     

    自动求导分成两种模式,一种是 Forward Mode,另外一种是 Reverse Mode。一般的机器学习库用的后一种,原因后面说。

    Forward Mode

    基于的就是就基本的 链式法则 chain rule,

    [公式]

    这个 Forward Mode 就是用 chain rule,像剥洋葱一样一层一层算出来

    [公式]

    为例。 我们可以把他的计算图画出来。

    假如我要 计算 [公式] ,可以根据上面的图得到一个表格

    那么上面这个表里,每一步我们既要算 forward 的值 [公式] ,也要算 backward 的值 [公式]

     

    有没有办法同时把这两个值算出来呢?

     

     

    首先引入一个新的概念,二元数。二元数其实跟复数差不多,也是一种实数的推广。我们回忆一下,一个复数可以写成这样的形式:

    [公式]

    对于复数的理解,一个比较直观的例子就是。本来实数都是在一个实数轴(x轴)的。复部 [公式] 相当于多了一个 y 轴出来。

    那么二元数是这个亚子,

    [公式]

    这个二元数很神奇的一个性质是,你带着他做运算,得出来的二元部 [公式] 前面的系数,就是导数。举个栗子, 我们要求

    [公式]

    我们可以把 [公式] ,所以

    [公式]

    我们把上面的三角函数展开,

    [公式]

    得到

    [公式]

    可以看到,二元部 [公式] 恰好就是原函数 [公式] 的导数。

    Reverse Mode

    这个模式就比较简单和直接了。就是说,上面那个表里面,我每次只计算每个“小运算”的梯度(也是是那个图里面的每个节点),最后我再根据 chain rule 把“小运算”们的梯度串起来。其实 forward modereverse mode 并没有本质的区别,只是说,reverse mode在计算梯度先不考虑 chain rule,最后再用 chain rule 把梯度组起来。而前者则是直接就应用 chain rule 来算梯度。

    下面总结一下 reverse mode 的流程:

    • 创建计算图
    • 计算前向传播的值及每个操作的梯度
      • 这里没有 chain rule 的事
      • 比如这个操作是乘法 $x_3 = x_1*x_2$,那么我们只需要把 [公式] 算出来就好了
    • 反向计算梯度从最后一个节点(操作)开始: [公式]
    • 根据 chain rule 逐层推进 [公式]
    • 假如有多条求导路径,我们要把他们加起来,例如 [公式]

     

    举个栗子,我们要计算函数

    [公式]

    在点 [公式] 的导数

    首先还是先把计算图画出来

    我们逐层的抽丝剥茧,

    [公式]

    总结

    1. 可以很清楚的看到,在训练人工神经网络时常用的 backpropagation 也是属于 reverse mode 的。
    2. 假如我们要计算的梯度的函数是 [公式]
    • 如果 n 是相对比较大的话,用 forward 比较省计算
    • 如果 m 是相对比较大的话,用 reverse 比较省计算
  • 相关阅读:
    java和.NET的比较
    联想笔记本不能无线上网
    js根据给定的日期计算当月有多少天
    jQuery中live()变更
    C#操作xml文件
    SQL server的with的用法(一)
    jquery拖拽实现UI设计组件
    自定义弹出框
    第一个超级简单Node.js实例
    windows 下使用redis
  • 原文地址:https://www.cnblogs.com/zhangchao0515/p/14480761.html
Copyright © 2020-2023  润新知