目录
自动微分
在进行问题求解和优化时要不可避免的使用梯度。手工计算梯度过于复杂且容易出错,而各种编程环境提供了自动微分即自动计算梯度的方法。数值微分,符号微分,前向自动微分和后向自动微分是四种主要的自动微分方法。
1.1 数值微分
-
定义
用数字计算偏导的近似值,如函数 h ( x ) h(x) h(x) 的导数 h ′ ( x 0 ) h'(x_0) h′(x0) 为函数在点 x 0 x_0 x0 处的斜率,或用如下方程计算: (1.1) h ′ ( x 0 ) = lim ϵ → 0 h ( x 0 + ϵ ) − h ( x 0 ) ϵ h'(x_0)=\lim_{\epsilon \to 0} \frac{h(x_0+\epsilon)-h(x_0)}{\epsilon}\tag{1.1} h′(x0)=ϵ→0limϵh(x0+ϵ)−h(x0)(1.1) -
代码
def f(x,y): return(x**2*y+y+2) def derivative(f, x, y, x_eps, y_eps) return(f(x+x_eps, y+y_eps)-f(x, y))/(x_eps+y_eps) df_dx = derivative(f, 3, 4, 0.00001, 0) df_dy = derivative(f, 3, 4, 0, 0.00001)
-
优缺点
优点:比较容易实现,是检查其它方法是否正确实施的好工具;可以处理用任意代码定义的函数。
缺点:准确度比较差,实现较为琐碎。
我个人理解数值微分就是为变量赋予特定的值及其变化量,然后利用公式(1.1)计算该点处的偏导值。
1.2 符号微分
-
定义
构建一个完全不同的图,通过微积分计算规则(如Mathematica, Maple等)自动求出函数导数的解析解1,本文将用一个例子进行较为详细的解释。 -
例子
下例通过符号微分的方式求方程 g ( x , y ) = 5 + x y g(x,y)=5+xy g(x,y)=5+xy 对 x x x 的偏导数。

程序先计算叶子节点的偏导数。常数节点的偏导为0。变量 x x x 的偏导为1,同时变量 y y y对 x x x的偏导为0。由微积分的知识可知,两个函数 u u u和 v v v的乘积的偏导为: ∂ ( u × v ) ∂ x = ∂ u ∂ x × v + ∂ v ∂ x × u \frac{\partial(u\times v)}{\partial x}=\frac{\partial u}{\partial x}\times v+\frac{\partial v}{\partial x}\times u ∂x∂(u×v)=∂x∂u×v+∂x∂v×u,所以 x y xy xy的偏导为 0 × x + 1 × y 0\times x+1\times y 0×x+1×y。再由微积分知识可知,两个函数的和的偏导为它们各自偏导的和,所以 5 + x y 5+xy 5+xy的偏导为 0 + ( 0 × x + 1 × y ) = y 0+(0\times x+1\times y)=y 0+(0×x+1×y)=y。
- 优缺点
优点:准确度较高。
缺点:对于复杂函数会产生巨大的图,导致性能降低,并且它不能处理用任意代码定义的函数。
我个人理解符号微分就是利用微积分计算规则将偏导数用公式或符号的形式表示出来。
1.3 前向自动微分
-
定义
前向自动微分是数值微分与符号微分的结合体。它依赖于对偶数,即形如 a + b ϵ a+b\epsilon a+bϵ 的数字,其中 a a a 和 b b b 是实数, ϵ \epsilon ϵ 是使 ϵ 2 = 0 \epsilon^2=0 ϵ2=0( ϵ ≠ 0 \epsilon \neq 0 ϵ̸=0)的无限小数。类似于数值微分,都是为变量假设一个变化量。然后根据对偶数的相关操作可以得出 h ( a + b ϵ ) = h ( a ) + b h ′ ( a ) ϵ h(a+b\epsilon)=h(a)+b h'(a)\epsilon h(a+bϵ)=h(a)+bh′(a)ϵ,建立计算图计算 h ( a + ϵ ) h(a+\epsilon) h(a+ϵ) 的表达式, ϵ \epsilon ϵ 前的系数即为函数的偏导数。具体使用可见下面的例子。 -
例子
下图通过正向微分的方式求方程 g ( x , y ) = x 2 y + y + 2 g(x,y)=x^2y+y+2 g(x,y)=x2y+y+2 对 x x x 的偏导数。

当要求对 y y y 的偏导数时再次使用该图,但参数修改为 x = 3 , y = 4 + ϵ x=3, y=4+\epsilon x=3,y=4+ϵ。
- 优缺点
优点:准确度较高;可以处理用任意代码定义的函数。
缺点:当函数中参数较多时,需要多次遍历图求得所有微分。
1.4 反向自动微分
-
定义
正向自动微分只需遍历图两次便可以求得函数所有微分,其思路类似于神经网络中的反向传播算法。它首先正向遍历图的每一个节点,,然后再反向遍历第二遍。在第一次遍历期间,它会算出所有节点的值,而第二次遍历时它会算出下一节点对上一节点的偏导数(将节点假设为一个变量 n n n,即将节点视为一个整体,不关心其内部构成)。具体使用见如下例子。 -
例子
下图通过反向自动微分求函数 g ( x , y ) = x 2 y + y + 2 g(x,y)=x^2y+y+2 g(x,y)=x2y+y+2 的所有偏导数。

节点右下角标示了当 x = 3 x=3 x=3 且 y = 4 y=4 y=4 时各节点的值。各节点被标记为 n 1 n_1 n1 到 n 7 n_7 n7。第二次遍历求偏导利用的是链式法则: ∂ f ∂ x = ∂ f ∂ n i × ∂ n i ∂ x \frac{\partial f}{\partial x}=\frac{\partial f}{\partial n_i}\times\frac{\partial n_i}{\partial x} ∂x∂f=∂ni∂f×∂x∂ni。
- 易知, f = n 7 f=n_7 f=n7,所以 ∂ f ∂ n 7 = 1 \frac{\partial f}{\partial n_7}=1 ∂n7∂f=1。
- 由图可知, n 7 = n 5 + n 6 n_7=n_5+n_6 n7=n5+n6,所以 ∂ n 7 ∂ n 5 = 1 \frac{\partial n_7}{\partial n_5}=1 ∂n5∂n7=1,那么 ∂ f ∂ n 5 = ∂ f ∂ n 7 × ∂ n 7 ∂ n 5 = 1 \frac{\partial f}{\partial n_5}=\frac{\partial f}{\partial n_7}\times\frac{\partial n_7}{\partial n_5}=1 ∂n5∂f=∂n7∂f×∂n5∂n7=1。
- 与2同理,可以得到 ∂ f ∂ n 6 = ∂ f ∂ n 7 × ∂ n 7 ∂ n 6 = 1 \frac{\partial f}{\partial n_6}=\frac{\partial f}{\partial n_7}\times\frac{\partial n_7}{\partial n_6}=1 ∂n6∂f=∂n7∂f×∂n6∂n7=1。
- 由图可知, n 5 = n 4 × n 2 n_5=n_4\times n_2 n5=n4×n2,所以 ∂ n 5 ∂ n 4 = n 2 \frac{\partial n_5}{\partial n_4}=n2 ∂n4∂n5=n2 且 ∂ n 5 ∂ n 2 = n 9 \frac{\partial n_5}{\partial n_2}=n_9 ∂n2∂n5=n9,那么 ∂ f ∂ n 4 = ∂ f ∂ n 5 × ∂ n 5 ∂ n 4 = 1 × n 2 = 4 \frac{\partial f}{\partial n_4}=\frac{\partial f}{\partial n_5}\times\frac{\partial n_5}{\partial n_4}=1\times n_2=4 ∂n4∂f=∂n5∂f×∂n4∂n5=1×n2=4 且 ∂ f ∂ n 2 = ∂ f ∂ n 5 × ∂ n 5 ∂ n 2 = 1 × n 4 = 9 \frac{\partial f}{\partial n_2}=\frac{\partial f}{\partial n_5}\times\frac{\partial n_5}{\partial n_2}=1\times n_4=9 ∂n2∂f=∂n5∂f×∂n2∂n5=1×n4=9。
- 与4同理,可以得到 ∂ f ∂ n 2 = ∂ f ∂ n 6 × ∂ n 6 ∂ n 2 = 1 \frac{\partial f}{\partial n_2}=\frac{\partial f}{\partial n_6}\times\frac{\partial n_6}{\partial n_2}=1 ∂n2∂f=∂n6∂f×∂n2∂n6=1 且 ∂ f ∂ n 3 = ∂ f ∂ n 6 × ∂ n 6 ∂ n 3 = 1 \frac{\partial f}{\partial n_3}=\frac{\partial f}{\partial n_6}\times\frac{\partial n_6}{\partial n_3}=1 ∂n3∂f=∂n6∂f×∂n3∂n6=1。
- 由图可知, f = n 7 = n 5 + n 6 = n 2 × n 4 + n 2 + n 3 = y × n 4 + y f=n_7=n_5+n_6=n_2\times n_4+n_2+n_3=y\times n_4+y f=n7=n5+n6=n2×n4+n2+n3=y×n4+y,所以 ∂ f ∂ y = n 4 + 1 = 10 \frac{\partial f}{\partial y}=n_4+1=10 ∂y∂f=n4+1=10。
- 易知, ∂ n 4 ∂ x = 2 x \frac{\partial n_4}{\partial x}=2x ∂x∂n4=2x,所以 f r a c ∂ f ∂ x = 4 × 2 x = 24 frac{\partial f}{\partial x}=4\times 2x=24 frac∂f∂x=4×2x=24。
- 优缺点
优点:准确度较高;可以处理用任意代码定义的函数;速度快。
缺点:暂时不知道。
1.5 参考
[1] inkfish-talk.计算机求导的四种方法
[2] Geron.机器学习实战