技术博客

行列式与逆矩阵的导数:Jacobi 公式,以及它在归一化流里的角色

第 11 / 147 篇 · 2026-10-06 · ai · 矩阵求导Jacobi公式归一化流

第一章数学基础的最后一块拼图是两个标量-矩阵函数的求导:$\det X$ 与 $X^{-1}$(后者是矩阵值函数的微分)。它们单独看是教科书内容,放在一起就解释了生成模型一整条产品线——归一化流(normalizing flow)——的架构为什么长那样:训练目标里有一项 $\log|\det J|$,而这项的计算成本直接决定了哪些变换结构可用。这篇先推公式,再看应用。

逆矩阵的微分:从 XX⁻¹=I 两边微分

设 $X$ 可逆,$XX^{-1}=I$ 恒成立,两边取微分:

$$ dX\cdot X^{-1}+X\cdot dX^{-1}=0\quad\Longrightarrow\quad \boxed{\;dX^{-1}=-X^{-1}\,dX\,X^{-1}\;} $$

形式上与标量法则 $d(1/x)=-dx/x^2$ 完全平行,只是$"x^2"$换成了两侧各夹一个 $X^{-1}$——矩阵不可交换,逆的微分只能这样"三明治"。这条公式是速查表里 $\mathrm{tr}(X^{-1}A)$ 梯度($-X^{-\top}A^\top X^{-\top}$)的来源:$df=\mathrm{tr}(-X^{-1}dX\,X^{-1}A)=-\mathrm{tr}(X^{-1}AX^{-1}dX)$,循环轮换后直接读出。

逆函数定理给了它几何身份:$X^{-1}$ 作为 $X$ 的函数,其在 $X$ 处的微分算子就是"左右夹 $-X^{-1}$"这个线性映射。矩阵求逆是个光滑但强非线性的操作,局部线性化的形态却异常简单。

Jacobi 公式:det 的微分

行列式是矩阵元素的多项式($n$ 次齐次、$n!$ 项),直接微分没有希望。正确路径是先处理单位阵附近的情形。对 $X=I+tM$ 展开到一阶:$\det(I+tM)$ 里只有对角项的乘积 $\prod_i(1+tm_{ii})$ 含一阶项,其余每项至少含两个非对角元素($t^2$ 以上),所以

$$ \det(I+tM)=1+t\,\mathrm{tr}(M)+O(t^2). $$

即 $d(\det)_I(M)=\mathrm{tr}(M)$:单位阵处行列式的微分就是 trace。这个结果有漂亮的几何读法——$\det$ 测体积变化率,单位阵处的无穷小变形 $I+tM$ 把单位立方体变成平行多面体,体积的一阶增量恰是各方向伸缩率之和 $\sum m_{ii}$,二阶以上的"剪切×剪切"相互作用被丢弃。

一般可逆阵处用链式法则把 $X$ 平移到单位阵:$\det(X+tH)=\det X\cdot\det(I+tX^{-1}H)$,于是

$$ d(\det)_X(H)=\det X\cdot\mathrm{tr}(X^{-1}H), $$

即 Jacobi 公式:

$$ \boxed{\;d\det X=\det(X)\,\mathrm{tr}(X^{-1}dX)\;} $$

工程上更常用它的对数形式($X$ 正定时无条件成立,一般可逆时取 $\log|\det|$):

$$ d\log\det X=\mathrm{tr}(X^{-1}dX)\quad\Longrightarrow\quad \frac{\partial\log\det X}{\partial X}=X^{-\top}. $$

"log det 的梯度是逆的转置"——速查表里那一行的出处。注意 $\det X$ 本身不是凸函数,但 $\log\det X$ 在正定锥上是凹函数,$-\log\det X$ 是凸的,这是它能做优化目标(高斯 MLE、内点法障碍函数)的分析学基础。

det 的微分:先在单位阵处得到 trace,再用 det(X+tH)=detX·det(I+tX⁻¹H) 平移到一般点 单位阵处 det(I+tM)=1+t·tr(M) 左乘 X 一般可逆阵 d detX = detX·tr(X⁻¹dX) 取对数 ∇ log det X = X⁻ᵀ 正定锥上凹函数 应用一:归一化流的 log |det J| 项 log p_X(x) = log p_Z(z) − log|det ∂f/∂z| 应用二:高斯 MLE 的精度矩阵 ℓ(Λ) = log det Λ − tr(SΛ) + const

应用一:归一化流的变量替换公式

归一化流用可逆变换 $x=f(z)$ 把简单分布 $p_Z$(标准高斯)变换成复杂分布 $p_X$。变量替换公式:

$$ \log p_X(x)=\log p_Z(z)-\log\Big|\det\frac{\partial f}{\partial z}\Big|. $$

训练是最大似然:对数据 $x$ 反解 $z=f^{-1}(x)$,最大化上式。第二项就是 Jacobi 行列式的对数——它惩罚变换的"体积膨胀":$f$ 把单位体积放大 $|\det J|$ 倍,密度就被摊薄同样的倍数。要让模型可训练,两件事必须同时便宜:求逆 $f^{-1}$ 和算 $\log|\det J|$。

Jacobi 公式解释了后者的成本结构:一般 $n\times n$ 矩阵的行列式是 $O(n^3)$(LU 分解),每步流变换都要付一次,几十层流的训练就不可行。出路是让雅可比结构化,使行列式近乎免费:

  • 耦合层(RealNVP, Dinh et al. 2017):把维度切成两半,$x_{1:d}$ 不变、$x_{d+1:n}$ 做以前半为参数的仿射变换。雅可比是分块下三角,行列式=对角块之积,只有仿射缩放因子贡献 $\log|\det|$,$O(n)$ 到手。求逆也便宜:逐维反解仿射。
  • 1×1 卷积(Glow, Kingma & Dhariwal 2018):跨通道混合用 $W$ 表示,$\log|\det W|$ 每步 $O(c^3)$ 但 $c$(通道数)远小于空间维,且 Glow 用 LU 参数化把 $\det W$ 变成对角元乘积,$O(c)$。
  • 连续流(FFJORD, Chen et al. 2018 的 Neural ODE 路线):把离散变换换成 ODE $\dot z=v(z,t)$,瞬时变化率满足 $\frac{d}{dt}\log p(z(t))=-\mathrm{tr}\big(\frac{\partial v}{\partial z}\big)$——行列式消失了,只剩 trace,这恰是 Jacobi 公式在单位阵处的形态:无穷小变换的 log det 就是迹。连续化把最难的那项从 $O(n^3)$ 降到 $O(n)$ 次向量-雅可比积估计(Hutchinson 估计器)。

一句话:归一化流的架构史就是一部"绕开一般行列式、把 log det 变便宜"的历史,而 Jacobi 公式是说明这件事为什么重要的唯一原因。

应用二:高斯 MLE 与精度矩阵

$d$ 维高斯的对数似然,用精度矩阵 $\Lambda=\Sigma^{-1}$ 参数化后:

$$ \ell(\Lambda)=\frac{n}{2}\log\det\Lambda-\frac{n}{2}\mathrm{tr}(S\Lambda)+\text{const}, $$

$S$ 是样本协方差。对 $\Lambda$ 求导(注意 $\Lambda$ 对称,按上一篇要做对称化,而这里 $\Lambda^{-\top}$ 与 $\Lambda^{-1}$ 已经对称,修正自动满足):

$$ \nabla_\Lambda\ell=\frac{n}{2}\big(\Lambda^{-1}-S\big)=0\ \Longrightarrow\ \Lambda=S^{-1},\quad \Sigma=S. $$

样本协方差就是 MLE——这个经典结论的推导核心就是 Jacobi 公式加 trace 微分各用一次。图模型里的 GLASSO(图套索)在 $\log\det\Lambda-\mathrm{tr}(S\Lambda)$ 上加 $\|\Lambda\|_1$ 惩罚学稀疏精度矩阵,优化器的每一步梯度都是 $\Lambda^{-1}-S$ 的变形,Jacobi 公式在每条迭代里都活一次。

逆矩阵微分的实战位:隐函数梯度

$dX^{-1}=-X^{-1}dX\,X^{-1}$ 单独看只是条公式,配上隐函数定理就变成了双层优化(bilevel optimization)的核心工具。经典场景:内层解线性系统 $A(\theta)x=b(\theta)$(元学习里的内层训练、深度均衡模型 DEQ 的不动点),外层要对 $\theta$ 求导。对 $Ax=b$ 两边微分:

$$ dA\cdot x+A\,dx=db\quad\Longrightarrow\quad dx=A^{-1}(db-dA\cdot x), $$

于是外层梯度 $\bar\theta$ 通过 $\bar x^\top dx=\bar x^\top A^{-1}(db-dA\,x)$ 回传。令 $\lambda=A^{-\top}\bar x$(解一次共轭线性系统),则

$$ \bar\theta\text{ 的贡献}=\lambda^\top db-(\lambda x^\top)\cdot dA, $$

即对 $b$ 的梯度是 $\lambda$,对 $A$ 的梯度是外积 $-\lambda x^\top$。整个链条只需要解两次线性系统(正向解 $x$、反向解 $\lambda$),从不需要实例化 $A^{-1}$——逆矩阵的微分永远以"再解一次系统"的形态落地,这就是为什么前文说显式求逆是反模式。MAML 的二阶梯度、超参数优化的隐式微分(implicit differentiation)都是这条链的特化。

另一个大规模场景的搭档是 Hutchinson trace 估计器:Jacobi 公式的右侧 $\mathrm{tr}(X^{-1}dX)$ 在大矩阵下仍嫌贵,用随机探针 $\mathrm{tr}(M)\approx\frac{1}{k}\sum_i \epsilon_i^\top M\epsilon_i$($\epsilon_i$ 取 Rademacher 随机向量)把 trace 换成 $k$ 次矩阵-向量乘。FFJORD 里的 $\mathrm{tr}(\partial v/\partial z)$ 就是这么估的——理论公式与随机估计器之间,只隔着一次 trace 的线性性。

数值注记:永远用 slogdet

工程上从不先算 $\det$ 再取对数:$\det$ 在维度稍大时上溢/下溢(特征值连乘),而 $\log\det$ 量级健康。NumPy/PyTorch 都提供 slogdet 直接返回 $(\mathrm{sign},\log|\det|)$,内部走 LU 分解的对角元对数求和,$O(n^3)$ 且数值稳定。梯度的 $X^{-\top}$ 用 LU 解方程获得,不做显式求逆——显式逆矩阵在数值分析里几乎是反模式,本篇所有公式里的 $X^{-1}$ 落地时都应读作"解一次线性方程组"。

随手验证一下 slogdet 与 Jacobi 公式的一致性:

import numpy as np
rng = np.random.default_rng(0)
A = rng.standard_normal((6, 6)); X = A @ A.T + np.eye(6)   # 正定
sign, logdet = np.linalg.slogdet(X)
assert sign == 1.0 and abs(logdet - np.log(np.linalg.det(X))) < 1e-10
# Jacobi: d logdet X = tr(X⁻¹ dX),用方向导数验证
H = rng.standard_normal((6, 6)); eps = 1e-6
num = (np.linalg.slogdet(X + eps*H)[1] - np.linalg.slogdet(X - eps*H)[1]) / (2*eps)
ana = np.trace(np.linalg.solve(X, H))                      # X⁻¹H 用解方程实现
assert abs(num - ana) < 1e-8

两处细节:np.linalg.solve(X, H) 就是"$X^{-1}H$ 的正确打开方式";方向导数用 slogdet 差分而不是 det 差分,因为后者在维度稍大时数值上已经不可信。

小结与第一章收束

两条公式:$dX^{-1}=-X^{-1}dX\,X^{-1}$(恒等式两边微分),$d\log\det X=\mathrm{tr}(X^{-1}dX)$(单位阵处 trace + 平移)。前者让一切含逆矩阵的目标可微,后者撑起归一化流与高斯 MLE,并解释了流模型架构向三角/耦合结构收敛的原因——不是审美选择,是行列式成本逼的。

到这里第一章"矩阵求导与反向传播"的工具箱齐了:布局约定与微分法(第一篇)、雅可比与链式法则、trace 技巧、reverse mode 的代价账、softmax/LayerNorm/注意力三场硬仗、速查表、Kronecker 与 vec、对称矩阵修正、Jacobi 公式。第二章转向概率与信息论,这套微分语言会原封不动地带过去——交叉熵与 KL 的等价、ELBO 的推导、Gumbel-max 技巧,全部是"概率建模 + 矩阵求导"两条线的交汇。