面向机器学习的微积分


文档摘要

面向机器学习的微积分 本节摘要:导数告诉你「哪边是下坡」——这就是神经网络学习所需的全部。你手上有百万个权重,每个都是一个旋钮;要训练模型,就得知道每个旋钮该往哪边拧一点点,好让误差下降。微积分给出的就是这个方向。本节从「导数是切线斜率」开始,逐步走到偏导数(每次只动一个变量)、梯度(把所有偏导数装进一个向量,指向最陡上升方向)、梯度下降(沿梯度的反方向走一步)。我们会区分数值导数(用小步长近似,任何函数通用)与解析导数(套规则手算,精确快速),推导机器学习里反复出现的那些导数(x²、wx+b、eˣ、ln x、sigmoid)。接着引入链式法则——反向传播的全部本质——以及刻画曲率的海森矩阵和局部多项式近似的泰勒展开,看清梯度下降、牛顿法、Adam 各自对应泰勒展开的哪一阶。

面向机器学习的微积分

本节摘要:导数告诉你「哪边是下坡」——这就是神经网络学习所需的全部。你手上有百万个权重,每个都是一个旋钮;要训练模型,就得知道每个旋钮该往哪边拧一点点,好让误差下降。微积分给出的就是这个方向。本节从「导数是切线斜率」开始,逐步走到偏导数(每次只动一个变量)、梯度(把所有偏导数装进一个向量,指向最陡上升方向)、梯度下降(沿梯度的反方向走一步)。我们会区分数值导数(用小步长近似,任何函数通用)与解析导数(套规则手算,精确快速),推导机器学习里反复出现的那些导数(x²、wx+b、eˣ、ln x、sigmoid)。接着引入链式法则——反向传播的全部本质——以及刻画曲率的海森矩阵和局部多项式近似的泰勒展开,看清梯度下降、牛顿法、Adam 各自对应泰勒展开的哪一阶。最后从零写一个线性回归的梯度下降训练循环,用 30 行代码完成「预测—算损失—算梯度—更新权重」这套深度学习通用骨架。

对应原课程:Phase 01 · Lesson 04 · calculus-for-ml(原英文 phases/01-math-foundations/04-calculus-for-ml/docs/en.md)。前置:第 1~3 节。

学习目标

阅读完本节,你应当能够:

  1. 对常见 ML 函数(x²、sigmoid、交叉熵)计算数值导数与解析导数
  2. 从零实现梯度下降,在一维与二维中最小化一个损失函数。
  3. 手动推导线性回归模型的梯度,并通过手写权重更新训练它。
  4. 解释海森矩阵泰勒展开及其与各种优化方法(梯度下降、牛顿法、Adam)的联系。

一、问题与直觉

你有一个含百万权重的神经网络,每个权重都是旋钮。你要算出每个旋钮该往哪个方向转,才能让模型「稍微更对一点」。微积分给的就是这个方向。

没有微积分,训练神经网络只能乱试一通撞大运;有了导数,你精确知道每个权重如何影响误差——每次都把每个旋钮往正确方向拧。

1.1 什么是导数?

导数度量变化率。对 y = f(x),f'(x) 告诉你:把 x 推一点,y 变多少。几何上,导数是该点切线的斜率。

f(x) = x²:

x f(x) f'(x)(斜率)
0 0 0(平,谷底)
1 1 2
2 4 4
3 9 6

形式定义:

f'(x) = lim f(x + h) − f(x) h→0 ───────────────── h

代码里跳过极限,直接用很小的 h——这就是数值导数。

1.2 偏导数:一次只动一个变量

真实函数输入很多。神经网络损失依赖成千上万个权重。偏导数把其他变量都当常数,只对其中一个求导。

f(x, y) = x² + 3xy + y² df/dx = 2x + 3y (把 y 当常数) df/dy = 3x + 2y (把 x 当常数)

每个偏导回答:若我只拧这一个权重,损失变多少?

1.3 梯度:所有偏导组成的向量

f(x, y, z),梯度是 ∇f = [df/dx, df/dy, df/dz]。梯度指向最陡上升方向;要最小化函数,就朝相反方向走。

f(x,y) = x² + y² 的等高线是同心圆,极小在 (0,0)。

∇f −∇f(下降方向)
(1,1) 2,2 −2,−2
(0,0) 0,0 [0,0]

这就是梯度下降的图像:算梯度、取反、走一步。

1.4 与优化的连接

训练神经网络就是优化。你有损失 L(w1, w2, …, wn),想最小化它。

梯度下降更新规则: w_new = w_old − learning_rate · dL/dw 对每个权重: 1. 算损失对该权重的偏导 2. 减去它的小倍数 3. 重复

学习率控制步长:太大冲过头,太小爬不动。梯度下降沿斜率下坡,可能困在局部极小——但在高维(百万权重)空间里,这几乎不是实际问题。

1.5 数值导数 vs 解析导数

  • 解析导数:手算套规则。f(x)=x²f'(x)=2x。精确、快。
  • 数值导数(中心差分):
f'(x) ≈ f(x+h) − f(x−h) ──────────────── 2h h = 0.0001 实践中表现良好

数值法慢但对任何函数可用;解析法快但要手推。神经网络框架用第三条路:自动微分——机械地算出精确导数(见第 5 节)。

1.6 常见函数的解析导数

函数 导数 用途 ──── ──── ──── x² 2x 损失函数(MSE) wx + b 对 w 为 x 线性层(对权重的梯度) 对 b 为 1 线性层(对偏置的梯度) 对 x 为 w 线性层(对输入的梯度) eˣ eˣ softmax、注意力 ln x 1/x 交叉熵损失 1/(1+e⁻ˣ) f(x)(1−f(x)) sigmoid 激活

1.7 链式法则(Chain Rule)

函数复合时,链式法则告诉你如何求导:

若 y = f(g(x)),则 dy/dx = f'(g(x)) · g'(x) 例:y = (3x + 1)² 外层:f(u) = u², f'(u) = 2u 内层:g(x) = 3x+1, g'(x) = 3 dy/dx = 2(3x+1)·3 = 6(3x+1)

神经网络是函数链:输入 → 线性 → 激活 → 线性 → 激活 → 损失。反向传播就是链式法则从输出反复作用到输入——这就是整个算法。

1.8 海森矩阵(Hessian)

梯度告诉你斜率,海森告诉你曲率。海森是二阶偏导组成的矩阵。对 f(x, y):

H = | d²f/dx² d²f/dxdy | | d²f/dydx d²f/dy² |

在临界点(梯度为 0 处),海森告诉你它是什么:

海森性质 含义 曲面形状
正定(所有特征值 > 0) 局部极小 朝上的碗
负定(所有特征值 < 0) 局部极大 朝下的碗
不定(特征值有正有负) 鞍点 马鞍形

:f(x,y) = x² − y²(鞍面),H = diag(2, −2),特征值 2、−2 → 鞍点。

牛顿法用海森走出比梯度下降更好的步:

牛顿法:w_new = w_old − H⁻¹ · ∇f 梯度下降:w_new = w_old − lr · ∇f

牛顿法更快,因为海森「重缩放」梯度——陡的方向步小、平的方向步大。代价:N 个参数时海森是 N×N,百万参数模型要 1 万亿项矩阵,所以实际用近似(Adam、L-BFGS、自然梯度)。

方法 用什么 成本 收敛
梯度下降 仅一阶导 每步 O(N) 慢(线性)
牛顿法 完整海森 每步 O(N³) 快(二次)
L-BFGS 梯度历史近似海森 每步 O(N) 中(超线性)
Adam 每参数自适应率(对角海森近似) 每步 O(N)
自然梯度 Fisher 信息矩阵(统计海森) 每步 O(N²)

💡 Adam 是深度学习的默认优化器——它通过跟踪每参数梯度的滑动均值与方差,廉价地近似二阶信息。

1.9 泰勒展开(Taylor Series)

任何光滑函数都能在局部用多项式近似:

f(x+h) = f(x) + f'(x)·h + (1/2)·f''(x)·h² + (1/6)·f'''(x)·h³ + …

对 ML 的意义:

  • 一阶泰勒 = 梯度下降:f(x+h) ≈ f(x) + f'(x)·h,最小化得 h = −lr·f'(x)
  • 二阶泰勒 = 牛顿法:加入 (1/2)f''(x)h²,最小化得 h = −f'(x)/f''(x)
  • 损失函数设计:MSE、交叉熵都是光滑的,泰勒展开良态——这不是巧合,光滑损失让优化可预测。
近似阶 捕获什么 对应优化方法
0 阶(常数) 仅数值 随机搜索
1 阶(线性) 斜率 梯度下降
2 阶(二次) 曲率 牛顿法

核心洞见:所有基于梯度的优化,本质上都是局部近似损失、再走到该近似的极小

1.10 计算图里的多元链式法则

神经网络里变量会分叉与合并。前向传播一个简单例子:

反向传播从右到左算梯度:

每条箭头乘以局部导数。任一参数的梯度 = 从损失到该参数路径上所有局部导数之积。路径分叉合并时,把各贡献求和(多元链式法则)。反向传播的全部就是这件事:系统化地在计算图上从输出到输入应用链式法则。

1.11 雅可比矩阵(Jacobian)

当函数把向量映射成向量(如神经网络层),它的导数是矩阵。雅可比包含「每个输出对每个输入」的全部偏导。对 f: ℝⁿ → ℝᵐ,雅可比 J 是 m×n 矩阵,J[i][j] = dfᵢ/dxⱼ。你不会为神经网络手算雅可比(PyTorch 自动处理),但知道它存在,能帮你理解反向传播中的形状——若一层把 ℝⁿ 映到 ℝᵐ,其雅可比是 m×n,梯度经其转置反向流动。

二、从零实现

完整源码见 phases/01-math-foundations/04-calculus-for-ml/code/

2.1 数值导数(中心差分)

def numerical_derivative(f, x, h=1e-7): return (f(x + h) - f(x - h)) / (2 * h)

2.2 多变量数值梯度

def numerical_gradient(f, point, h=1e-7): grad = [] for i in range(len(point)): p_plus = list(point); p_plus[i] += h p_minus = list(point); p_minus[i] -= h grad.append((f(p_plus) - f(p_minus)) / (2 * h)) return grad

2.3 一维梯度下降:f(x) = x²

x = 5.0; lr = 0.1 for step in range(20): grad = 2 * x x = x - lr * grad # 每步都更靠近 x=0

2.4 二维梯度下降

def f_2d(p): x, y = p return x**2 + y**2 point = [4.0, 3.0]; lr = 0.1 for step in range(30): grad = numerical_gradient(f_2d, point) point = [p - lr * g for p, g in zip(point, grad)]

2.5 数值海森(2D)

def hessian_2d(f, x, y, h=1e-5): fxx = ( f(x+h,y) - 2*f(x,y) + f(x-h,y) ) / h**2 fyy = ( f(x,y+h) - 2*f(x,y) + f(x,y-h) ) / h**2 fxy = ( f(x+h,y+h) - f(x+h,y-h) - f(x-h,y+h) + f(x-h,y-h) ) / (4*h**2) return [[fxx, fxy], [fxy, fyy]] # 鞍面 x²−y² → H = [[2,0],[0,-2]](混合符号,鞍点) # 碗 x²+y² → H = [[2,0],[0,2]](全正,极小)

2.6 线性回归:整套训练循环

w = random.gauss(0, 1); b = random.gauss(0, 1); lr = 0.01 xs = [1.0, 2.0, 3.0, 4.0, 5.0] ys = [3.0, 5.0, 7.0, 9.0, 11.0] # 真值 y = 2x + 1 for epoch in range(200): dw = db = total_loss = 0 for x, y in zip(xs, ys): pred = w * x + b error = pred - y total_loss += error ** 2 dw += 2 * error * x # dL/dw(链式法则) db += 2 * error # dL/db dw /= len(xs); db /= len(xs); total_loss /= len(xs) w -= lr * dw; b -= lr * db

每个梯度训练循环都遵循这套模式:预测—算损失—算梯度—更新权重

设计要点:这里 dw = 2·error·x 是手推的解析梯度。第 5 节我们会用自动微分让框架替我们算,但底层就是这个链式法则。

三、框架对比

NumPy 让同样的事更快、更简洁:

import numpy as np x = np.array([1,2,3,4,5], dtype=float); y = np.array([3,5,7,9,11], dtype=float) w, b = np.random.randn(), np.random.randn(); lr = 0.01 for epoch in range(200): pred = w * x + b error = pred - y dw = np.mean(2 * error * x) db = np.mean(2 * error) w -= lr * dw; b -= lr * db print(f"y = {w:.2f}x + {b:.2f}") # ≈ y = 2x + 1

PyTorch 把梯度计算自动化,但更新循环完全一样——只是 dwdb 不再手推。

四、可复用产物

本节是整个深度学习的算法地基。产物包括:

  • 一组从零实现:numerical_derivativenumerical_gradientgradient_descenthessian_2d,可作为后续章节的梯度校验(gradient check)工具——用数值梯度对照手写/自动微分梯度,排查 bug。
  • 一个最小线性回归训练循环,后续(第 3 章机器学习基础)将被扩成完整神经网络框架。

源码见 phases/01-math-foundations/04-calculus-for-ml/code/

五、练习

  1. (Easy) 实现 numerical_second_derivative(f, x)(调用 numerical_derivative 两次),验证 在 x=2 处二阶导为 12。
  2. (Medium) 用梯度下降求 f(x,y) = (x−3)² + (y+1)² 的极小,从 (0,0) 出发,验证收敛到 (3, −1)。
  3. (Hard) 给梯度下降加动量:维护一个速度向量累积历史梯度,在 f(x) = x⁴ − 3x² 上比较有/无动量的收敛速度。

本节要点回顾

  1. 导数 = 切线斜率,告诉你输入微调时输出变多少;形式定义是极限,代码里用小 h 近似。
  2. 偏导数固定其他变量、对一个求导;梯度把所有偏导装进一个向量,指向最陡上升方向。
  3. 梯度下降:w_new = w_old − lr·∇L,沿梯度的反方向走一步,这是神经网络训练的核心。
  4. 学习率是步长,过大发散、过小爬行,选它是工程艺术。
  5. 链式法则是反向传播的数学本质——从输出到输入逐层乘局部导数。
  6. 海森矩阵描述曲率,正定/负定/不定对应极小/极大/鞍点;牛顿法用海森走更聪明的步。
  7. 泰勒展开把优化方法统一为「局部近似损失」:一阶对应梯度下降,二阶对应牛顿法。
  8. 雅可比是向量到向量函数的导数矩阵,反向传播中梯度经其转置回流。
  9. Adam 是默认优化器,廉价近似对角海森,兼顾速度与成本。

下一节,我们把链式法则机械化——自动微分让框架精确、自动地算出任意复杂函数的梯度,这是 PyTorch/JAX 的核心引擎。


发布者: 作者: Rohit Gupta 转发
评论区 (0)
U