符号微分 · 机械的规则

符号求导是符号计算里最「顺」的操作:一组有限的规则,机械地递归应用,总能算、还精确。这一章看 SymPy 的 diff、高阶与偏导,并说清它和数值微分的天壤之别,以及它如何长成了深度学习的引擎——自动微分。

作者 David更新于 第 9 篇(共 18 篇)

符号微分 · 机械的规则

进入微积分的符号版。第一站是求导,而它有个让人愉快的性质:简单。我们在「计算即重写」那章已经剧透过——求导不过是几条规则递归地作用在树上。这一章把它讲全,并揭示它一个了不起的现代身份。

diff:总能算,还精确

SymPy 的 diff 求导,信手拈来:

from sympy import *
x, y = symbols('x y')

print(diff(sin(x**2), x))          # 2*x*cos(x**2)         —— 链式法则
print(diff(exp(x)*sin(x), x))      # exp(x)*sin(x) + exp(x)*cos(x)   —— 乘积法则
print(diff(x**3, x, 2))            # 6*x                   —— 二阶导(求两次)
print(diff(x**2 * y**3, x, y))     # 6*x*y**2              —— 混合偏导 ∂²/∂x∂y

链式、乘积、幂、偏导、高阶……全都手到擒来,而且结果精确。这背后没有任何近似——就是那五条规则(和的导数=导数的和、乘积法则、幂法则、链式法则……)机械地递归到底。

求导是「可判定、可机械化」的典范:任何初等函数,求导规则都是有限的、确定的,一步步套下去,一定能得到答案。 没有搜索、没有猜测、没有「算不出来」。这和下一章的积分形成刺眼的对比——那里没有万能规则,有些函数甚至根本没有初等原函数。求导易如反掌,积分举步维艰——这个不对称是微积分符号版最迷人的主题。

和数值微分,天壤之别

还记得孪生专栏里数值微分那章的痛苦吗?用差商 f(x+h)−f(x)h\frac{f(x+h)-f(x)}{h} 近似导数,hh 太大不准、太小又被灾难性抵消反噬,误差呈 U 形,存在一个尴尬的「最优 hh」。符号微分把这些痛苦一扫而空:

数值微分符号微分
怎么算差商近似 f(x+h)−f(x)h\frac{f(x+h)-f(x)}{h}套求导规则
要选步长 hh 吗要,还很难选不用
精度有截断 + 抵消误差(U 形)精确,无误差
给出的是某一点的一个近似数整个导函数的公式
局限每点都得重算、误差难控表达式可能膨胀

符号微分给的不是「x=1x=1 处导数约等于 0.540.54」,而是整条导函数 cos⁡x\cos x——精确、解析、放之四海。当你需要的是公式(而非某点的一个数)时,符号微分无可替代。

它的现代身份:自动微分

符号微分最耀眼的地方,是它悄悄长成了深度学习的引擎。训练神经网络要对上百万参数求梯度,靠的是自动微分(automatic differentiation, autodiff)——而 autodiff 的灵魂,正是符号微分那套求导规则:

自动微分 = 把符号求导的链式法则,施加到「计算图」上。 神经网络的前向计算是一张由加、乘、exp、max 等运算搭成的树 / 图。反向传播做的,就是沿着这张图,机械地套链式法则,把梯度一层层传回去——和符号微分同一套规则。

区别只在工程手法:纯符号微分会把导数写成一个大表达式(容易膨胀);而 autodiff 一边算数值、一边套规则,复用中间结果,避免了表达式爆炸。可以说,autodiff 是符号微分规则 + 数值求值的联姻——PyTorch、JAX、TensorFlow 每天在 GPU 上跑的,正是这门古老符号手艺的现代化身。求导规则的机械性,是整个深度学习得以自动化的根基。

小结与下一章

符号微分是机械、可判定、精确的:一组有限的求导规则递归套用,链式 / 乘积 / 高阶 / 偏导皆信手拈来(diff),给出的是整条导函数而非某点近似——彻底摆脱数值微分的步长与 U 形误差之苦。它更是自动微分的灵魂:把链式法则施加到计算图上,撑起了整个深度学习。

求导这么顺,积分呢?下一章你会撞上一堵墙:积分没有万能规则,有的函数根本没有初等原函数,而计算机能证明这一点。这堵墙背后,是符号积分深刻而美丽的理论——Risch 算法。👉 符号积分:为什么难得多。

参考文献

本页目录