想象你走进一家糖果工厂,看到一条组装生产线:第一站给奶糖剥糖纸,第二站裹上巧克力脆皮,第三站压出漂亮花纹。整条线串起来,一端的原料糖块,变成了另一端的成品花糖。每站只干自己那道工序,但成品的任何变化,都会由这道工序接力放大或缩小。 现在质检员说:“成品甜度不够,请调整一下。”你会怎么做?你不会从头到尾重设每台机器,而是从最后一站开始,往回逐站查:最后一道工序每变一点,成品跟着变多少?上一道工序每变一点,最后一道工序的输入又变多少?把这一连串的“变化率”乘起来,你就知道原料端该调几下。这就是链式法则——把复合函数这条“流水线”的总变化率,拆成每个工作站局部变化率的乘积。它不仅是微积分的核心工具,更是深度学习里“反向传播”算法的数学灵魂。

岗位关联

掌握链式法则,你就拿到了理解神经网络训练机制的钥匙。面试官问“梯度怎么回传”时,你能从数学本质上讲透,而不是只会调框架。

目录
  1. 可视化演示
  2. 复合函数辨识
  3. 法则核心公式
  4. 单层嵌套求导
  5. 多层嵌套求导
  6. 计算图直观
  7. 反向传播应用
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示复合函数链式法则公式、计算图前向反向传播、多层嵌套逐层求导及反向传播梯度消失,通过多模式交互理解核心数学原理。

本节配有交互动效(进入视口后自动加载,约 3KB)。

链式法则基本公式 复合函数y=f(g(x))需逐层求导 外层对中间变量u求导f(u) 内层对x求导g(x) dy/dx = f(u) × g(x) 链式法则是复合函数求导核心工具

复合函数辨识

糖果流水线的第一步不是开动机器,而是看清这条线到底有几道工序、每道工序的输入输出是什么。剥糖纸的机器吃进去的是糖块,吐出来的是裸糖;裹巧克力的机器吃进去的是裸糖,吐出来的是脆皮糖。它们是前后串联的,后一道机器的输入,恰好是前一道机器的输出。两个机器叠在一起,就形成了“嵌套”的完整生产线。

数学里的复合函数,就是这种嵌套的流水线。设内层工序为 \(u = g(x)\),外层工序为 \(y = f(u)\),那么从原料 \(x\) 到成品 \(y\) 的直接描述是 \(y = f(g(x))\)。学习链式法则的第一课,就是学会辨认这种结构:看到一个复杂函数,先问自己——哪部分是“先发生的操作”,哪部分是“后发生的操作”?剥掉外层,剩下的就是内层;层层剥开,结构就清楚了。

y=f(g(x))=(f∘g)(x)\displaystyle y = f(g(x)) = (f \circ g)(x)

1. 内层函数:\(g(x)\) 先作用于输入 \(x\),如同流水线第一站处理原料。

u=g(x)u = g(x)

2. 外层函数:\(f\) 再作用于中间量 \(u\),如同第二站处理半成品。

y=f(u)y = f(u)

3. 嵌套表示:将两步合并,写成 \(f \circ g\),读作“\(f\) 复合 \(g\)”。

(f∘g)(x)=f(g(x))(f \circ g)(x) = f(g(x))

看清水流线的工序结构,就成功了一半。很多同学一上来就套公式求导,结果把内层当外层,求出来的导数自然是错的。先花十秒钟把“哪层在内、哪层在外”标出来,后面的计算就顺畅了。就像车间主任拿到新糖型,先是画工序图,而不是急着调机器。

法则核心公式

现在质检员要求:改变原料糖的甜度 \(x\),让成品甜度 \(y\) 变化得更多。于是你要到每一道工序去问同样一个问题:“我的输入变一点点,你的输出跟着变多少?”这个比例,数学上就叫导数。剥糖纸这一站,输出 \(u\) 对输入 \(x\) 的变化率是 \(\frac{du}{dx}\);裹巧克力这一站,输出 \(y\) 对输入 \(u\) 的变化率是 \(\frac{dy}{du}\)。

如果两站串联,原料小幅变化 \(\mathrm{d}x\),先被第一站放大成 \(\mathrm{d}u = \frac{du}{dx}\mathrm{d}x\),再被第二站放大成 \(\mathrm{d}y = \frac{dy}{du}\mathrm{d}u\)。把两个放大倍数乘起来,就是整条流水线的总放大率。这就是链式法则的核心直觉:变化率沿着流水线逐站相乘。

dydx=dydu×dudx\displaystyle \frac{dy}{dx} = \frac{dy}{du} \times \frac{du}{dx}

1. 中间变量:\(u = g(x)\) 是内外层之间的桥梁,相当于第一站的输出。

u=g(x)u = g(x)

2. 外层求导:\(y\) 对 \(u\) 求导,得到第二站的局部变化率。

dydu=f′(u)\frac{dy}{du} = f'(u)

3. 内层求导:\(u\) 对 \(x\) 求导,得到第一站的局部变化率。

dudx=g′(x)\frac{du}{dx} = g'(x)

4. 相乘合并:两个局部变化率相乘,得到总变化率。

dydx=f′(g(x))⋅g′(x)\frac{dy}{dx} = f'(g(x)) \cdot g'(x)

这个式子的莱布尼茨记号特别优雅:左边是终点 \(y\) 对起点 \(x\) 的导数,右边把中间变量 \(u\) 的微分在分子分母各出现一次,像约分一样“消掉”了。它暗示我们,无论中间有几站,都可以一层层写下去、乘起来。这套记号本身就是为流水线设计的,读它就像读一张车间布局图。

单层嵌套求导

光看公式还不够,直接上手干一道最简单的活:求 \(y = (3x+1)^5\) 的导数。这就像流水线上只有两道工序——第一站把糖块称重成 \(u = 3x+1\),第二站把糖块放入模具压成五次方。现在要问:原料 \(x\) 变化一丁点,成品 \(y\) 变化多少?

先找内外层:外层是“五次方”机器,内层是“乘三加一”机器。外层机器对输入的局部变化率是“五次方”的导数,即 \(5u^4\);内层机器对原料的局部变化率是“乘三加一”的导数,即 \(3\)。按照流水线法则,把两个放大倍数相乘,就得到总变化率。

dydx=5(3x+1)4×3=15(3x+1)4\displaystyle \frac{dy}{dx} = 5(3x+1)^4 \times 3 = 15(3x+1)^4

1. 设中间变量:令 \(u = 3x+1\),内层是线性变换,如同第一站机器。

u=3x+1u = 3x + 1

2. 外层求导:\(y = u^5\) 对 \(u\) 求导,幂函数求导规则生效。

dydu=5u4\frac{dy}{du} = 5u^4

3. 内层求导:\(u = 3x+1\) 对 \(x\) 求导,常数项消失,系数留下。

dudx=3\frac{du}{dx} = 3

4. 结果还原:把中间变量换回 \(3x+1\),两部分相乘。

dydx=5(3x+1)4×3\frac{dy}{dx} = 5(3x+1)^4 \times 3

这里最容易犯的错是只写 \(5(3x+1)^4\),把内层的系数 \(3\) 弄丢了。想象一下:如果第一站机器每转一周能处理三颗糖,而你只算了压模机的放大率,那整条线的产能就低估了三分之二。在流水线上,每一站的放大率都不能漏;在链式法则里,每一层的导数都不能缺。

多层嵌套求导

当流水线从两站变成四站、五站时,链式法则的威力才真正显现。比如求 \(y = \sin\left((x^2+1)^2\right)\) 的导数。这条流水线的工序是:第一站做 \(x^2+1\),第二站把它平方,第三站取正弦。仿佛一个多层洋葱,剥开一层还有一层。

处理这种多层嵌套的秘诀是“由外向内逐层剥”:先把最外层的“正弦”当成一个函数,把里面整块 \((x^2+1)^2\) 视为它的输入,求导得到 \(\cos\left((x^2+1)^2\right)\);接着进入下一层,对 \((x^2+1)^2\) 求导,用链式法则得 \(2(x^2+1) \cdot 2x\);最后把每一层的结果乘起来。每剥一层,就多乘一个因子。

dydx=cos⁡((x2+1)2)×2(x2+1)×2x\displaystyle \frac{dy}{dx} = \cos\left((x^2+1)^2\right) \times 2(x^2+1) \times 2x

1. 剥最外层:外层是 \(\sin(\cdot)\),求导后变 \(\cos(\cdot)\),内部保持不动。

dyd(u2)=cos⁡((x2+1)2)\frac{dy}{d(u^2)} = \cos\left((x^2+1)^2\right)

2. 剥第二层:对 \((x^2+1)^2\) 求导,幂函数规则加内层再导。

d(u2)du=2(x2+1)\frac{d(u^2)}{du} = 2(x^2+1)

3. 剥第三层:对 \(x^2+1\) 求导,只剩 \(2x\)。

dudx=2x\frac{du}{dx} = 2x

4. 累乘全部因子:三层的局部导数依次相乘,得到最终答案。

dydx=cos⁡(u2)×2u×2x\frac{dy}{dx} = \cos(u^2) \times 2u \times 2x

洋葱剥到最里层时,手上已经积了一串因子。只要每层都问一句“我的输入是什么、怎么变”,然后认真相乘,再复杂的嵌套也能拆干净。要特别提醒的是,千万别认为剥到第二层就结束了,最里面的 \(2x\) 是这条流水线的源头,漏掉它,整条线的产能就又算错了一截。

计算图直观

面对五层甚至十层的流水线,靠脑子记住每道工序的关系太累了。工程师的做法是画一张车间流程图:每个圆代表一台机器(一个数学函数),每条箭头代表半成品流向(数据传递)。这张图在深度学习里有个正式名字——计算图。

在计算图上,导数的传播变得非常直观。每个节点对它直接输入的导数,叫局部梯度;反向传播时,上游传来的梯度乘以当前节点的局部梯度,就是继续往前传的梯度。这就好比质检员在流水线末端给出一个“误差量级”,它逆着箭头流动,每经过一台机器就乘以这台机器的放大率,越往源头走,数值就越能反映“该调整哪台机器、调多少”。

∂L∂x=∂L∂y×∂y∂x\displaystyle \frac{\partial L}{\partial x} = \frac{\partial L}{\partial y} \times \frac{\partial y}{\partial x}

1. 上游梯度:\(\frac{\partial L}{\partial y}\) 是损失 \(L\) 对节点输出 \(y\) 的梯度,由下游传回。

上游梯度=∂L∂y\text{上游梯度} = \frac{\partial L}{\partial y}

2. 局部梯度:\(\frac{\partial y}{\partial x}\) 是节点输出对输入的导数,只由当前机器的表达式决定。

局部梯度=∂y∂x\text{局部梯度} = \frac{\partial y}{\partial x}

3. 梯度合成:上游梯度乘局部梯度,得到继续往上游传的梯度。

∂L∂x=∂L∂y×∂y∂x\frac{\partial L}{\partial x} = \frac{\partial L}{\partial y} \times \frac{\partial y}{\partial x}

看,这张图上的每个节点只需要关心自己“输入怎么变、输出怎么变”,不需要知道整条线的全局细节,然后靠着相邻节点之间的接力,梯度就能一路传到最前端。这种“各管一段、全局联通”的思想,正是现代深度学习框架自动求导的底层设计。可以说,链式法则给了工程师一张可以照着施工的流水线图纸。

反向传播应用

现在把流水线放大到极致——一个神经网络。输入是数据,隐藏层的每个神经元是一道工序,输出是预测值,损失函数是最终的质检报告。训练网络的基本目标就是:让质检报告的误差尽量小,于是要沿着流水线逆流而上,算每个旋钮(权重参数)该往哪个方向拧、拧多大。这个逆流而上的算法,就是反向传播,它本质上是链式法则的工程化应用。

假设某条通路是:输入 \(x\) 经过权重 \(w\) 得到 \(z = wx + b\),再经过激活函数得到 \(a\),最后参与损失 \(L\) 的计算。我们要问的是:权重 \(w\) 变一点,损失 \(L\) 变多少?答案是沿着通路把三段变化率乘起来。这跟糖果流水线里问“第一站机器调一下,成品变化多少”是同一个问题,只是工序变成了矩阵乘法和激活函数。

∂L∂w=∂L∂a×∂a∂z×∂z∂w\displaystyle \frac{\partial L}{\partial w} = \frac{\partial L}{\partial a} \times \frac{\partial a}{\partial z} \times \frac{\partial z}{\partial w}

1. 损失对激活输出求导:算出最终质检误差对激活值的敏感度。

∂L∂a\frac{\partial L}{\partial a}

2. 激活函数局部梯度:激活输出 \(a\) 对加权和 \(z\) 的导数,如 Sigmoid 或 ReLU 的导数。

∂a∂z\frac{\partial a}{\partial z}

3. 加权和对权重求导:\(z = wx + b\) 对 \(w\) 的导数正好是输入 \(x\)。

∂z∂w=x\frac{\partial z}{\partial w} = x

4. 三项相乘:三段局部变化率相乘,得到权重 \(w\) 的最终梯度。

∂L∂w=∂L∂a×f′(z)×x\frac{\partial L}{\partial w} = \frac{\partial L}{\partial a} \times f'(z) \times x

得到梯度后,优化器让权重沿着梯度的反方向迈一小步:\(w \leftarrow w - \eta \frac{\partial L}{\partial w}\),其中 \(\eta\) 是学习率。整条流水线每周转一次,就是一轮训练。所以,链式法则不仅是一道考试题,它根本就是深度学习引擎的燃油管道——每一滴梯度信号,都是沿着这条链条从最终误差倒灌回每个权重旋钮的。

AI 应用场景

深度学习框架的自动求导引擎

阶段:模型训练(反向传播)。

解决的问题:手写神经网络时,每层权重都要手动推导梯度公式,层数一多极易出错。PyTorch、TensorFlow 等框架利用计算图和链式法则,自动把损失对每个参数的梯度计算出来,让研究者只需关心前向逻辑。

具体案例:你定义了一个三层全连接网络,调用 loss.backward() 时,框架自动从损失节点沿计算图回传梯度,每一层的权重参数都拿到各自的梯度值。这个过程就是可视化演示中红色小球走过的路径,只是节点更多、维度更高。

物理仿真中的敏感性分析

阶段:物理信息神经网络(PINN)或机器人控制。

解决的问题:机器人关节角度变化时,末端执行器位置变化多少?这类复合运动链的求导,传统上靠手推雅可比矩阵,复杂且易错。用链式法则的自动微分,可以精确得到每一个关节角度对末端位置的梯度。

具体案例:机械臂由三个旋转关节串联组成,末端坐标是关节角度的复合函数。工程师用自动微分算出末端位置对每个关节角度的偏导,从而规划出平滑的轨迹。就像在糖果流水线上精确知道每个旋钮对成品形状的影响。

金融衍生品定价的希腊值计算

阶段:量化建模与风险度量。

解决的问题:期权价格是标的价格、波动率、时间等多个变量的复合函数,银行需要计算 Delta、Gamma 等敏感度指标。用链式法则从定价公式逐层求导,比数值差分更快更准。

具体案例:一个包含分红、利率调整的期权定价模型,价格是若干中间变量的嵌套组合。量化团队用自动微分计算出每个风险因子的敏感度,就像沿着定价流水线逐站测算变化率,为风控提供实时数据。

Python 演示

python41 行
def forward(x):    u = 3 * x + 1          # 内层工序    y = u ** 5             # 外层工序    return y  def chain_rule(x):    u = 3 * x + 1    dy_du = 5 * (u ** 4)   # 外层局部梯度    du_dx = 3              # 内层局部梯度    dy_dx = dy_du * du_dx  # 链式法则相乘    return dy_dx  def numerical_derivative(f, x, h=1e-6):    # 中心差分做数值验证    return (f(x + h) - f(x - h)) / (2 * h)  def backward_demo(x, target):    w = 2.0                # 初始权重    b = 1.0                # 初始偏置    pred = w * x + b       # 前向传播    loss = (pred - target) ** 2    dloss_dpred = 2 * (pred - target)  # 损失局部梯度    dpred_dw = x           # 加权和对权重的梯度    dw = dloss_dpred * dpred_dw        # 链式法则求权重梯度    return loss, dw, pred  if __name__ == "__main__":    x = 2.0    analytic = chain_rule(x)    numeric = numerical_derivative(forward, x)    print("解析链式法则:", analytic)    print("数值微分验证:", numeric)     loss, dw, pred = backward_demo(x=2.0, target=100.0)    print("预测值:", pred)    print("损失:", loss)    print("权重梯度:", dw)
目的:用解析的链式法则和数值微分对比验证复合函数的导数,并演示神经网络反向传播中权重梯度的计算过程。
  1. u = 3 * x + 1定义内层工序,等价于流水线的第一站。
  2. dy_du = 5 * (u ** 4)外层求导,得到第二站的局部放大率。
  3. dy_dx = dy_du * du_dx两个局部梯度相乘,正是链式法则的核心。
  4. (f(x + h) - f(x - h)) / (2 * h)中心差分,用数值方式近似导数,用来验证解析解。
  5. dloss_dpred = 2 * (pred - target)损失函数对预测输出的局部梯度。
  6. dw = dloss_dpred * dpred_dw把损失梯度与输入信号相乘,就是权重梯度。

常见误区

误区求 \(y=(3x+1)^5\) 的导数时,直接写下 \(5(3x+1)^4\),觉得幂函数求导完就结束了,没意识到里面还有个 \(3x+1\) 需要继续求导。

正解链式法则说得很清楚:外层导必须乘内层导。流水线上第一站的放大率漏掉了,总产能一定算错。正确结果是 \(5(3x+1)^4 \times 3\)。可以这样自我检查:对内层做个微小的数值变化,用差分估算一下,看自己的解析答案是否吻合。

为何常见:初学时习惯了“求导是对整个表达式操作”的单一视角,忽视了函数内部还有变量在变化。

误区有的同学记住了“外层导加上内层导”,把 \(dy/dx = dy/du + du/dx\) 当成链式法则,觉得变化率可以叠加。

正解复合函数是串联结构,不是并联。串联流水线的总放大率是各站放大率的乘积,而不是相加。加法对应的是“两条独立路径汇合”的场景(如多变量函数的偏导),而这在链式法则里并不适用。

为何常见:高中物理里学过的“合速度等于各速度之和”等加法直觉被错误迁移到了这个场景。

误区遇到 \(y=\sin((x^2+1)^2)\),写到 \(\cos((x^2+1)^2)\times 2(x^2+1)\) 就停了,觉得最里面只是个二次多项式,不用再导。

正解只要最里层还包含变量 \(x\),就必须继续求导,直到最内层的自变量是真正独立的输入变量为止。这道题还有第三层 \(x^2+1\) 的导数 \(2x\),所以完整答案有三个因子。可以想象剥洋葱,只要里面还有洋葱瓣,就要继续剥。

为何常见:人的注意力资源有限,套了多层括号后容易在视觉上忽略最内层的小结构。

误区在计算图里做反向传播时,只计算当前节点的局部梯度就直接回传,没有把它乘以上游传来的梯度,导致梯度值越来越小或直接错误。

正解反向传播的精髓是“梯度沿边相乘”。每个节点的回传梯度 = 上游梯度 × 局部梯度。上游梯度是下游所有通路传上来的累积贡献,丢掉它等于切断了流水线的下游反馈,机器调整必然失真。

为何常见:习惯了一次性求导的思维,忽略了反向传播是逐步接力而非独立计算。

面试题

Q1. 对复合函数 y=f(g(x)) 求导,链式法则说的是?

单选题 · easy

  • A.外层导乘以内层导← 正确答案
  • B.外层导加内层导
  • C.外层导除以内层导
  • D.外层导减以内层导

答案:A。复合函数是串联流水线,总变化率是各层局部变化率的乘积。A 选项正是“外层导乘内层导”,B、C、D 分别是加、除、减,都不符合串联系统的放大规律。

Q2. 设 y=(3x+1)^5,令 u=3x+1,则 dy/dx 等于?

单选题 · easy

  • A.15 乘以 u 的四次方← 正确答案
  • B.5 乘以 u 的四次方
  • C.3 乘以 u 的五次方
  • D.15 乘以 u 的三次方

答案:A。外层是五次幂,导数为 5u^4;内层 u=3x+1 对 x 求导为 3。两者相乘得 15u^4,选 A。B 漏了内层导数 3,C 把内层当成了外层,D 指数算错。

Q3. 链式法则的莱布尼茨记号形式是?

单选题 · easy

  • A.dy/dx = dy/du + du/dx
  • B.dy/dx = dy/du × du/dx← 正确答案
  • C.dy/dx = dy/du ÷ du/dx
  • D.dy/dx = du/dy × dx/du

答案:B。莱布尼茨记号把中间变量 u 的微分在分子分母各出现一次,相乘后“约分”得到 dy/dx,这对应 B 选项。A 是加法,C 是除法,D 把分子分母写反了。

Q4. 求 y=sin(x²) 的导数 dy/dx?

单选题 · mid

  • A.cos(x²) 乘以 2x← 正确答案
  • B.sin(x²) 乘以 2x
  • C.cos(x²) 加上 2x
  • D.cos(2x) 乘以 x²

答案:A。外层是正弦,导数为 cos(x²);内层是 x²,导数为 2x。两者相乘得 cos(x²)·2x。B 混淆了正弦与余弦,C 把乘法写成加法,D 对内层求导有误。

Q5. 多层嵌套 y=e^(x²+1) 求导时,正确的顺序是?

单选题 · mid

  • A.先求 x²+1 再求 e^u
  • B.先求 e^u 再求 x²+1← 正确答案
  • C.先求 e 的导数再求 x²
  • D.所有层同时求导

答案:B。链式法则强调由外向内逐层求导。先处理最外层指数函数,得到 e^(x²+1),再乘内层 x²+1 的导数 2x。由内向外或同时求导都会漏因子或搞乱顺序。

Q6. 关于计算图的反向传播,下列哪些说法正确?

多选题 · mid

  • A.梯度由输出流向输入← 正确答案
  • B.梯度由输入流向输出
  • C.局部梯度沿途相乘← 正确答案
  • D.局部梯度沿途相加

答案:AC。反向传播的方向与正向计算相反,从损失(输出端)逆流回输入,A 对 B 错。回传过程中每个节点的梯度等于上游梯度乘局部梯度,C 对 D 错。这就像红色小球逆着传送带走回原料端。

Q7. 计算图中“局部梯度”指的是什么?

单选题 · mid

  • A.该边的输出对输入之导数← 正确答案
  • B.该边的输入对输出之导数
  • C.整体损失对该边输出之导数
  • D.整体损失对输入之导数

答案:A。局部梯度只由当前节点函数本身决定,是输出对输入的导数,如 z=wx+b 对 w 的局部梯度是 x。C、D 描述的是“上游梯度”或“最终梯度”,不是局部量。

Q8. 已知 y=f(g(h(x))),则 dy/dx 的正确展开是?

单选题 · hard

  • A.f'(g)·g'(h)·h'(x)← 正确答案
  • B.f'(g)·g'(x)·h'(x)
  • C.f'(x)·g'(x)·h'(x)
  • D.f'(g)·g'(x)·h'(g)

答案:A。三层嵌套要写三个因子,每层的“输入”是下一层的输出。A 中 f' 以 g 为输入,g' 以 h 为输入,h' 以 x 为输入,完全对应由外向内逐层求导。B、C 搞错了各层的输入变量,D 最后一项写错。

Q9. 神经网络反向传播中,权重 w 的梯度由哪些量相乘得到?

多选题 · hard

  • A.损失对输出的梯度← 正确答案
  • B.激活函数局部梯度← 正确答案
  • C.该层的输入信号← 正确答案
  • D.训练用的学习率

答案:ABC。权重梯度的链式展开为:损失对激活输出梯度 × 激活函数对加权和的导数 × 加权和对权重的导数(即输入信号),A、B、C 都对。学习率是更新参数时的步长,不参与梯度本身的计算,D 错。

Q10. ReLU 函数 y=max(0,x),当 x>0 时其局部梯度为?

单选题 · extreme

  • A.恒等于 1← 正确答案
  • B.恒等于 0
  • C.等于输入 x
  • D.等于负一

答案:A。ReLU 在 x>0 时是恒等映射 y=x,斜率为 1,所以局部梯度恒为 1;在 x<0 时斜率为 0。C 是把函数值当成了梯度,B、D 都不符合正区间的斜率。