Part I · 第 3 章 多元与向量微积分 · 3.3

雅可比:局部线性变换

非线性映射会把方格网弄弯。可只要拿放大镜对准任何一点,弯曲的网格就会变回一张笔直、等距、只是被斜拉过的网格,也就是一个矩阵。这个"放大之后看到的矩阵"就是雅可比矩阵 (Jacobian)。机械臂的速度、EKF 的线性化、逆运动学的每一步迭代,都靠它。

约 25 分钟 前置:1.3 矩阵即变换 · 2.1 导数 · 3.1 偏导 5 个交互

    1为什么机器人需要它

    机械臂的控制器每毫秒都要回答一个问题:"如果让每个关节以某个速度转,手爪会朝哪个方向、以多快的速度移动?"从关节角到手爪位置的映射里全是 sin 和 cos,是弯的、非线性的。控制器想要的答案却是线性的:关节速度乘以一个矩阵,等于手爪速度。

    同样的需求在机器人里随处可见:

    • 扩展卡尔曼滤波 (EKF) 要在当前估计附近,把非线性的传感器模型"拉直"成一个矩阵,才能套用卡尔曼滤波的公式;
    • 视觉 SLAM 与相机标定要知道:三维点挪动一点点,它在图像上的像素会挪多少;
    • 逆运动学和 Gauss-Newton 优化每一步都在问:参数朝哪个方向改,误差下降得最快?

    这些问题找的是同一个东西:一个非线性映射在某一点附近的最佳线性近似。它就是本节的主角。

    2直觉:放大到足够近,弯的都会变直

    先回到一维(2.1 节)。一条曲线远看是弯的,但盯住曲线上一点不断放大,它会越来越像一条直线,也就是那一点的切线。切线的斜率 \(g'(a)\) 就是导数。

    换个说法:在 \(a\) 附近,\(g\) 的行为就像"乘以 \(g'(a)\)"这个最简单的线性映射。输入挪动 \(\delta\),输出就挪动 \(g'(a)\,\delta\)。拖动黄点换个位置,再把放大倍数拉高看看。

    FIG 1放大一条曲线
    青色是曲线 \(g(x)\),黄色虚线是 \(a\) 处的切线。红色横边是输入的挪动 \(\delta\),绿色竖边是切线预测的输出挪动 \(g'(a)\,\delta\)。放大 100 倍后,曲线和切线已经分不开了。

    二维也是同一个故事。回想 1.3 节的橡皮膜:非线性映射 \(f:\R^2\to\R^2\) 把膜上的方格网弄得弯弯曲曲。可是用放大镜对准某一点 \(\mathbf p\),放得越大,看到的网格就越接近笔直、平行、等距,只是被斜拉、旋转、伸缩过。这正是 1.3 节里线性变换的样子,而线性变换就是一个矩阵。

    这个矩阵只属于 \(\mathbf p\) 这一点,换一个点,放大后看到的斜网格就不一样。它叫做 \(f\) 在 \(\mathbf p\) 处的雅可比矩阵 \(J(\mathbf p)\):

    $$ f(\mathbf p + \boldsymbol\delta) \;\approx\; \cv{f(\mathbf p)} \;+\; \cw{J(\mathbf p)}\,\boldsymbol\delta \qquad (\boldsymbol\delta \text{ small}) $$
    核心洞见

    雅可比矩阵就是放大之后看到的那个线性变换。按 1.3 节的读法读它的列:第 1 列是"沿第 1 个输入方向轻推一下,输出往哪走、走多快",第 2 列是"沿第 2 个输入方向轻推一下"。所以第 \(j\) 列就是偏导数 \(\partial f/\partial x_j\)(3.1 节)。

    3动手玩:雅可比实验室

    左边是输入平面:拖动黄点 \(\mathbf p\),它周围有一个边长为 \(h\) 的小方块。右边是输出平面:青色的弯曲网格是 \(f\) 作用之后的网格;黄色区域是小方块的真实像(边是弯的);紫色虚线平行四边形是雅可比的预测 \(f(\mathbf p) + J\,\boldsymbol\delta\)。切换到"放大"视图,再把 \(h\) 往小拉,看两者如何重合。

    FIG 2雅可比实验室
    小方块的红边沿第 1 个输入方向,绿边沿第 2 个输入方向;它们的像在右边仍用红、绿表示。穿过 \(\mathbf p\) 的两条网格线也标成了红、绿。黄色是真实的像,紫色虚线是线性预测,短红线连接对应的角点,长度就是误差。注意:把 \(h\) 减半,角点误差大约变成原来的四分之一。
    试一试
    • 把 \(h\) 缩小,直到相对误差低于 1%:这时弯曲的像和平行四边形已经肉眼难辨。
    • 找一个让 \(J\) 退化(\(\det J \approx 0\))的点。提示:试试"复平方"的原点,或者极坐标里的 \(r = 0\)。小方块的像变成了什么?
    • 在"镜头畸变"里找一个让网格翻面(\(\det J < 0\))的点。它们都在一个圆环外面,那个圆环就是"折痕"。

    从实验里可以读出两件事。第一,误差随 \(h\) 按平方缩小:\(h\) 减半,误差约变为四分之一;而方块本身只缩小一半,所以相对误差也跟着减半。这就是"一阶近似"的确切含义:剩下的误差比 \(\boldsymbol\delta\) 本身小得多。

    第二,\(J\) 在每一点都不同。在极坐标的例子里,越往外(\(r\) 越大),绿色那一列越长:同样转动角度 \(\theta\),离原点越远的点走得越远。

    4第二视角:列是速度,行列式是面积

    1.3 节说,矩阵的列是 î、ĵ 的去向。对雅可比来说,"去向"换成了"速度":让输入点沿第 1 个坐标方向以单位速度匀速前进,它的像会沿一条弯曲的路走,像在每一时刻的速度向量,正好是那一时刻所在点的雅可比的第 1 列。

    下面的动画就在做这件事。看实线箭头(当前位置的速度)经过 \(\mathbf p\) 时,与虚线箭头 \(J(\mathbf p)\) 的那一列完全重合。

    FIG 3雅可比的列 = 输出的速度
    输入:匀速直线运动
    输出:弯曲路径上的速度
    箭头都按 0.55 倍长度绘制。左边的箭头始终是单位长度的 \(\hat e_j\);右边的实线箭头是当前点处的 \(J\,\hat e_j\),即第 \(j\) 列。下方的有限差分读数用 \(\big(f(\mathbf p+\varepsilon\hat e_j)-f(\mathbf p)\big)/\varepsilon\) 估计这一列:把 \(\varepsilon\) 从 1 一路拉到 \(10^{-15}\),误差会先下降、再回升。

    再看行列式。1.5 节讲过,矩阵的行列式是面积的缩放倍数,负号表示网格翻了面。非线性映射在每一点都有自己的雅可比,也就有自己的缩放倍数 \(\det J(\mathbf p)\):那一点附近的小方块,面积被放大(或缩小)了这么多倍。

    下图把 \(\det J\) 画成输入平面上的一张热力图。把鼠标移到图上(手机上点一下),右边会显示那一点的 \(J\) 把单位正方形变成了什么。

    FIG 4\(\det J\):每一点的面积缩放
    < 00> 0
    青色表示 \(\det J > 0\)(保持朝向),紫色表示 \(\det J < 0\)(翻面),颜色越淡越接近 0。红色细线标出 \(\det J\) 变号的位置,也就是"折痕"。右上小图:浅色虚线是单位正方形,彩色平行四边形是它在 \(J\) 下的像,红、绿边分别是 \(J\) 的两列。

    几个值得留意的现象:漩涡看起来扭得很厉害,\(\det J\) 却处处等于 1,它只搬动不压缩,是一个保面积的映射。极坐标的 \(\det J = r\),越靠近 \(r=0\) 越淡。镜头畸变有一圈 \(\det J = 0\) 的折痕,折痕以外的部分被翻折回来,同一个像素对应了两个方向的光线。真实的鱼眼镜头模型只在折痕以内才可逆,标定时要特别小心。

    5再看数学

    提示:把鼠标悬停在公式中带底色的符号上,FIG 2 中对应的元素会被高亮。

    定义

    设 \(f:\R^n\to\R^m\),\(f = (f_1,\dots,f_m)\)。它在点 \(\mathbf p\) 处的雅可比矩阵是 \(m\times n\) 的偏导数表:第 \(i\) 行第 \(j\) 列是"第 \(i\) 个输出对第 \(j\) 个输入的偏导"。

    $$ J_f(\mathbf p) = \begin{bmatrix} \hl{c1}{\ci{\dfrac{\partial f}{\partial x_1}}} & \hl{c2}{\cj{\dfrac{\partial f}{\partial x_2}}} & \cdots & \dfrac{\partial f}{\partial x_n} \end{bmatrix} = \begin{bmatrix} \ci{\dfrac{\partial f_1}{\partial x_1}} & \cj{\dfrac{\partial f_1}{\partial x_2}} & \cdots & \dfrac{\partial f_1}{\partial x_n} \\ \vdots & \vdots & & \vdots \\ \ci{\dfrac{\partial f_m}{\partial x_1}} & \cj{\dfrac{\partial f_m}{\partial x_2}} & \cdots & \dfrac{\partial f_m}{\partial x_n} \end{bmatrix}, \qquad J_{ij} = \frac{\partial f_i}{\partial x_j}(\mathbf p). $$

    按列读:第 \(j\) 列是沿 \(x_j\) 轻推时输出的速度(FIG 3)。按行读:第 \(i\) 行是单个输出 \(f_i\) 的梯度 \(\nabla f_i^\top\)(3.2 节)。特别地,如果输出只有一个数(\(m = 1\)),雅可比就是一行,正好是梯度的转置:\(J = \nabla f^\top\)。

    一阶泰勒展开

    "放大后像一个矩阵"写成公式,就是:

    $$ f(\mathbf p + \hl{d}{\boldsymbol\delta}) \;=\; \hl{fp}{\cv{f(\mathbf p)}} \;+\; \hl{J}{\cw{J(\mathbf p)}}\,\hl{d}{\boldsymbol\delta} \;+\; \hl{err}{o(\|\boldsymbol\delta\|)} $$

    余项 \(o(\|\boldsymbol\delta\|)\) 的意思是:它比 \(\|\boldsymbol\delta\|\) 消失得更快,除以 \(\|\boldsymbol\delta\|\) 后趋于 0。对光滑的 \(f\),余项的大小是 \(O(\|\boldsymbol\delta\|^2)\),这正是 FIG 2 里"\(h\) 减半,误差变为四分之一"的原因。而且 \(J(\mathbf p)\) 是唯一满足这个式子的矩阵,所以叫它"最佳"线性近似。

    链式法则:局部线性映射的复合就是矩阵乘法

    先做 \(f\),再做 \(g\)。在 \(\mathbf p\) 附近,\(f\) 像矩阵 \(J_f(\mathbf p)\);在 \(f(\mathbf p)\) 附近,\(g\) 像矩阵 \(J_g(f(\mathbf p))\)。两个线性映射接连作用,就是两个矩阵相乘(1.4 节):

    $$ J_{g\circ f}(\mathbf p) \;=\; J_g\big(f(\mathbf p)\big)\; J_f(\mathbf p). $$

    注意两件事:顺序是"后做的在左边",和 1.4 节的矩阵复合一样;\(J_g\) 要在 \(f(\mathbf p)\) 处求值,而不是在 \(\mathbf p\) 处。机器人里,相机投影的雅可比就是这样拼出来的:世界点 → 相机坐标(位姿变换)→ 像素(针孔投影),各自的雅可比相乘即可。

    行列式与反函数

    由 1.5 节,小区域经过 \(f\) 后面积约放大 \(|\det J|\) 倍,这就是换元积分里那个因子的来源。在 \(\det J(\mathbf p)\ne 0\) 的地方,\(f\) 在局部可逆,反函数的雅可比就是雅可比的逆(反函数定理):

    $$ \operatorname{area}\big(f(\Omega)\big) \approx |\det J(\mathbf p)|\cdot\operatorname{area}(\Omega), \qquad J_{f^{-1}}\big(f(\mathbf p)\big) = J_f(\mathbf p)^{-1}\quad (\det J_f(\mathbf p)\neq 0). $$

    例题:极坐标

    \(f(r,\theta) = (r\cos\theta,\; r\sin\theta)\)。对 \(r\) 求偏导得第 1 列,对 \(\theta\) 求偏导得第 2 列:

    $$ J(r,\theta) = \begin{bmatrix} \ci{\cos\theta} & \cj{-r\sin\theta} \\ \ci{\sin\theta} & \cj{r\cos\theta} \end{bmatrix}, \qquad \det J = r\cos^2\theta + r\sin^2\theta = r. $$

    逐列读出几何意义:第 1 列是单位长度的径向向量,沿 \(r\) 走一步,点就朝外走一步;第 2 列垂直于径向、长度为 \(r\),转动 \(\theta\) 时,离原点越远的点走得越快。\(\det J = r\) 说明 \(dr\times d\theta\) 的小矩形变成面积约 \(r\,dr\,d\theta\) 的小扇形,这就是 \(dx\,dy = r\,dr\,d\theta\)。在 \(r=0\) 处第 2 列为零,转动 \(\theta\) 根本不动,\(J\) 退化,这正是 FIG 2 的任务 2。

    6机器人中的它:两连杆机械臂

    平面两连杆机械臂,连杆长 \(l_1, l_2\),关节角 \(\theta_1, \theta_2\)。正运动学把关节角映射到末端位置,这就是一个 \(\R^2\to\R^2\) 的非线性映射,和 FIG 2 里的那些映射没有本质区别:

    $$ \mathbf x(\boldsymbol\theta) = \begin{bmatrix} l_1\cos\theta_1 + l_2\cos(\theta_1+\theta_2) \\ l_1\sin\theta_1 + l_2\sin(\theta_1+\theta_2) \end{bmatrix}, \qquad \cv{\dot{\mathbf x}} = J(\boldsymbol\theta)\,\dot{\boldsymbol\theta}, $$ $$ J(\boldsymbol\theta) = \begin{bmatrix} \ci{-l_1 s_1 - l_2 s_{12}} & \cj{-l_2 s_{12}} \\ \ci{l_1 c_1 + l_2 c_{12}} & \cj{l_2 c_{12}} \end{bmatrix}, \qquad \det J = l_1 l_2 \sin\theta_2 $$

    (\(s_1 = \sin\theta_1\),\(c_{12} = \cos(\theta_1+\theta_2)\),以此类推。)第 1 列是只转关节 1 时末端的速度:整条手臂绕基座转,所以它垂直于"基座→末端"的连线。第 2 列是只转关节 2 时的速度:只有前臂绕肘部转,所以它垂直于前臂。当两列平行时,也就是基座、肘部、末端三点共线(手臂完全伸直或完全折回,\(\theta_2 = 0\) 或 \(\pi\)),\(\det J = 0\),末端在某个方向上无论关节怎么转都动不了。这叫奇异位形 (singular configuration)。

    左边是关节空间:拖动黄点改变 \((\theta_1, \theta_2)\),背景是 \(\det J\) 的热力图。右边是工作空间:也可以直接拖动末端,机械臂会用雅可比做逆运动学跟上来。关节空间里的黄色小圆被映射成工作空间里的黄色椭圆(速度椭圆),紫色虚线是小圆的真实像。

    FIG 5两连杆机械臂的雅可比
    关节空间 (θ₁, θ₂)
    工作空间 (x, y)
    末端的红、绿箭头是 \(J\) 的两列(按小圆半径 ρ 缩放),也就是只转关节 1 或只转关节 2 时末端的速度。红色细虚线是基座到末端的连线,红箭头总是垂直于它。左图中的红色虚线 \(\theta_2 = 0, \pm\pi\) 是奇异位形。把末端往工作空间的边缘拖,看看手臂和椭圆会怎样。
    • 让机械臂进入奇异位形:速度椭圆被压扁成一条线段,两个红绿箭头变得共线。
    真实系统里

    速度控制:给定末端期望速度 \(\dot{\mathbf x}\),求关节速度 \(\dot{\boldsymbol\theta} = J^{-1}\dot{\mathbf x}\)。靠近奇异位形时 \(J^{-1}\) 会爆炸,所以工业控制器普遍使用阻尼最小二乘 \(J^\top(JJ^\top+\lambda^2 I)^{-1}\),FIG 5 的拖动逆解用的就是它。EKF:观测模型 \(h(\mathbf x)\) 的雅可比 \(H = \partial h/\partial\mathbf x\) 决定了卡尔曼增益,每一步都要在新的估计点上重新计算。SLAM / 光束法平差:重投影误差对位姿和三维点的雅可比,按链式法则由"位姿变换"和"针孔投影"两段拼出。6 自由度机械臂的完整雅可比(包含角速度)留到 3.4 节。

    7常见误区

    误区 1:雅可比是一个固定的矩阵

    不是。它是一个矩阵场:每个点都有自己的 \(J(\mathbf p)\)。用旧点上算出的 \(J\) 去处理新点,是 EKF 和逆运动学代码里的经典 bug。状态一变,就要在新的点上重新线性化。

    误区 2:把 \(J\) 当成反方向的映射,或者随手求逆

    \(J\) 把输入的微小变化映射成输出的微小变化,方向是固定的。反方向要用 \(J^{-1}\),而它只在 \(\det J\ne 0\) 时存在。在奇异点附近,\(J^{-1}\) 里的数会变得极大:末端只想挪一毫米,关节却要飞速转动。

    误区 3:忘了近似只在局部成立

    误差按 \(\|\boldsymbol\delta\|^2\) 增长。在 FIG 2 里把 \(h\) 调大,预测很快就离谱了。Gauss-Newton 和牛顿法如果一步迈得太大,就会跳出线性近似成立的范围,所以实际实现里总有步长控制或阻尼(Levenberg-Marquardt)。

    误区 4:变量顺序和单位

    列的顺序跟着输入变量的顺序走:写成 \((r,\theta)\) 还是 \((\theta,r)\),矩阵的列就会对调,行列式也会变号。各列的单位也可能不同:极坐标的第 1 列是"米/米",第 2 列是"米/弧度"。把位置(米)和角度(弧度)放进同一个状态向量时,要想清楚尺度,否则矩阵的条件数会很差。

    误区 5:有限差分的步长随便取

    用 \(\big(f(\mathbf p+\varepsilon\hat e_j)-f(\mathbf p)\big)/\varepsilon\) 数值求雅可比时,\(\varepsilon\) 太大有截断误差,太小则两个几乎相等的浮点数相减,舍入误差会被放大。双精度下前向差分的经验值约为 \(\varepsilon\approx 10^{-8}\times\)(变量的尺度),中心差分更准。FIG 3 下方的滑块可以亲自验证这一点。

    8小练习

    1. \(f(x,y) = (x^2,\; xy)\)。它在点 \((1, 2)\) 处的雅可比是?
    第 1 行是 \(f_1 = x^2\) 的偏导 \((2x,\,0)\),第 2 行是 \(f_2 = xy\) 的偏导 \((y,\,x)\)。代入 \((1,2)\) 得 \(\begin{bmatrix}2&0\\2&1\end{bmatrix}\)。选项 A 是它的转置,正是"行列搞反"的错误。
    2. 在极坐标映射下,输入平面中 \(r = 2\) 附近一个 \(dr\times d\theta\) 的小矩形,它的像面积约为?
    面积缩放倍数是 \(|\det J| = r = 2\)。直观上:径向长度不变,角向长度被放大成 \(r\,d\theta\)。
    3. 平面两连杆机械臂(\(l_1, l_2 > 0\))在什么情况下处于奇异位形?
    \(\det J = l_1 l_2\sin\theta_2\),只和 \(\theta_2\) 有关,在 \(\theta_2 = 0, \pi\) 时为零。此时两列都垂直于同一条直线,末端沿这条直线方向动不了。\(\theta_2 = \pi/2\) 恰恰相反,\(|\det J|\) 最大,最灵活。
    4. 像素坐标 = \(g(f(\mathbf p))\),其中 \(f\) 把世界点变到相机坐标系,\(g\) 是针孔投影。像素对 \(\mathbf p\) 的雅可比是?
    链式法则:后做的 \(g\) 在左边,而且要在 \(f(\mathbf p)\) 处求值。选项 C 把求值点弄错了,选项 A 顺序反了(维度通常也对不上:\(J_g\) 是 2×3,\(J_f\) 是 3×3)。

    9延伸阅读

    • K. Lynch & F. Park, Modern Robotics, Ch. 5 — 速度运动学与静力学(机械臂雅可比、奇异性、可操作度椭球)
    • Khan Academy, Multivariable Calculus — Grant Sanderson(3Blue1Brown)讲解的"局部线性"与"雅可比矩阵"系列视频
    • G. Strang, Calculus (MIT OpenCourseWare) — 偏导数、链式法则与重积分换元
    • S. Thrun, W. Burgard & D. Fox, Probabilistic Robotics, Ch. 3.3 — 扩展卡尔曼滤波中的雅可比线性化
    • J. Nocedal & S. Wright, Numerical Optimization, Ch. 8 & 10 — 有限差分求导、Gauss-Newton 与 Levenberg-Marquardt