这个系列前面几篇一直在用一个约定:$df=\mathrm{tr}(A^\top dX)$ 时称 $A$ 为梯度。为什么是这个形式而不是别的?梯度难道不是"导数排成向量"吗?不是。严格地说,微分是内蕴的,梯度是表示出来的,两者之间隔着一座桥:内积。看懂这座桥,整个矩阵求导系列的记号选择、最速下降方向的方向之争、乃至自然梯度的动机,全部各归其位。
微分:不需要坐标的线性映射
设 $f:\mathbb{R}^n\to\mathbb{R}$ 在 $x$ 可微。微分 $df_x$ 是一个线性映射(线性泛函):给定扰动方向 $h$,它给出函数值的一阶变化
$$ f(x+h)=f(x)+df_x(h)+o(\|h\|). $$
这个定义里 $h$ 是"方向扰动"而不是"点"——$df_x$ 是对扰动的响应规则,固定 $x$ 后它对 $h$ 线性。线性性是整个链条的起点:后面 Riesz 定理、链式法则的雅可比形式,全靠它成立。
$df_x$ 本身不是向量,它活在 $h$ 的对偶空间里——它"吃"向量、"吐"标量。偏导数 $\partial f/\partial x_i$ 只是它在标准基下的系数:$df_x(h)=\sum_i\frac{\partial f}{\partial x_i}h_i$。到这里为止,一切定义都不需要内积参与。
"吃向量、吐标量"不是修辞。$\mathbb{R}^n$ 上所有线性泛函构成的对偶空间 $V^*$ 与 $V$ 维数相同、甚至同构,但同构方式不唯一——没有内积就没有"自然"的那一个。这就是为什么"把导数直接当向量"在任何稍一般的场合都会露馅:雅可比矩阵对非方阵根本排不成同形向量,连排都排不下,这个日常事实本身就是"导数不是向量"的证据。
Riesz 表示定理:线性泛函的向量化身
问题是工程上要算、要存、要传给优化器的是一个向量。从线性泛函到向量需要桥,桥是内积。Riesz 表示定理:在 Hilbert 空间里,每个连续线性泛函 $\phi$ 都存在唯一向量 $u$,使
$$ \phi(h)=\langle u,h\rangle\quad\forall h. $$
把这个 $u$ 命名为梯度:$\nabla f(x)$ 由 $df_x(h)=\langle\nabla f(x),h\rangle$ 定义。注意这个定义的循环依赖性——梯度长什么样,取决于你选了什么内积。
定理里"唯一"两个字承担了全部重量:选定了内积,表示向量就被钉死,不存在"另一个同样合法的梯度"。所以争论"梯度该是什么"从来不是数学分歧,只是双方默认的内积不同——把内积摆到桌面上,分歧就显形了。
标准欧氏内积 $\langle u,h\rangle=u^\top h$ 下,$\nabla f$ 恰好是偏导数拼成的列向量,这就是我们熟悉的形式,熟悉到很多人以为它是定义。它是表示,不是定义。
这里有一个表述习惯要说清:不少教材把"梯度"直接定义为偏导数向量,这在欧氏空间里不算错,只是把这个定义能用多久的问题藏了起来——一旦离开平直欧氏空间(加权、流形、复空间),那套定义就要打补丁,而微分的定义纹丝不动。先微分后表示的顺序,是为这些推广预留的正确地基。
工程语境里的对应物:代码审查时看到"梯度"一词,第一反应该问"哪个度量下的"。预条件器的输出、.grad 里的原始值、论文里的自然梯度,是三件不同的东西,混用任何两个都会产生静默的错误缩放。
换内积,换梯度:Mahalanobis 的例子
换一个内积试试。给对称正定矩阵 $M$,定义加权内积 $\langle u,h\rangle_M=u^\top M h$。同一个微分 $df_x$(系数仍是 $\partial f/\partial x_i$)在新内积下的表示向量 $g_M$ 要满足
$$ df_x(h)=(\nabla_{\text{euc}}f)^\top h=g_M^\top M h\quad\forall h \ \Rightarrow\ \boxed{\ g_M=M^{-1}\nabla_{\text{euc}}f\ } $$
微分没变,梯度变了——而且是左乘 $M^{-1}$。这个公式眼熟不是巧合:自然梯度就是 $M$ 取 Fisher 信息矩阵时的特例,牛顿方向是 $M$ 取海森时的特例。它们都是"同一个微分在不同内积/度量下的梯度表示"。 Amari 的自然梯度之所以叫"自然",正因为它选择的是参数空间作为统计流形上的内蕴内积,不随参数化方式改变。
这里有一个方向性细节容易看反:加权内积把"贵的方向"拉长,梯度表示里就要用 $M^{-1}$ 把它压回去——在贵方向上走得少。度量与逆度量一个管"怎么量距离"、一个管"怎么改方向",两者的倒置关系是理解一切预条件器的钥匙:预条件矩阵出现在更新式的位置永远是逆。
矩阵情形的 trace 约定也是同一回事:矩阵空间 $\mathbb{R}^{m\times n}$ 上选 Frobenius 内积 $\langle A,B\rangle_F=\mathrm{tr}(A^\top B)$,微分 $df(dX)$ 的 Riesz 表示就是满足 $df=\mathrm{tr}(G^\top dX)$ 的那个 $G$。整个系列"凑 trace 标准形"的全部操作,本质都是在 Frobenius 内积下读出表示向量。
顺带回应一个常见疑问:能不能给矩阵参数也上 Mahalanobis 内积 $\mathrm{tr}(A^\top MB)$?能,而且这正是 K-FAC 在做的事的一种读法——把参数矩阵空间上的度量取成 Kronecker 结构。公式的形态因此完全一致,变的只是"M 选什么",这再次说明内积视角的推广没有边界。
为什么偏偏是 Frobenius 内积?两个理由。其一是计算上的:它与向量化后的欧氏内积完全一致($\mathrm{tr}(A^\top B)=\mathrm{vec}(A)^\top\mathrm{vec}(B)$),所以矩阵求导的结论与把矩阵拉直当向量求导逐分量吻合,不会让"矩阵版公式"与"向量版公式"打架。其二是几何上的:它在正交变换下不变($\langle QAU,QBU\rangle_F=\langle A,B\rangle_F$),意味着它不偏袒任何坐标方向——对没有特殊结构的参数矩阵,这是唯一"中立"的选择,与最大熵原理里均匀先验的地位平行。
最速下降方向也是内积的函数
"梯度指向最速上升方向"这句话同样依赖内积。严格的问法是:在单位球 $\{h:\|h\|=1\}$ 上最大化方向导数 $df_x(h)=\langle\nabla f,h\rangle$。Cauchy-Schwarz 给出答案 $h^*=\nabla f/\|\nabla f\|$——但范数来自内积,换内积连"单位球"的形状都变了。
先把论证链条摆完整:方向导数有内积表达式是 Riesz 定理给的;最大化内积在单位球上的解是 Cauchy-Schwarz 给的;而"单位球是什么形状"又回到范数即内积。三步里两步依赖内积——最速方向是几何对象,不是分析对象。具体看几种常见球:
- $\ell_2$ 球(欧氏):$h^*\propto\nabla f$,梯度下降;
- Mahalanobis 球 $\|h\|_M=1$:$h^*\propto M^{-1}\nabla f$,自然梯度/牛顿方向;
- $\ell_1$ 球:$h^*$ 集中在 $|\nabla f|$ 最大的单个坐标上,坐标下降。
所以"用哪个方向更新"没有绝对答案,只有你隐式选择了哪种几何。Adam 的对角预条件、信赖域方法、镜像下降,全部可以读成"选择不同的单位球"。
镜像下降值得多给两行:它把"距离"从欧氏平方换成 Bregman 散度 $D_\phi(x,y)=\phi(x)-\phi(y)-\nabla\phi(y)^\top(x-y)$,更新规则变成在对偶空间里走直线再映射回来。取 $\phi$ 为负熵时,在概率单纯形上导出的正是指数化梯度(exponentiated gradient)——乘法更新、天然保正性,与 softmax 的几何完美咬合。这又绕回了本系列反复出现的主题:选对几何,朴素方法自动变成"聪明"方法。
一个算到底的二维例子
抽象讨论落个数。取 $f(x)=x_1^2+3x_2^2$,在 $x=(1,1)$ 处欧氏梯度 $g=(2,6)^\top$。换 Mahalanobis 内积 $M=\mathrm{diag}(1,3)$:
$$ g_M=M^{-1}g=\begin{pmatrix}1&0\\0&1/3\end{pmatrix}\begin{pmatrix}2\\6\end{pmatrix}=\begin{pmatrix}2\\2\end{pmatrix}. $$
两个梯度不同,但微分是同一个:任意方向 $h$ 上,$df(h)=g^\top h=g_M^\top M h$,两种表示给出同一个数。几何上,$g$ 垂直于欧氏圆球的切线方向,$g_M$ 垂直于被 $M$ 拉伸的椭球的"切线"——在拉长 $x_2$ 的几何里,$x_2$ 方向的步子显得更"贵",梯度因此把它调小。二次型 $f(x)=x^\top Mx$ 时还有个漂亮巧合:$g=2Mx$,$g_M=2x$,加权梯度一步直指原点——内积选得贴合问题的曲率,梯度法当场变牛顿法。这就是"选内积=选几何=选收敛速度"的最小演示。
这个演示也能反过来当设计工具用:面对一个收敛慢的问题,先问"它的曲率张什么样",再找一个 $M$ 让加权后的等高线尽量圆。Adam 的对角 $M$ 对应"逐坐标拉直",K-FAC 的 Kronecker 结构对应"层内双方向拉直",都是在用可负担的 $M$ 逼近"把椭圆捏回圆"这件事。
坐标变换下谁变谁不变也值得记一笔:换参数化 $\theta\mapsto\varphi(\theta)$,微分作为对偶向量按 $J^\top$ 变换,度量张量按 $J^\top MJ$ 变换,两者配合使 $df(h)$ 不变。自然梯度号称"参数化不变",靠的正是 Fisher 度量与梯度按相反规则变换后方向抵消。
再看离散情形补上最后一块拼图:概率单纯形上没有平直的欧氏几何,自然的选择是 Fisher-Rao 度量 $M_{ij}=\mathbb{E}[\partial_i\log p\,\partial_j\log p]$。在这套内积下,对数似然对得分的微分的表示向量恰好回到朴素 softmax 参数化——换句话说,指数族参数化(最大熵那篇的主题)是"让 Fisher 内积在参数坐标下呈现最简单形式"的坐标系。内积视角、指数族、自然梯度在这里汇成同一条线。
一个二维例子之外的收尾观察:内积视角下"梯度为零"的定义不变(微分为零泛函在任何内积下的表示都是零向量),所以极值点的位置不依赖几何选择——变的只是抵达路径。这句话值得记住:换预条件器、换度量不改变收敛点集合(凸情形下),只改变收敛速度与轨迹形状。优化器之争是几何之争,不是目标之争。
再补一个观察把上一节的图景闭环:欧氏内积是"所有方向等价"的几何,所以它给出的梯度在参数坐标拉伸下会变形——把某层权重整体放大 10 倍、偏置不变,函数不变但梯度方向剧烈改变。这正解释了为什么有归一化层的网络里参数尺度的变化如此频繁而不影响函数:LayerNorm/RMSNorm 让函数对缩放不变(LayerNorm 反向那篇详推过),欧氏梯度里对应的径向分量是纯浪费的运动,weight decay 与归一化的交互研究的就是这部分"虚位移"。换了贴合不变性的度量,这些虚位移在几何里直接消失。
从定义重新推导熟悉的公式
为验证这套定义确实回到熟悉的结果,从头推一遍二次型。$f(x)=\frac12x^\top Ax$($A$ 对称),微分是 $df_x(h)=x^\top Ah$。欧氏内积下的梯度要满足 $\langle\nabla f,h\rangle=(\nabla f)^\top h=x^\top Ah$ 对一切 $h$ 成立,读出 $\nabla f=Ax$——与直接求偏导一致。整个练习的价值在于看清楚:每一步里"导数"作为线性泛函在前,"梯度"作为表示向量在后,两者的转换点永远写着内积的名字。
再看复值与流形的边界。复向量空间上内积要带共轭,Riesz 表示相应给出 Wirtinger 微积分的规则;弯曲流形(球面、正交群)上内积逐点变化,梯度变成切空间里的表示——Riemannian 梯度下降就是这么来的。这些看似高深的构造没有一个超出"选定内积、读表示向量"这两步。
内积视角下的推导方法论
这套视角还反向改进了推导本身的工作流。矩阵求导里最机械的步骤——"把 $d\ell$ 整理成 $\mathrm{tr}(G^\top dX)$"——现在有了正式身份:它是在 Frobenius 内积下求 Riesz 表示向量。整理技巧(循环置换、转置恒等式)因此不是背诵清单,而是同一个内积下的换元法则。遇到新的张量结构(比如对 $(b,h,n,d)$ 四阶张量的梯度),第一件事是选定内积(几乎总是逐分量乘积求和的自然内积),剩下的推导路径是确定的。
它也澄清了"梯度检查该对比什么":内积不变时,reshape、permute、转置存储都只是坐标重排,表示向量随之按相同规则重排——这就是为什么 gradcheck 里 analytic 与 numeric 可以直接逐分量对比而不问布局。一旦有人在内积里加了权重(加权损失、mask),对比之前要先确认两边用的是同一个内积下的表示,否则差出来的不是误差而是几何。
这座桥解决了什么实际困惑
内积视角不是哲学装饰,它直接回答几个学习路上的真实困惑:
- 为什么矩阵梯度定义成 $df=\mathrm{tr}(G^\top dX)$ 而不是别的形式:因为 Frobenius 内积下这是 Riesz 表示的唯一形式,"凑 trace"就是在做表示定理的计算。2. 为什么张量 reshape/换布局后梯度公式要跟着变:reshape 改了坐标,若内积形式不变(Frobenius 内积对 reshape 不变),表示向量跟着做同样的 reshape 即可——梯度 reshape 与参数 reshape 一致,这不是巧合是内积保持的推论。
-
自然梯度、牛顿法、信赖域的统一:全是"同一微分 + 不同度量"。优化器的近代史一半是在选度量,另一半是在廉价地近似它(见上一篇海森的成本账)。
-
为什么深度学习库把梯度默认存成与参数同形的张量:梯度是表示向量,参数是点;同形只是标准基下的便利。换了内积(比如做预条件),"梯度"就该先经过 $M^{-1}$ 才配和参数相减——
optimizer.step()里预条件器做的正是这件事,框架把这一步藏进了优化器而不是 autograd,分工的界线就画在内积的选择上。
还有一层表述上的澄清值得留下:数学文献里常说"梯度是列向量、导数是行向量(雅可比)",这个行列之争在欧氏内积下确实是转置关系,但它只是表示层面的 bookkeeping。内蕴对象——微分——不分行列,行列是你选定内积与坐标之后的排版决定。纠结"梯度该横着写还是竖着写"的人,真正该问的是"我用的是哪个内积"。
小结
微分 $df_x$ 是内蕴的线性泛函,不依赖任何内积;梯度是它在选定内积下经 Riesz 定理得到的向量表示。欧氏内积给出偏导数向量,Frobenius 内积给出矩阵梯度,Fisher/海森内积分别给出自然梯度与牛顿方向,最速下降方向随单位球形状而变。记住"换内积 = 换几何 = 换梯度",优化器设计里一半的黑话就都有了坐标。
这套语言练熟的标志是能自如地做"翻译":看到任何一个优化器更新式,先拆出"它用的微分是什么"(几乎总是同一个 $\nabla L$)与"它的度量是什么"(对角、Kronecker、信赖域球),两部分一拼,这个优化器的全部行为边界就清楚了。
作为本章的收官篇之一,再强调一次它在工具箱里的位置:前面几篇的所有"凑成标准形"操作,合法性都来自这里的表示定理;后面所有关于优化器的讨论,词汇表都来自这里的度量语言。内积这座桥一旦搭好,两岸的货就都能过了。下一篇落到最朴素的地方:从 SGD 的一行更新式里拆出深度学习的最小结构。