附录D——自动微分(Autodiff)
本文介绍了五种微分方式,最后两种才是自动微分。
前两种方法求出了原函数对应的导函数,后三种方法只是求出了某一点的导数。
假设原函数是$f(x,y) = x^2y + y +2$,需要求其偏导数$\frac{\partial f}{\partial x}$和$\frac{\partial f}{\partial y}$,以便应用于梯度下降等算法。
1、手工求导
该方法比较简单,就是自备纸笔,应用基本的求导规则,以及链式求导法则,人工求导。缺点是对于复杂函数容易出错。幸运的是,这一计算过程可由计算机帮我们完成,这就是符号微分。
2、符号微分(Symbolic Differentiation)
如图D-1所示,使用符号微分的方法,计算函数$g(x,y) = 5 + xy$的偏导数。该图左侧代表函数$g(x,y)$,右侧代表$g(x,y)$关于$x$的偏导数$\frac{\partial g}{\partial x} = 0 + (0 \times x + y \times 1) = y$(同样的,可以求得$\frac{\partial g}{\partial y}$)。

图D-1 符号微分
该算法首先求叶子节点关于$x$的偏导数,然后沿着树向上,求得其他节点关于自变量的偏导数。这与手工求导所使用的规则是一样的。
如果函数复杂,该算法生成的树将十分庞大,性能不高。而且无法对很随意的代码求导,例如:
def my_func(a, b):
z = 0
for i in range(100):
z = a * np.cos(z + i) + z * np.sin(b - i)
return z
3、数值微分(Numerical Differentiation)
这是根据导数的定义来求解的。函数$h(x)$在$x_0$点的导数为:
$h'(x) = \lim_{\varepsilon \rightarrow 0} \frac{h(x_0 + \varepsilon) - h(x_0)}{\varepsilon}$
我们取一个很小的$\varepsilon$,带入公式进行计算即可。该方法所得结果不够精确,参数过多时计算量也比较大。但是计算起来很简单,可用于校验手工算出的导数是否正确。
如果有1000个参数,至少需要调用$h(x)$1001词,来求得所有偏导数。
4、前向自动微分(Forward-Mode Autodiff)
该算法依赖一个虚数(dual numbers,这让我想起来oracle的虚表。难度dual可以表示虚无的意思?) $\varepsilon$,满足$\varepsilon^2 = 0$但是$\varepsilon \neq 0$(姑且理解为一阶无穷小吧)。
由于$\varepsilon$是无穷小,因此满足$h(a + b \varepsilon) = h(a) + b \times h'(a)\varepsilon$。因此,算出$h(a + \varepsilon) $可以同时得到$h(a)$和$h'(a)$,如图D-2所示。

图D-2 前向自动微分
上图值计算了$\frac{\partial f}{\partial x}(3,4)$,同样的方法可以算的$\frac{\partial f}{\partial y}(3,4)$。
如果有1000个参数,需要遍历上图1000次,来求得所有偏导数。
5、反向自动微分(Reverse-Mode Autodiff)
这是TensorFlow所采用的自动微分算法。如图D-3所示,该算法首先前向(也就是从输入到输出)计算每个节点的值,然后反向(从输出到输入)计算所有的偏导数。

图D-3 反向自动微分
反向计算时应用链式求导法则:
$\frac{\partial f}{\partial x} = \frac{\partial f}{\partial n_i} \times \frac{\partial n_i}{\partial x}$
由于$n_7$就是输出节点,$f = n_7$,因此$\frac{\partial f}{\partial n_7} = 1$。
该算法强大且精确,尤其是输入很多,输出很少时。假如函数有10个输出(不管输入是1千,2万还是更多),求得所有偏导数需要对上图遍历11次。
各个算法比较:

附录D——自动微分(Autodiff)的更多相关文章
- (转)自动微分(Automatic Differentiation)简介——tensorflow核心原理
现代深度学习系统中(比如MXNet, TensorFlow等)都用到了一种技术——自动微分.在此之前,机器学习社区中很少发挥这个利器,一般都是用Backpropagation进行梯度求解,然后进行SG ...
- pytorch学习-AUTOGRAD: AUTOMATIC DIFFERENTIATION自动微分
参考:https://pytorch.org/tutorials/beginner/blitz/autograd_tutorial.html#sphx-glr-beginner-blitz-autog ...
- 自动微分(AD)学习笔记
1.自动微分(AD) 作者:李济深链接:https://www.zhihu.com/question/48356514/answer/125175491来源:知乎著作权归作者所有.商业转载请联系作者获 ...
- <转>如何用C++实现自动微分
作者:李瞬生转摘链接:https://www.zhihu.com/question/48356514/answer/123290631来源:知乎著作权归作者所有. 实现 AD 有两种方式,函数重载与代 ...
- PyTorch自动微分基本原理
序言:在训练一个神经网络时,梯度的计算是一个关键的步骤,它为神经网络的优化提供了关键数据.但是在面临复杂神经网络的时候导数的计算就成为一个难题,要求人们解出复杂.高维的方程是不现实的.这就是自动微分出 ...
- 【tensorflow2.0】自动微分机制
神经网络通常依赖反向传播求梯度来更新网络参数,求梯度过程通常是一件非常复杂而容易出错的事情. 而深度学习框架可以帮助我们自动地完成这种求梯度运算. Tensorflow一般使用梯度磁带tf.Gradi ...
- PyTorch 自动微分示例
PyTorch 自动微分示例 autograd 包是 PyTorch 中所有神经网络的核心.首先简要地介绍,然后训练第一个神经网络.autograd 软件包为 Tensors 上的所有算子提供自动微分 ...
- PyTorch 自动微分
PyTorch 自动微分 autograd 包是 PyTorch 中所有神经网络的核心.首先简要地介绍,然后将会去训练的第一个神经网络.该 autograd 软件包为 Tensors 上的所有操作提供 ...
- MindSpore:自动微分
MindSpore:自动微分 作为一款「全场景 AI 框架」,MindSpore 是人工智能解决方案的重要组成部分,与 TensorFlow.PyTorch.PaddlePaddle 等流行深度学习框 ...
随机推荐
- ViewPager切换动画PageTransformer的使用
Android从3.0开始添加了属性动画后,诸多难以实现的动画都可以轻松解决了,v4包下的ViewPager控件当然也不例外,相对于非常平庸的默认切换动画,Google官方给我们展示了两个动画例子:D ...
- 第一个Polymer应用 - (2)创建你自己的元素
原文链接: Step 2: Your own element翻译日期: 2014年7月6日翻译人员: 铁锚通过上一节的学习和实践, 您已经完成了一个基本的应用程序结构(application stru ...
- iOS监听模式系列之对APNs的认知与理解
前言: APNs 协议在近两年的 WWDC 上改过两次, 15 年 12 月 17 日更是推出了革命性的新特性.但在国内传播的博客.面试题里关于 APNs 的答案全都是旧的.错的. 导航: 对 APN ...
- Java继承与多态
感慨一下,到了现在感觉Java里面很多东西都是模模糊糊,不能这样了,一点点解决吧.今天看了继承与多态的一些内容,感觉看得很浅,先写下来,算是巩固,如果后面看到更好的内容,再慢慢加上去. 继承与多态,他 ...
- 基于 Java Web 的毕业设计选题管理平台--选题报告与需求规格说明书
一.选题报告 目录 团队名称 团队成员 项目名称 项目描述 创新与收益 用户场景分析 真实用户调研 未来市场与竞争 项目导图 比例权重 总结 1.团队名称--指南者团队 2.团队成员 孔潭活:2015 ...
- JVM学习--(五)垃圾回收器
上一篇我们介绍了常见的垃圾回收算法,不同的算法各有各的优缺点,在JVM中并不是单纯的使用某一种算法进行垃圾回收,而是将不同的垃圾回收算法包装在不同的垃圾回收器当中,用户可以根据自身的需求,使用不同的垃 ...
- struts 开发流程
- JavaScript设计模式之一封装
对于熟悉C#和Java的兄弟们,面向对象的三大思想(封装,继承,多态)肯定是了解的,今天我想讲讲如何在Javascript中利用封装这个特性,开讲! 我们会把现实中的一些事物抽象成一个Class并且把 ...
- Java编程语言下Selenium 对于下拉框,单选,多选等选择器的操作
WebElement selector = driver.findElement(By.id("Selector")); Select select = new Select(se ...
- go Mutex (互斥锁)和RWMutex(读写锁)
转载自: https://blog.csdn.net/skh2015java/article/details/60334437 golang中sync包实现了两种锁Mutex (互斥锁)和RWMute ...