前几篇的微分法对付"标量对矩阵求导"所向披靡,但有两类问题它会变得笨拙:一是矩阵对矩阵求导(比如整层输出对整层输入的雅可比,结果是四维张量,微分法给不出舒服的记号);二是矩阵方程求解(Lyapunov 方程 $AX+XB=C$ 这类,未知数被两个常量夹着)。这两个问题的共同解法是先把矩阵"拉直"成向量——vec 操作,配上 Kronecker 积这把瑞士军刀。更实际的是,这套工具是 K-FAC、Shampoo 等二阶优化器的理论语言,不理解它就读不懂现代预训练优化的一半文献。
vec 与 Kronecker 积的定义
vec 操作把矩阵按列堆成向量:$X\in\mathbb{R}^{m\times n}$,
$$ \mathrm{vec}(X)=\begin{bmatrix}X_{:,1}\\ X_{:,2}\\ \vdots\\ X_{:,n}\end{bmatrix}\in\mathbb{R}^{mn}. $$
Kronecker 积 $A\otimes B$($A\in\mathbb{R}^{p\times q}$、$B\in\mathbb{R}^{r\times s}$)是把 $A$ 的每个元素替换成该元素乘以整个 $B$ 的分块矩阵,结果是 $pr\times qs$:
$$ A\otimes B=\begin{bmatrix}a_{11}B&\cdots&a_{1q}B\\ \vdots&\ddots&\vdots\\ a_{p1}B&\cdots&a_{pq}B\end{bmatrix}. $$
两个常用性质先记住:$(A\otimes B)^\top=A^\top\otimes B^\top$,以及混合积 $(A\otimes B)(C\otimes D)=(AC)\otimes(BD)$(维度相容时)——Kronecker 积与矩阵乘"可交换次序",这是它一切魔力的来源。
核心恒等式:vec(AXB) = (Bᵀ⊗A)vec(X)
整套理论只建立在一个恒等式上:
$$ \boxed{\;\mathrm{vec}(AXB)=(B^\top\otimes A)\,\mathrm{vec}(X)\;} $$
推导不复杂,按列看就行。$AXB$ 的第 $j$ 列是 $A\,X\,B_{:,j}=A\sum_k b_{kj}X_{:,k}$,即 $X$ 各列的线性组合再左乘 $A$。vec 后第 $j$ 段正好是 $\sum_k b_{kj}(A\,X_{:,k})$,这正对应分块矩阵 $B^\top\otimes A$ 的第 $j$ 个块行(其块为 $b_{kj}A$)作用在 $\mathrm{vec}(X)$ 上。逐列对应,等式成立。
这个恒等式的意义:矩阵左乘 $A$、右乘 $B$ 这种"双侧作用",在 vec 世界里就是单次矩阵-向量乘,矩阵维数从 $m\times n$ 涨到 $mn\times mn$,但换来了向量空间的全套工具(线性方程、特征值、求导都能用标准记号)。
配套的还有两条常用推论:$\mathrm{tr}(A^\top B)=\mathrm{vec}(A)^\top\mathrm{vec}(B)$(trace 内积即 vec 点积,前几篇一直在用);$\mathrm{vec}(AX)=(I\otimes A)\mathrm{vec}(X)$,$\mathrm{vec}(XB)=(B^\top\otimes I)\mathrm{vec}(X)$(单侧作用是上式的退化)。
战例一:矩阵最小二乘拉回普通最小二乘
$\|XW-Y\|_F^2$ 对 $W$ 求导,vec 视角下:$\mathrm{vec}(XW)=(I\otimes X)\mathrm{vec}(W)$,于是目标函数就是普通最小二乘 $\|(I\otimes X)w-y\|^2$($w=\mathrm{vec}(W)$),梯度 $2(I\otimes X)^\top\big((I\otimes X)w-y\big)$。用混合积展开 $(I\otimes X)^\top(I\otimes X)=I\otimes X^\top X$,正规方程变成
$$ (I\otimes X^\top X)\,\mathrm{vec}(W)=(I\otimes X^\top)\mathrm{vec}(Y)\ \Longleftrightarrow\ X^\top XW=X^\top Y, $$
与第三篇微分法的结果一致。绕了一圈回到原地,但这正是目的:vec+Kronecker 把矩阵问题翻译成向量问题,翻译结果与直接推导互相印证,哪边都不出错。
战例二:矩阵对矩阵的雅可比
微分法说不清的"矩阵对矩阵求导",vec 后立刻有定义:$Y=AXB$ 时
$$ \frac{\partial\,\mathrm{vec}(Y)}{\partial\,\mathrm{vec}(X)}=B^\top\otimes A. $$
线性层的雅可比因此有了统一表达。它还能反推 VJP:$\mathrm{vec}(\bar X)=(B^\top\otimes A)^\top\mathrm{vec}(\bar Y)=(B\otimes A^\top)\mathrm{vec}(\bar Y)$,再用恒等式反 vec 回去得 $\bar X=A^\top\bar Y B^\top$——上一篇速查表里的"对调转置"口诀,在这里有了正式出处。口诀是从这个恒等式推出来的,不是背下来的巧合。
为什么深度学习从不实例化 Kronecker 积
恒等式虽美,$mn\times mn$ 的尺寸是灾难:$d=4096$ 的线性层,$I\otimes X$ 是 $4096^2\times4096^2$ 量级,没有任何硬件装得下。所以主流框架的 autograd 完全不走这条路——VJP 直接用原始矩阵乘表达($A^\top\bar Y B^\top$),Kronecker 积只存在于理论分析里。
但有一个领域真的把 Kronecker 积搬到了工程上,靠的正是它的逆有廉价结构。
K-FAC:Kronecker 分解救活二阶优化
二阶优化(牛顿法家族)需要海森或 Fisher 信息矩阵 $F$,参数量 $p$ 时存储 $p^2$、求逆 $p^3$,对大模型完全不可行。K-FAC(Martens & Grosse, 2015)的观察:线性层 $y=Wx$ 的 Fisher 块在理想化假设下可分解为
$$ F_{W}\approx \mathbb{E}[xx^\top]\otimes\mathbb{E}[\bar y\,\bar y^\top]=:A\otimes G, $$
$A$ 是输入的二阶矩($d_{\text{in}}\times d_{\text{in}}$),$G$ 是输出梯度的二阶矩($d_{\text{out}}\times d_{\text{out}}$)。注意顺序——这里用的是 $\mathrm{vec}(W)$ 按行展开的约定(文献里常用 $\mathrm{vec}$ 的行版本,顺序因此和上式相反),记号细节各家不同,结构思想一致。这个分解的回报来自混合积的推论:
$$ (A\otimes G)^{-1}=A^{-1}\otimes G^{-1}. $$
$mn\times mn$ 矩阵的逆,拆成两个小矩阵各自求逆再做 Kronecker——存储从 $(mn)^2$ 降到 $m^2+n^2$,求逆从 $O((mn)^3)$ 降到 $O(m^3+n^3)$,差四个数量级。自然梯度更新 $w\leftarrow w-\eta F^{-1}\bar w$ 甚至不需要显式构造 $F^{-1}$:
$$ \mathrm{vec}\big(G^{-1}\bar W A^{-1}\big)=(A^{-\top}\otimes G^{-1})\mathrm{vec}(\bar W), $$
对称矩阵下 $A^{-\top}=A^{-1}$,更新就是 $\bar W$ 左右各夹一个小逆矩阵——这个"双侧三明治"形态就是 vec 恒等式的直接化身。Shampoo 把同一思想用到梯度二阶矩的预处理上,2024 年 MLCommons 训练速度赛上多个赛道冠军用的都是它,二阶方法因此在大模型预训练里真正落了地。
用 NumPy 验证核心恒等式
恒等式这种东西,亲手验一次比看三遍证明管用:
import numpy as np
rng = np.random.default_rng(0)
A = rng.standard_normal((3, 4))
X = rng.standard_normal((4, 5))
B = rng.standard_normal((5, 2))
lhs = (A @ X @ B).flatten(order="F") # vec:按列堆叠
rhs = np.kron(B.T, A) @ X.flatten(order="F") # (Bᵀ⊗A) vec(X)
assert np.allclose(lhs, rhs) # 恒等式成立
# 逆可分拆:(A⊗G)⁻¹ = A⁻¹⊗G⁻¹
G = rng.standard_normal((2, 2)); G = G @ G.T
AA = rng.standard_normal((3, 3)); AA = AA @ AA.T
assert np.allclose(np.linalg.inv(np.kron(AA, G)), np.kron(np.linalg.inv(AA), np.linalg.inv(G)))
两个细节:flatten(order="F") 对应按列 vec(NumPy 默认按行,这是最常见的踩坑点);第二条断言就是 K-FAC 省四个数量级的全部代数学依据。
从 K-FAC 到 Shampoo:同一个恒等式的两种用法
K-FAC 分解的是 Fisher(对数似然二阶导的期望),Shampoo 分解的是梯度外积的累计量 $\sum_t \mathrm{vec}(\bar W_t)\mathrm{vec}(\bar W_t)^\top$,同样近似为 $L\otimes R$,但预 conditioner 取的是四次根:更新形如 $L^{-1/4}\bar W R^{-1/4}$。取四次根而不是逆的直觉:Shampoo 把 $L,R$ 当作全 Adagrad 在矩阵维度上的近似——完整 Adagrad 的预 conditioner 是梯度平方累计的逆平方根,分解到左右两侧后各摊一半,逆平方根分到两边就成了逆四次根。严格推导可以用 vec 恒等式验证:$L^{-1/4}\bar WR^{-1/4}$ vec 后正是 $(R^{-1/4}\otimes L^{-1/4})\mathrm{vec}(\bar W)$,即预条件矩阵 $(R\otimes L)^{-1/4}$ 的 VJP 形式。看懂这一个句子,Shampoo 论文的核心算法页就没有秘密了。
vec 视角的其他用途
vec+Kronecker 在深度学习理论里还有几个固定出场位。Lyapunov/Sylvester 方程 $AX+XB=C$ vec 后变 $(I\otimes A+B^\top\otimes I)\mathrm{vec}(X)=\mathrm{vec}(C)$,这是分析线性动力系统和 RNN 稳定性的标准起手式;矩阵微分里处理 $f(X)=\varphi(AXB)$ 这类复合时,vec 后的链式法则 $D_X=(B^\top\otimes A)^\top D_Y$ 让高维张量求导保持二维记号;随机矩阵与初始化理论里,$\mathbb{E}[\mathrm{vec}(W)\mathrm{vec}(W)^\top]$ 这类量的结构分析也离不开它。
小结
vec 把矩阵拉成向量,Kronecker 积把双侧矩阵作用翻译成一次大矩阵乘,恒等式 $\mathrm{vec}(AXB)=(B^\top\otimes A)\mathrm{vec}(X)$ 是唯一的支点。直接应用受限于 $mn\times mn$ 的尺寸而停留在理论层,但 K-FAC/Shampoo 用"分解+逆可分拆"把同一结构变回了工程现实——理解 vec 恒等式,二阶优化文献就从天书变成了代数练习。下一篇处理矩阵微分里最后一个经典陷阱:对对称矩阵求导时,独立变量只有一半,梯度该怎么修正。