矩阵微积分与优化 -- 从梯度到反向传播
调淋浴水温就是一个最小号的神经网络训练:根据误差去调一个参数。矩阵微积分把这件事推广到上亿个参数,优化算法则是把它做下去的引擎。本章从标量梯度讲到 Jacobian、Hessian、反向传播、凸优化与 Adam。
从淋浴龙头讲起
每天早上你都在训练一个微型神经网络。水太凉,于是你拧一下旋钮——一个参数;过一秒钟你感受到新的水温——误差信号;再拧一下。三四次之后你就收敛了。
现代深度学习是同一件事,规模放大七个数量级。“旋钮"变成了一个动辄几千万到上亿条目的矩阵$W$;“误差"变成了一个标量损失$L$。但提的问题完全一样:对每一个参数,应该往哪个方向、用多大幅度去推? 答案藏在一个对象里:梯度$\partial L / \partial W$。
本章从零搭起这个对象,再把它真正用起来。
你将学到什么
- 梯度——标量对向量的导数,以及它为什么"指向上坡”
- 方向导数——任意方向上的坡度,以及"最速下降"的几何意义
- Jacobian 矩阵——向量函数的导数,链式法则的基本拼块
- Hessian 矩阵——二阶导数矩阵,用来判别临界点类型
- 矩阵导数——你真正会用到的迹和行列式公式
- 链式法则与反向传播——同一个法则,递归地走遍计算图
- 凸优化——把"搜索"变成"顺坡而下"的关键性质
- 优化器全家桶——梯度下降、牛顿法、SGD、动量、Adam
前置知识
- 一元微积分(导数与链式法则)
- 向量与点积(第 1 章)
- 矩阵乘法(第 3 章)
- 对称矩阵与正定性(第 8 章)
梯度:多维世界里的"坡度”
从一维到多维
你在开一家奶茶店。利润$f$取决于价格$x_1$和广告投入$x_2$。你想知道:稍微改一下价格、或稍微加点广告预算,利润会怎么变?
两个偏导数各回答了半个问题:
-$\partial f/\partial x_1$——固定广告,价格每涨 1 元利润变多少; -$\partial f/\partial x_2$——固定价格,广告每加 1 元利润变多少。
把它们打包成一个向量,就得到梯度:
$$ \nabla f = \begin{pmatrix} \partial f/\partial x_1 \\ \partial f/\partial x_2 \end{pmatrix} $$对一般的$f: \mathbb{R}^n \to \mathbb{R}$:
$$ \nabla f(\vec{x}) = \begin{pmatrix} \partial f/\partial x_1 \\ \vdots \\ \partial f/\partial x_n \end{pmatrix} \in \mathbb{R}^n $$为什么必须打包成这样:三条几何含义
梯度不只是"偏导数的堆叠",它的"打包方式"正是被三条几何含义所决定的。
1. 方向。 梯度指向函数增长最快的方向。在所有可能的单位方向里,沿$\nabla f$方向走带来最大的增量;反方向走则带来最大的减量——这一句话就是梯度下降算法的全部理论依据。
2. 大小。$\|\nabla f\|$是这个最快方向上的增长率。梯度大,说明此处地势陡,挪一小步函数值就会有大变化;梯度近零,说明你站在了平地或者临界点附近。
3. 正交性。 梯度垂直于等值集$\{\vec{y}: f(\vec{y}) = f(\vec{x})\}$。地形图上的等高线连成一条条"高度不变的线",而梯度永远垂直于这些等高线,正对着上坡方向。

三个值得背下来的例子
下面三个公式后续到处都会用到,建议直接背下来。
线性函数$f(\vec{x}) = \vec{a}^T\vec{x}$,则$\nabla f = \vec{a}$。
图像是一个超平面,$\vec{a}$是它的法向量,也就是函数增长最快的方向。
平方范数$f(\vec{x}) = \|\vec{x}\|^2 = \vec{x}^T\vec{x}$,则$\nabla f = 2\vec{x}$。
一个以原点为底的"碗",梯度从原点辐射向外,正好和"远离最小值的方向"一致。
一般二次型$f(\vec{x}) = \vec{x}^TA\vec{x}$,$A$对称,则$\nabla f = 2A\vec{x}$。
本书后面碰到的所有二次损失,归根到底都是这个公式。如果$A$不对称,把它替换成$\tfrac{1}{2}(A+A^T)$即可——梯度本来也只看到对称部分。
方向导数:不一定要走最陡的路
你不一定非得正对着山顶往上爬。方向导数告诉你在任意单位方向$\vec{d}$上的坡度:
$$ D_{\vec{d}}f = \nabla f \cdot \vec{d} = \|\nabla f\| \cos\theta $$其中$\theta$是$\nabla f$与$\vec{d}$的夹角。三个角度值最关键:
-$\theta = 0°$(沿梯度方向):增量最大,等于$\|\nabla f\|$; -$\theta = 90°$(沿等高线):函数值不变; -$\theta = 180°$(逆梯度方向):减量最大,等于$-\|\nabla f\|$。
最后一行就是梯度下降的理论根据:要让$f$下降得最快,就沿$-\nabla f$方向走。
Jacobian:向量进,向量出
当输出也是向量时,单个梯度就不够用了——你需要一整张矩阵,每一项对应一对(输入,输出)。
一个做菜的类比
三种调料用量$(x_1, x_2, x_3)$同时影响三个口味指标$(f_1, f_2, f_3)$:咸度、甜度、辣度。一共有$3 \times 3 = 9$个"输入$j$对输出$i$影响多大"的关系。把它们排进一张$3 \times 3$矩阵,就是 Jacobian。
定义
对$\vec{f}: \mathbb{R}^n \to \mathbb{R}^m$,Jacobian 矩阵是一张$m \times n$的矩阵:
$$ J = \frac{\partial \vec{f}}{\partial \vec{x}} = \begin{pmatrix} \partial f_1/\partial x_1 & \cdots & \partial f_1/\partial x_n \\ \vdots & \ddots & \vdots \\ \partial f_m/\partial x_1 & \cdots & \partial f_m/\partial x_n \end{pmatrix} $$第$i$行就是$f_i$的梯度;$(i,j)$位置回答的是"输入$j$动一下,输出$i$跟着动多少"。
几何含义:最佳线性近似
在$\vec{x}_0$附近,Jacobian 就是$\vec{f}$的最佳线性近似:
$$ \vec{f}(\vec{x}_0 + \Delta\vec{x}) \approx \vec{f}(\vec{x}_0) + J\,\Delta\vec{x} $$形象一点:Jacobian 描述了函数如何"局部地拉伸/扭曲空间"。输入空间里一个小方块,经过函数后变成一个小平行四边形,而$J$正是那次形变的矩阵。
经典例子:极坐标
变换$(r, \theta) \to (x, y) = (r\cos\theta, r\sin\theta)$的 Jacobian 是
$$ J = \begin{pmatrix} \cos\theta & -r\sin\theta \\ \sin\theta & r\cos\theta \end{pmatrix} $$它的行列式$\det(J) = r$——这正是把$dx\,dy$换成$r\,dr\,d\theta$时多出来的那个$r$。微积分课上这个$r$像是凭空冒出来的,这里它被你亲手算出来了。
Hessian:曲率,与临界点分类
梯度告诉你坡度,Hessian 告诉你坡度本身怎么变——也就是曲率。
定义
对$f: \mathbb{R}^n \to \mathbb{R}$,Hessian 是一张$n \times n$的二阶偏导矩阵:
$$ H = \begin{pmatrix} \partial^2 f/\partial x_1^2 & \cdots & \partial^2 f/\partial x_1 \partial x_n \\ \vdots & \ddots & \vdots \\ \partial^2 f/\partial x_n \partial x_1 & \cdots & \partial^2 f/\partial x_n^2 \end{pmatrix} $$只要二阶偏导连续,Hessian 就是对称矩阵(Schwarz/Clairaut 定理)。这个对称性是后面一切讨论得以成立的基础——它让我们可以放心地谈$H$的特征值。
二阶 Taylor 展开
Hessian 出现在二阶 Taylor 展开里:
$$ f(\vec{x}_0 + \Delta\vec{x}) \approx f(\vec{x}_0) + \nabla f^T \Delta\vec{x} + \frac{1}{2}\Delta\vec{x}^T H \Delta\vec{x} $$三项分别是:当前值、线性修正(梯度)、二次修正(曲率)。
临界点分类
在临界点($\nabla f = \vec{0}$)处,线性项消失,函数的局部行为完全由 Hessian 决定:
| Hessian 性质 | 临界点类型 | 几何画面 |
|---|---|---|
| 正定($\lambda_i > 0$) | 局部极小 | 碗底 |
| 负定($\lambda_i < 0$) | 局部极大 | 山顶 |
| 不定(特征值正负都有) | 鞍点 | 马鞍面 |
| 半定(有$\lambda_i = 0$) | 不能确定 | 某些方向是"平的" |
两个例子。$f(x,y) = x^2 + y^2$的 Hessian 是$\mathrm{diag}(2,2)$,正定,所以$(0,0)$是极小值点;$f(x,y) = x^2 - y^2$的 Hessian 是$\mathrm{diag}(2,-2)$,不定,所以$(0,0)$是鞍点。

为什么深度学习里要单独关心鞍点? 在高维非凸损失里,你随机碰到的"梯度为零"几乎一定是鞍点,而不是真正的极小值。现代优化器必须能穿过它们——这正是动量类方法盛行、而朴素牛顿法在深度网络里几乎没人用的原因。
矩阵导数:当参数本身是矩阵
神经网络里参数大多是矩阵(权重矩阵)。我们需要的是"标量损失对权重矩阵的导数"。
定义
对$f: \mathbb{R}^{m \times n} \to \mathbb{R}$:
$$ \frac{\partial f}{\partial X} = \begin{pmatrix} \partial f/\partial x_{11} & \cdots & \partial f/\partial x_{1n}\\ \vdots & \ddots & \vdots\\ \partial f/\partial x_{m1} & \cdots & \partial f/\partial x_{mn} \end{pmatrix} $$结果与$X$同形。这个形状规则是本章最实用的"对错检查"——只要推导出来的答案形状不对,那一定是哪一步代数错了。
你真正会用到的几条恒等式
| 函数 | 关于$X$的导数 | 备注 |
|---|---|---|
| $\text{tr}(AX)$ | $A^T$ | $X$的线性项 |
| $\text{tr}(X^TAX)$ | $(A + A^T)X$ | $A$对称时退化为$2AX$ |
| $\text{tr}(AXB)$ | $A^TB^T$ | 三明治形式 |
| $\det(X)$ | $\det(X)\, X^{-T}$ | 行列式 |
| $\ln\det(X)$ | $X^{-T}$ | 极大似然估计里到处都是 |
| $X^{-1}$(微分) | $\partial(X^{-1}) = -X^{-1}(\partial X)X^{-1}$ | 逆矩阵 |
迹之所以高频出现,是因为任何关于矩阵的标量函数都能写成迹的形式,而迹又满足循环不变性$\text{tr}(ABC) = \text{tr}(BCA) = \text{tr}(CAB)$,特别好用。完整公式表请参见 Petersen & Pedersen 的 Matrix Cookbook。

链式法则与反向传播
矩阵形式的链式法则
设$\vec{u} = \vec{h}(\vec{x})$,$y = g(\vec{u})$且$g$为标量,则
$$ \frac{\partial (g \circ \vec{h})}{\partial \vec{x}} = J_h^T \nabla g $$如果两段都是向量值函数,那么各阶段的 Jacobian 直接相乘:
$$ J_{\text{total}} = J_k\,J_{k-1}\,\cdots\,J_1 $$河流污染类比。 上游工厂排放变化$\delta_1$,中游浓度跟着变$\delta_2 = J_1 \delta_1$,下游生态指数再变$\delta_3 = J_2 \delta_2$。最终$\delta_3 = J_2 J_1 \delta_1$——一段一个矩阵,依次相乘。
反向传播:链式法则的高效实现
任何复合表达式——包括上千层的神经网络——都能拆成基本运算的有向无环图,称为计算图。反向传播就是在这张图上反向应用链式法则。
为什么要反向? 设有$n$个输入、$1$个输出(典型场景:百万参数、单标量损失)。
- 前向模式(dual numbers)算的是 Jacobian-向量乘积$J\vec{v}$;要拿到所有梯度,得做$n$次。
- 反向模式(反向传播)算的是向量-Jacobian 乘积$\vec{v}^TJ$;一次遍历就能拿到所有$n$个输入的梯度。
深度学习里"$n$“是"模型里所有参数”——反向模式比前向模式大约便宜上百万倍。这一比值,是深度学习在算力上能跑得动的唯一原因。

全连接层的反向传播
这是最常见也最值得吃透的一段推导;如果本章只让你内化一个计算,就让它是这个。
前向:
$$ \vec{z} = W\vec{x} + \vec{b}, \qquad \vec{a} = \sigma(\vec{z})\quad(\text{逐元素}) $$反向: 假设后续层已经把$\delta_a := \partial L / \partial \vec{a}$算好传过来。
- 穿过激活:$\delta_z = \delta_a \odot \sigma'(\vec{z})$($\odot$是逐元素乘)。
- 权重梯度:$\dfrac{\partial L}{\partial W} = \delta_z \vec{x}^T$。注意形状:上游信号与输入的外积,正好和$W$同形。
- 偏置梯度:$\dfrac{\partial L}{\partial \vec{b}} = \delta_z$。
- 回传给上一层:$\dfrac{\partial L}{\partial \vec{x}} = W^T\delta_z$。
PyTorch、JAX、TensorFlow 等所有现代框架,背后干的就是这一套,逐层执行。
常见激活函数及其导数
ReLU:$\sigma(z) = \max(0, z)$,$\sigma'(z) = 1$($z>0$)或 0。计算便宜、正区间不饱和。代价是负区间梯度恒为零,可能导致"死亡 ReLU"。
Sigmoid:$\sigma(z) = 1/(1+e^{-z})$,有一个优美的恒等式$\sigma'(z) = \sigma(z)(1 - \sigma(z))$。输出在$(0,1)$,可解释为概率。代价是两端饱和,导致深网中梯度消失。
Softmax + 交叉熵。 分类器输出端的标准搭配。这两者组合后的梯度极其干净:
$$ \frac{\partial L}{\partial \vec{z}} = \hat{\vec{y}} - \vec{y} $$“预测概率减真实标签”——梯度局部、便宜、量级合适,这正是这种组合成为分类问题事实标准的原因。
凸优化:让一切变简单的那条性质
什么叫"凸"
函数$f$是凸的,当图像上任意两点的弦都在图像上方:
$$ f(\alpha\vec{x} + (1-\alpha)\vec{y}) \leq \alpha f(\vec{x}) + (1-\alpha)f(\vec{y}), \quad \alpha \in [0,1] $$凸性之所以宝贵,靠的就是一句话:
定理: 凸函数的任何局部最小值都是全局最小值。
对凸问题来说,“优化器收敛到了一个局部极小值"就已经是全部故事——你完全不必担心被困在某个糟糕的低洼里。
三种等价刻画(针对$C^2$函数)
1.$f$是凸函数。 2. 图像在切平面上方:$f(\vec{y}) \geq f(\vec{x}) + \nabla f(\vec{x})^T(\vec{y} - \vec{x})$。 3. Hessian 处处半正定:$H(\vec{x}) \succeq 0$。
如果是严格凸,把$\succeq$换成$\succ$。
常见凸函数
| 函数 | 凸性来源 |
|---|---|
| $\vec{a}^T\vec{x} + b$ | 仿射,既凸又凹 |
| $\|\vec{x}\|_p$($p \geq 1$) | 三角不等式 |
| $\vec{x}^TA\vec{x}$,$A \succeq 0$ | Hessian 是$2A \succeq 0$ |
| $e^x$,$x \log x$ | 二阶导数$> 0$ |
| $-\log x$($x > 0$) | 对数似然损失的基础 |

KKT 条件
对带约束问题$\min f(\vec{x})$,s.t.$g_i(\vec{x}) \leq 0$与$h_j(\vec{x}) = 0$,KKT 条件是任何最优点必须满足的,当问题凸时也是充分条件:
- 原问题可行:$g_i(\vec{x}^*) \leq 0$,$h_j(\vec{x}^*) = 0$。
- 对偶可行:$\mu_i \geq 0$。
- 互补松弛:$\mu_i\, g_i(\vec{x}^*) = 0$(不等式约束要么紧、要么对应乘子为零)。
- 驻点条件:$\nabla f + \sum_i \mu_i \nabla g_i + \sum_j \nu_j \nabla h_j = \vec{0}$。
KKT 是带约束优化的主力工具——而它背后的拉格朗日框架,也是 SVM、最大熵模型乃至 PCA 推导的统一出发点。
优化算法
梯度下降
$$ \vec{x}_{k+1} = \vec{x}_k - \alpha \nabla f(\vec{x}_k) $$顺坡而下。步长$\alpha$是学习率:太小爬得慢,太大会发散。
对一个条件数为$\kappa$的凸二次函数,收敛率约为$\bigl(\tfrac{\kappa - 1}{\kappa + 1}\bigr)^k$——也就是说一个病态问题($\kappa \gg 1$)会慢得让人崩溃,且轨迹会沿着碗的长轴方向反复横跳。

牛顿法
$$ \vec{x}_{k+1} = \vec{x}_k - H^{-1}\nabla f(\vec{x}_k) $$用二阶 Taylor 展开把$f$近似成二次函数,直接一步跳到那个二次函数的极值点。带来的是二次收敛:每次迭代正确数字位数大致翻倍。
代价是组装并求逆 Hessian 要$O(n^3)$,参数上百万时根本跑不起;而且对非凸损失,牛顿法可能会径直冲向鞍点甚至极大值——它只看"梯度为零”,并不挑类型。

随机梯度下降(SGD)
当损失是$N$个样本损失的均值$L = \tfrac{1}{N}\sum_i \ell_i$时,精确梯度要$O(N)$。改用单个样本(或小批量)的梯度:
$$ \vec{x}_{k+1} = \vec{x}_k - \alpha \nabla \ell_{i_k} $$每步极便宜。注入的噪声还能帮你穿过窄鞍点和浅盆地——对非凸的深度学习来说,这是一种正面特性。
动量法(Momentum)
朴素 SGD 抖得厉害。动量法用过去梯度的指数滑动平均来"抚平"轨迹:
$$ \vec{v}_{k+1} = \beta\vec{v}_k + \nabla f(\vec{x}_k), \qquad \vec{x}_{k+1} = \vec{x}_k - \alpha\vec{v}_{k+1} $$经典心象:一颗有质量的球沿坡滚下。惯性把路径磨圆,还能"冲过"小坑。
Adam
把动量(一阶矩)和自适应步长(二阶矩)合二为一:
$$ m_t = \beta_1 m_{t-1} + (1-\beta_1)\nabla f \qquad v_t = \beta_2 v_{t-1} + (1-\beta_2)(\nabla f)^2 $$$$ \vec{x}_{t+1} = \vec{x}_t - \frac{\alpha}{\sqrt{\hat{v}_t} + \epsilon}\hat{m}_t $$梯度持续较大的参数会被自动调小步长;梯度小、不太动的参数则被调大。默认配置$\beta_1 = 0.9$、$\beta_2 = 0.999$、$\alpha = 10^{-3}$已经是当今大部分深度学习训练的"开箱即用"选择。
三个值得手算的应用
线性回归(闭式解)
目标:$L(\vec{w}) = \|X\vec{w} - \vec{y}\|^2$。
梯度:$\nabla L = 2X^T(X\vec{w} - \vec{y})$。
令其为零,就得到著名的正规方程:
$$ \vec{w}^* = (X^TX)^{-1}X^T\vec{y} $$之所以存在闭式解,正是因为损失是关于$\vec{w}$的凸二次函数。
岭回归
加上一个$\ell_2$正则项:$L(\vec{w}) = \|X\vec{w} - \vec{y}\|^2 + \lambda\|\vec{w}\|^2$,
$$ \vec{w}^* = (X^TX + \lambda I)^{-1}X^T\vec{y} $$$\lambda I$把$X^TX$的每个特征值整体抬高$\lambda$,从而保证可逆,并把条件数压下来——这是上一章关于条件数那一套直觉的直接应用。
把 PCA 写成优化问题
PCA 可以表述为带约束的最大化问题:
$$ \max_{\|\vec{w}\|=1} \vec{w}^T\Sigma\vec{w} $$构造拉格朗日$\vec{w}^T\Sigma\vec{w} - \lambda(\vec{w}^T\vec{w} - 1)$,对$\vec{w}$求导并令为零,得$\Sigma\vec{w} = \lambda\vec{w}$。正是因为 KKT 的驻点条件,PCA 才是一个特征值问题;其最优解就是$\Sigma$的最大特征值对应的特征向量。
公式速查表
向量导数
| 函数 | 导数 |
|---|---|
| $\vec{a}^T\vec{x}$ | $\vec{a}$ |
| $\vec{x}^T\vec{x}$ | $2\vec{x}$ |
| $\vec{x}^TA\vec{x}$($A$对称) | $2A\vec{x}$ |
| $\|\vec{x}\|_2$ | $\vec{x}/\|\vec{x}\|_2$ |
矩阵导数
| 函数 | 导数 |
|---|---|
| $\text{tr}(AX)$ | $A^T$ |
| $\text{tr}(X^TAX)$ | $(A+A^T)X$ |
| $\det(X)$ | $\det(X)\cdot X^{-T}$ |
| $\ln\det(X)$ | $X^{-T}$ |
Python 实战
梯度检验
任何手推梯度的最佳调试工具:用中心差分对照一下。
| |
相对误差小于$10^{-7}$算合格,小于$10^{-9}$算优秀。
比较 GD、Momentum、Adam
| |
练习题
热身
- 计算$f(\vec{x}) = 3x_1^2 + 2x_1x_2 + x_2^2$的梯度。
- 找出$f(x,y) = x^3 - 3xy + y^3$的所有临界点,并用 Hessian 逐个分类。
- 从偏导定义出发,证明$\nabla(\vec{x}^TA\vec{x}) = (A + A^T)\vec{x}$。
进阶
- 推导两层神经网络$f = \sigma_2(W_2\sigma_1(W_1\vec{x} + \vec{b}_1) + \vec{b}_2)$的完整反向传播公式,每一步都标清楚形状。
- 证明牛顿法在任意二次函数上一步收敛到最优解。
- 用"弦在图像上方"的定义证明:凸函数的任何局部极小值都是全局极小值。
编程
- 实现上面的梯度检验函数,并在三个不同函数(其中至少一个含矩阵参数)上验证。
- 从零实现 SGD、Momentum、Adam,在 Rosenbrock 函数上比较收敛轨迹并画出来。
- 用纯 numpy 实现一个两层神经网络,在二维玩具分类数据集上手写反向传播(不许用任何自动微分框架)。
本章小结
| 概念 | 关键事实 | 在 ML 中的角色 |
|---|---|---|
| 梯度 | 最速上升方向 | 驱动梯度下降 |
| Jacobian | 最佳线性近似 | 链式法则的基本拼块 |
| Hessian | 曲率矩阵 | 判别临界点类型 |
| 链式法则 | Jacobian 相乘 | 反向传播的内核 |
| 凸性 | 局部极小 = 全局极小 | 大量损失函数的保证 |
| Adam | 自适应学习率 | 深度学习默认优化器 |
最重要的一句话:对一个有上百万参数、单个标量损失的模型,一次反向传播能同时算出所有参数的梯度。 本章其它一切内容,都是为了让这一句话变得精确、可信。
系列导航
- 上一篇: 第十章 矩阵范数与条件数
- 下一篇: 第十二章 稀疏矩阵与压缩感知
- 完整系列: 线性代数的本质(1–18)
参考资料
- Petersen, K. B. & Pedersen, M. S. The Matrix Cookbook. 矩阵导数恒等式的标准参考。
- Goodfellow, I., Bengio, Y. & Courville, A. (2016). Deep Learning, 第 6 章——反向传播详解。
- Boyd, S. & Vandenberghe, L. (2004). Convex Optimization——凸性、拉格朗日、KKT 的标准教材。
- Nocedal, J. & Wright, S. (2006). Numerical Optimization——牛顿、拟牛顿、信赖域的经典参考。
- Kingma, D. P. & Ba, J. (2015). “Adam: A Method for Stochastic Optimization.” ICLR.