Part I · 第 2 章 微积分 · 2.2Part I · Ch. 2 Calculus · 2.2

链式法则The Chain Rule

机器人里的函数几乎都是一层套一层:电机角度 → 关节角 → 末端位置 → 误差 → 损失。链式法则说:每一层的"放大倍数"相乘,就是整条链的放大倍数。神经网络的反向传播、机械臂速度的逐关节传递,都只是这一句话。 Almost every function in robotics is layers inside layers: motor angle → joint angle → end-effector position → error → loss. The chain rule says the magnifications of the layers multiply. Backpropagation in neural nets and joint-by-joint velocity propagation in an arm are that single sentence.

约 20 分钟~20 min 前置:2.1 导数Prereqs: 2.1 Derivatives 4 个交互4 interactives

    1为什么机器人需要它Why robots need this

    一台机械臂的电机经过减速器带动关节,关节带动连杆,连杆末端的高度又决定任务完成得好不好。你想知道"电机多转一点点,末端高度变多少",答案不会写在任何一个零件上,而是每一级放大倍数的乘积:减速比 × 连杆几何 × 误差对高度的敏感度。

    训练一个控制策略时也一样:损失依赖于动作,动作依赖于网络输出,网络输出依赖于几百万个参数。要用梯度下降调参数,就得算出"损失对每个参数的导数",这正是链式法则,从后往前反复使用。这个过程叫反向传播,是现代机器学习和可微仿真的核心。

    A robot arm's motor drives a joint through a gearbox, the joint swings a link, and the height of the link's tip decides whether the task succeeds. "If the motor turns a bit more, how much does the tip height change?" is not written on any one part. It is the product of each stage's gain: gear ratio × link geometry × sensitivity of the error to height.

    Training a control policy is the same story: the loss depends on the action, the action on the network output, the output on millions of parameters. To tune parameters by gradient descent you need "the derivative of the loss with respect to every parameter", which is the chain rule applied from the back to the front, over and over. That procedure is backpropagation, the core of modern machine learning and differentiable simulation.

    2直觉:放大倍数相乘Intuition: magnifications multiply

    2.1 节说,导数是"输入动一点点,输出动多少倍"。现在把两个函数接起来:\(u=g(x)\),\(y=f(u)\)。\(x\) 动了 \(\Delta x\),\(u\) 先动 \(g'\,\Delta x\);\(u\) 的这一点点变化再被 \(f\) 放大 \(f'\) 倍,所以 \(y\) 动了 \(f'\cdot g'\,\Delta x\)。倍数是一级一级乘上去的。

    下面三条数轴依次是 \(x\)、\(u=g(x)\)、\(y=f(u)\)。细线表示"这个点被送到了哪里"。拖动 \(x_0\),看琥珀色小区间怎么被一级一级拉长或压扁。

    Lesson 2.1 said the derivative is "if the input moves a tiny bit, by what factor does the output move?" Now connect two functions: \(u=g(x)\), \(y=f(u)\). When \(x\) moves by \(\Delta x\), \(u\) first moves by \(g'\,\Delta x\); that small change in \(u\) is then magnified by \(f'\), so \(y\) moves by \(f'\cdot g'\,\Delta x\). The factors are stacked stage by stage.

    The three number lines below are \(x\), \(u=g(x)\) and \(y=f(u)\). Thin lines show "where each point is sent". Drag \(x_0\) and watch the small amber interval get stretched or squeezed stage by stage.

    FIG 1三条数轴Three number lines
    琥珀色是 \(x\) 附近一小段区间 \([x_0,\,x_0+\Delta x]\) 及其在两级之后的像。细线是"一格一格"的对应:线挤在一起表示被压缩(倍数小于 1),线分开表示被拉伸。 Amber marks a small interval \([x_0,\,x_0+\Delta x]\) and its images after each stage. The thin lines connect evenly spaced points: crowded lines mean squeezing (factor below 1), spread lines mean stretching.
    • 找到一个位置,使整条链的放大倍数几乎为 0(某一级把区间压成了一个点)。Find a position where the whole chain's magnification is nearly 0 (one stage squeezes the interval to a point).
    • 找到一个位置,第一级 \(g'\) 为正,但整条链的倍数为负(第二级把方向翻了过来)。Find a position where the first stage \(g'\) is positive but the whole chain is negative (the second stage flips direction).
    核心洞见Key insight

    复合函数的导数 = 各级导数的乘积,但每一级的导数要在它自己的输入点上求:\(g'\) 在 \(x_0\) 处求,\(f'\) 在 \(u_0=g(x_0)\) 处求。这一条是最常见的出错点。

    The derivative of a composition is the product of the stage derivatives, each evaluated at its own input: \(g'\) at \(x_0\), \(f'\) at \(u_0=g(x_0)\). Getting this wrong is the most common slip.

    3动手玩:前向与反向Play: forward and backward

    真实的程序没有"数轴",只有一连串小运算。把计算写成一张图,每个节点只做一件简单的事,那么每条边上的局部导数都很好写。前向从左往右算出各节点的值;反向从右往左,把 \(\partial L/\partial(\text{节点})\) 一级一级乘回来。下面的例子是 \(L=(\sin(x^2)-c)^2\),可以想成"一个非线性传感器读数与目标值 \(c\) 的平方误差"。

    Real programs have no "number lines", only a string of small operations. Write the computation as a graph in which every node does one simple thing, and each edge's local derivative is easy. The forward pass computes node values left to right; the backward pass goes right to left, multiplying \(\partial L/\partial(\text{node})\) back one stage at a time. The example is \(L=(\sin(x^2)-c)^2\): picture the squared error between a nonlinear sensor reading and a target \(c\).

    FIG 2计算图:反向传播一步一步走A computational graph, one backprop step at a time
    青色是前向的节点值,琥珀色是反向的 \(\bar v=\partial L/\partial v\)("这个节点动一下,损失动多少"),紫色是每条边上的局部导数。反向时每一步只做一次乘法:\(\bar v_{\text{前}} = \bar v_{\text{后}}\times\text{局部导数}\)。最后一行用数值差分独立检验结果。 Cyan are forward node values, amber the backward \(\bar v=\partial L/\partial v\) ("if this node moves a bit, by how much does the loss move"), purple the local derivative on each edge. Each backward step is one multiplication: \(\bar v_{\text{earlier}} = \bar v_{\text{later}}\times\text{local derivative}\). The last line checks the result independently with a numerical difference.
    • 点"下一步",一步一步走完前向和反向。Press "Next step" until both passes are complete.
    • 调 x 和 c,让 \(\partial L/\partial x\) 几乎为 0 但 \(L\) 并不为 0(哪一级的局部导数为 0?)。Tune x and c so \(\partial L/\partial x\) is nearly 0 while \(L\) is not (which stage's local derivative is 0?).

    很长的链:乘积会消失,也会爆炸Very long chains: products vanish, and explode

    链越长,乘积里的因子越多。若每一级的因子都略小于 1,乘起来就趋于 0(梯度消失);若略大于 1,就爆炸。下面把同一个小函数 \(y_i=\tanh(w\,y_{i-1})\) 连接 \(n\) 层,看输出对输入的敏感度 \(\mathrm{d}y_n/\mathrm{d}x\) 怎样随层数变化。这和深度网络难训练、长时间序列的状态对初值极其敏感,是同一个原因。

    The longer the chain, the more factors in the product. If every stage's factor is a bit below 1 the product heads to 0 (vanishing gradient); a bit above 1 and it explodes. Below, the same small function \(y_i=\tanh(w\,y_{i-1})\) is stacked \(n\) times; watch how the sensitivity \(\mathrm{d}y_n/\mathrm{d}x\) changes with depth. It is the same reason deep networks are hard to train and why a long rollout's final state can be hypersensitive to its initial state.

    FIG 3长链的敏感度Sensitivity of a long chain
    输出 yₙ 对 x(拖动 x₀)output yₙ versus x (drag x₀)
    log₁₀ |dyᵢ/dx| 随层数 ilog₁₀ |dyᵢ/dx| versus layer i
    左:第 n 层输出随输入 x 变化的曲线(淡色是第 1 层)。右:在 \(x_0\) 处,每增加一层,敏感度乘上一个因子 \(w(1-y_i^2)\);虚线是 \(\log_{10}w\cdot i\),即"不饱和时"的增长趋势。\(\tanh\) 饱和后因子骤降,敏感度就塌下去了。 Left: the n-th layer's output as a function of the input x (faint is layer 1). Right: at \(x_0\), each extra layer multiplies the sensitivity by \(w(1-y_i^2)\); the dashed line is \(\log_{10}w\cdot i\), the unsaturated trend. Once \(\tanh\) saturates, the factor collapses and so does the sensitivity.
    • 让 20 层以上的链敏感度小于 \(10^{-6}\)(梯度消失)。Make a chain of 20+ layers whose sensitivity falls below \(10^{-6}\) (vanishing gradient).
    • 找一组 w、x₀,使敏感度在前几层先增长到 10 以上,然后再塌下去。Find a w and x₀ where the sensitivity first grows above 10 in the early layers and then collapses.

    4再看数学The math

    提示:悬停在公式带底色的符号上,FIG 1 里对应的那一级会高亮。Tip: hover the highlighted symbols; the matching stage in FIG 1 lights up.

    链式法则The chain rule

    设 \(u=g(x)\),\(y=f(u)\),两者都可导,则

    If \(u=g(x)\) and \(y=f(u)\) are both differentiable, then

    $$ \frac{\mathrm{d}y}{\mathrm{d}x} \;=\; \hl{f}{f'(\,g(x)\,)}\cdot \hl{g}{g'(x)}\;=\;\frac{\mathrm{d}y}{\mathrm{d}u}\cdot\frac{\mathrm{d}u}{\mathrm{d}x}. $$

    为什么?用 2.1 节的线性近似:\(\Delta u\approx g'(x)\Delta x\),\(\Delta y\approx f'(u)\Delta u\),代入就得 \(\Delta y\approx f'(u)\,g'(x)\,\Delta x\)。右边那个"分式相消"只是记忆口诀,\(\mathrm{d}y/\mathrm{d}u\) 并不是真的分数;真正成立的是上面这条线性近似。

    Why? Use the linear approximation from Lesson 2.1: \(\Delta u\approx g'(x)\Delta x\) and \(\Delta y\approx f'(u)\Delta u\); substituting gives \(\Delta y\approx f'(u)\,g'(x)\,\Delta x\). The "fractions cancel" on the right is a mnemonic, since \(\mathrm{d}y/\mathrm{d}u\) is not literally a fraction; what actually holds is the linear approximation above.

    多层与多元Many layers, many variables

    三层就是三个因子:\(\dfrac{\mathrm{d}}{\mathrm{d}x}f(g(h(x)))=f'(g(h(x)))\cdot g'(h(x))\cdot h'(x)\)。输入输出是向量时,"倍数"变成雅可比矩阵(3.3 节),乘法变成矩阵乘法(1.4 节):

    Three layers means three factors: \(\dfrac{\mathrm{d}}{\mathrm{d}x}f(g(h(x)))=f'(g(h(x)))\cdot g'(h(x))\cdot h'(x)\). With vector inputs and outputs the "factor" becomes a Jacobian matrix (Lesson 3.3) and the product becomes matrix multiplication (Lesson 1.4):

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

    矩阵乘法不可交换,所以顺序必须与"先做哪一级"一致。

    Matrix multiplication does not commute, so the order must match which stage comes first.

    前向模式与反向模式Forward mode and reverse mode

    因子相乘满足结合律,可以从左往右乘,也可以从右往左乘,结果相同,代价却不同。设输入 \(n\) 维、输出 \(m\) 维:从输入端开始乘(前向模式)一遍只能得到对一个输入的导数,要跑 \(n\) 遍;从输出端开始乘(反向模式)一遍得到一个输出对所有输入的导数,要跑 \(m\) 遍。训练神经网络时损失是标量(\(m=1\))而参数有百万个(\(n\) 很大),所以用反向模式:一次反向传播的代价只相当于一次前向。

    Multiplication is associative, so the factors can be multiplied left to right or right to left with the same result but different cost. With \(n\) inputs and \(m\) outputs, starting from the input side (forward mode) yields the derivatives with respect to one input per sweep, so \(n\) sweeps; starting from the output side (reverse mode) yields one output's derivatives with respect to all inputs per sweep, so \(m\) sweeps. A neural network's loss is a scalar (\(m=1\)) with millions of parameters (large \(n\)), so reverse mode wins: one backward pass costs about as much as one forward pass.

    反向传播的递推式The backprop recursion

    对计算图中的节点 \(v_i\),设它的后继节点为 \(v_j\),则 \(\bar v_i=\sum_j \bar v_j\,\dfrac{\partial v_j}{\partial v_i}\),从 \(\bar L=1\) 开始,按拓扑序倒着算。若一个节点被多条路径使用,各路径的贡献要相加。

    For a node \(v_i\) with successors \(v_j\): \(\bar v_i=\sum_j \bar v_j\,\dfrac{\partial v_j}{\partial v_i}\). Start from \(\bar L=1\) and go backward in topological order. If a node is used along several paths, the contributions add.

    5机器人中的它:带减速器的机械臂In robotics: a geared robot arm

    一根长为 \(\ell\) 的连杆由电机经减速比 \(N\) 驱动:关节角 \(q=\theta_m/N\),末端高度 \(z=\ell\sin q\)。我们希望末端到达目标高度 \(z^\star\),损失 \(L=(z-z^\star)^2\)。用链式法则:

    A link of length \(\ell\) is driven by a motor through gear ratio \(N\): joint angle \(q=\theta_m/N\), tip height \(z=\ell\sin q\). We want the tip at the target height \(z^\star\), with loss \(L=(z-z^\star)^2\). By the chain rule:

    $$ \frac{\partial L}{\partial\theta_m}\;=\;\underbrace{2(z-z^\star)}_{\partial L/\partial z}\cdot\underbrace{\ell\cos q}_{\partial z/\partial q}\cdot\underbrace{\tfrac1N}_{\partial q/\partial\theta_m}. $$

    减速比越大,最后一个因子 \(1/N\) 越小,梯度整体变小,同样的学习率就走得很慢。拖动末端或目标线,调整减速比和学习率,点"梯度下降"看看。

    The larger the gear ratio, the smaller the last factor \(1/N\); the whole gradient shrinks, and the same learning rate crawls. Drag the tip or the target line, change the gear ratio and the learning rate, and press "Gradient descent".

    FIG 4用链式法则驱动一根杆Driving a link with the chain rule
    log₁₀ 损失 随步数log₁₀ loss versus step
    左:灰色是连杆,青色是末端,琥珀色线是目标高度(可拖动)。拖动末端可以手动设定关节角。右:每一步的损失(对数坐标)。学习率相对 \(N^2\) 太小会爬得很慢;太大则会来回震荡甚至不收敛。 Left: the gray bar is the link, cyan the tip, the amber line the target height (draggable). Drag the tip to set the joint angle by hand. Right: the loss at each step (log scale). A learning rate that is too small relative to \(N^2\) crawls; too large and it oscillates or fails to converge.
    • 用默认设置点"梯度下降",观察它要走很多步才靠近目标。Press "Gradient descent" with the defaults and watch it take many steps to approach the target.
    • 把减速比调到 40 以上,调大学习率,让下降在 200 步内把末端误差压到 0.01 以内。Raise the gear ratio to 40 or more, increase the learning rate, and bring the tip error under 0.01 within 200 steps.
    真实系统里In real systems

    不同量纲的参数(电机弧度、关节弧度、米)混在一起时,梯度大小可以差几个数量级,就像这里的 \(1/N\)。所以优化器要做尺度归一化(预条件、Adam、给关节加权),6.3 节和 6.6 节会回到这件事。机械臂速度运动学也是同一条链:关节速度 → 每个连杆 → 末端速度,雅可比就是这条链上各级矩阵的乘积(3.4 节)。

    When parameters with different units (motor radians, joint radians, meters) are mixed, gradient magnitudes can differ by orders of magnitude, like the \(1/N\) here. Optimizers therefore rescale (preconditioning, Adam, weighting joints); Lessons 6.3 and 6.6 return to this. Arm velocity kinematics is the same chain: joint velocities → each link → end-effector velocity, with the Jacobian as the product of per-stage matrices (Lesson 3.4).

    6常见误区Common pitfalls

    误区 1:把外层导数算在 \(x\) 上Pitfall 1: evaluating the outer derivative at \(x\)

    \((\sin x^2)'\) 是 \(\cos(x^2)\cdot 2x\),不是 \(\cos(x)\cdot 2x\)。外层的导数要在内层的输出上求。

    \((\sin x^2)'\) is \(\cos(x^2)\cdot 2x\), not \(\cos(x)\cdot 2x\). The outer derivative is evaluated at the inner function's output.

    误区 2:漏掉内层导数Pitfall 2: dropping the inner derivative

    \((\sin 3x)'=3\cos 3x\)。少乘的那个 3,在机器人里常表现为"单位忘了换":角度换成度、时间换成毫秒、经过减速比,都是内层函数,都会在导数里多出一个常数。

    \((\sin 3x)'=3\cos 3x\). The missing 3 often shows up in robotics as "forgot a unit conversion": degrees, milliseconds and gear ratios are all inner functions and each leaves a constant in the derivative.

    误区 3:矩阵链乘的顺序写反Pitfall 3: multiplying matrix factors in the wrong order

    \(J_{f\circ g}=J_f J_g\),外层在左。检查维度是最简单的自检:\(J_g\) 是 \(p\times n\),\(J_f\) 是 \(m\times p\),乘出来才是 \(m\times n\)。

    \(J_{f\circ g}=J_f J_g\), outer layer on the left. Checking dimensions is the quickest sanity test: \(J_g\) is \(p\times n\), \(J_f\) is \(m\times p\), and only then does the product come out \(m\times n\).

    误区 4:忽视长链里的梯度消失 / 爆炸Pitfall 4: ignoring vanishing / exploding gradients in long chains

    梯度是很多因子之积,只要典型因子偏离 1,乘积就是指数级的。长时程的轨迹优化和循环网络都会遇到。常见对策:缩短链(多重打靶)、归一化、残差连接、梯度裁剪。

    A gradient is a product of many factors; if the typical factor is off 1 the product is exponential. Long-horizon trajectory optimization and recurrent networks both suffer. Common remedies: shorten the chain (multiple shooting), normalization, residual connections, gradient clipping.

    7小练习Check yourself

    1. \(y=\sin(3x)\),\(\mathrm{d}y/\mathrm{d}x\) 等于?1. For \(y=\sin(3x)\), what is \(\mathrm{d}y/\mathrm{d}x\)?
    外层 \(\sin\) 的导数是 \(\cos(3x)\),内层 \(3x\) 的导数是 3,相乘得 \(3\cos 3x\)。The outer \(\sin\) gives \(\cos(3x)\); the inner \(3x\) gives 3; the product is \(3\cos 3x\).
    2. \(y=(x^2+1)^3\),\(\mathrm{d}y/\mathrm{d}x\) 等于?2. For \(y=(x^2+1)^3\), what is \(\mathrm{d}y/\mathrm{d}x\)?
    令 \(u=x^2+1\):\(\mathrm{d}y/\mathrm{d}u=3u^2\),\(\mathrm{d}u/\mathrm{d}x=2x\),乘起来是 \(6x(x^2+1)^2\)。Let \(u=x^2+1\): \(\mathrm{d}y/\mathrm{d}u=3u^2\) and \(\mathrm{d}u/\mathrm{d}x=2x\); the product is \(6x(x^2+1)^2\).
    3. 连杆长 \(\ell=0.5\) m,减速比 \(N=50\),此时 \(q=0\)。末端高度对电机角度的导数 \(\partial z/\partial\theta_m\) 是多少?3. A link of length \(\ell=0.5\) m, gear ratio \(N=50\), and \(q=0\). What is \(\partial z/\partial\theta_m\) of the tip height with respect to the motor angle?
    \(\partial z/\partial\theta_m=\ell\cos q\cdot\tfrac1N=0.5\times1\times\tfrac1{50}=0.01\)。\(\partial z/\partial\theta_m=\ell\cos q\cdot\tfrac1N=0.5\times1\times\tfrac1{50}=0.01\).
    4. 一条 20 层的链,每层的局部导数都约为 0.8。总导数大约是多少?4. A 20-layer chain whose local derivatives are all about 0.8. Roughly what is the total derivative?
    \(0.8^{20}\approx 0.0115\)。因子只比 1 小一点,乘上 20 次就几乎消失了。这就是梯度消失。\(0.8^{20}\approx 0.0115\). Factors only slightly under 1 nearly vanish after 20 multiplications: a vanishing gradient.
    5. 为什么训练神经网络用反向模式(反向传播)而不是前向模式?5. Why do we train neural networks with reverse mode (backprop) rather than forward mode?
    两种模式给出同样的导数,区别只在代价:前向模式每次只能求对一个输入的导数,要跑和参数个数一样多遍。Both modes give the same derivatives; the difference is cost: forward mode handles one input per sweep and needs as many sweeps as there are parameters.

    8延伸阅读Further reading

    • 3Blue1Brown, Essence of Calculus — 第 4 章:链式法则与乘积法则的可视化Ch. 4: visualizing the chain and product rules
    • A. Griewank & A. Walther, Evaluating Derivatives — 自动微分的前向 / 反向模式forward and reverse mode automatic differentiation
    • I. Goodfellow, Y. Bengio & A. Courville, Deep Learning, Ch. 6.5 — 反向传播与计算图backpropagation and computational graphs
    • K. Lynch & F. Park, Modern Robotics, Ch. 5 — 速度运动学与雅可比velocity kinematics and the Jacobian