微分算法
前言
我们在接触深度学习框架 pytorch 的时候,经常会听到 “自动微分” 这个词,以及他相较于传统微分算法的种种优点,那什么是微分算法,有哪些微分算法,和我们大学数学中学的微积分有什么关系与区别。这几个问题我将在下面一一解答。
微分算法是什么
微分算法是指通过编程实现求导。
在数学中,导数和微分是不混为一谈的,微分关注的是变化量 / 有量纲 /
在计算机中,我们不严格区分两者,因为计算机中最主要的目的就是计算导数,用于反向传播等。所以微分算法的目的就是在于求导。
微分算法的实现
一共有 4 种实现:
手动微分
人工推导目标函数对求导变量的求导公式,然后编程实现
缺点:
- 费时费力,容易出错
- 对每个目标函数都要推导,灵活性差
符号微分
类似于我们大学中求导时写的步骤,得到的是导函数的解析表达式
只要人工设定求导规则即可。得到导数的解析表达式之后再将具体数值代入,就可以得到任意点的导数值。
计算得到的表达式需要用字符串或者其他数据结构存储,如表达式树(语法树)。 Python 的 sympy 实现了这类算法
缺点:
- 深层符合函数,比如神经网络等,得到的计算公式十分冗长,即表达式膨胀
- 机器学习的应用一般只需要得到函数在某一点的具体数值,不需要表达式字符串,计算和存储存在冗余
数值微分
用导数的定义公式进行计算,有前向差分与中心差分
前向差分:
中心差分:
缺点:
- 数值微分存在误差
- 根据公式可以看出,每个自变量求偏导的时候需要计算两次函数值
一般只用于检验别的算法结果的正确性
自动微分
自动微分(Auto Differentiation)也称自动求导,是反向传播算法的一般化。
介于符号微分和数值微分之间。数值微分一开始就把自变量的数值代入函数,近似计算该点的导数值;符号微分先得到表达式,最后才代入自变量的值得到该点处的导数值。而自动微分将符号应用于最基本的运算(原子操作),如常数、幂函数、指数函数、对数函数等,代入自变量的值得到其导数值,作为中间结果进行保留,最后根据这些基本运算单元的求导结果计算出整个函数的导数值
我记得 cs231n 里有教手写这个,到时候去看看
参考资料
《机器学习的数学》(雷明著)3.6 节