在读论文或者自己推导优化算法的时候,我经常遇到这样一幕:一个看起来很简单的表达式 ( f(x) = x^T A x + b^T x + c ),后面的推导却突然冒出一堆“二次型”“正定矩阵”“Hessian矩阵”的结论。如果你对这几个概念之间的关系没有形成一张网,很容易卡在中间——尤其是当你发现有的文献里强调“A必须是对称矩阵”,有的例子却直接给了一个非对称矩阵,你还得自己默认为“取对称部分”。这篇文章就把矩阵的二次型、迹、正定矩阵、Hessian矩阵、实对称这串概念一次性讲透。我会从几何直觉讲到判定条件,再落到机器学习和优化里的实际场景,顺便把我踩过的坑也一并列出来。
1. 二次型:从一条多项式到一张 “会变形的曲面”
1.1 二次型的标准写法与矩阵表示
二次型听起来很唬人,其实就是一个所有项的次数都是 2 的多项式。比如两个变量的情况:
[ f(x_1, x_2) = a_{11}x_1^2 + 2a_{12}x_1x_2 + a_{22}x_2^2 ]
注意中间交叉项的系数我写成了 (2a_{12}),这是为了后面写成矩阵时更方便。如果写成 (a_{12}x_1x_2 + a_{21}x_2x_1),并且规定 (a_{12}=a_{21}),那整个式子就可以写成:
[ f(x) = x^T A x ]
其中:
[ A = \begin{bmatrix} a_{11} & a_{12} \ a_{12} & a_{22} \end{bmatrix},\quad x = \begin{bmatrix} x_1 \ x_2 \end{bmatrix} ]
推一遍你就知道为什么矩阵里要填两个 (a_{12}) 了:(x^T A x) 展开后是 (a_{11}x_1^2 + a_{12}x_1x_2 + a_{21}x_2x_1 + a_{22}x_2^2),当 (a_{12}=a_{21}) 时,中间两项合并成 (2a_{12}x_1x_2)。所以矩阵 A 天然应当是对称的。这也是实对称矩阵和二次型强绑定的起点。
推广到 n 个变量,二次型就是一个 n 元齐二次多项式,矩阵表示依然是 (x^T A x),只是 A 变成 n×n 矩阵。如果 A 不对称,那也没关系,因为任意一个方阵都可以拆成对称部分和反对称部分:
[ A = \frac{A+A^T}{2} + \frac{A-A^T}{2} ]
而反对称部分在二次型里贡献恰好为零:对任意向量 x,(x^T S x = 0),其中 S 是反对称矩阵。所以你以后看到 (x^T A x) 里面 A 不是对称阵,可以直接把它替换成 ((A+A^T)/2) 再讨论性质,结果完全一样。
1.2 二次型与曲面:配方、主轴与几何直觉
二次型不只是代数表达式,它对应的几何对象是二次曲面。在一元情形,(ax^2) 决定抛物线的开口方向和宽窄;在多元情形,二次型 (x^T A x) 决定了一个二次曲面的“弯曲方式”。
举个两维例子:
[ f(x_1, x_2) = 2x_1^2 + 3x_2^2 ]
对应矩阵是 diag(2, 3),函数图像是一个椭圆抛物面。如果你把系数改成 2 和 -3,就变成鞍形曲面——一个方向向上弯,另一个方向向下弯。这个“方向”就是矩阵的特征向量方向,而“弯的剧烈程度”就是特征值。这正是谱分解的几何含义:实对称矩阵可以正交对角化,等价于找到一个旋转坐标系,使得二次曲面在新坐标系下没有交叉项。
我在实际做优化可视化时,经常靠这个直觉判断一个函数局部是谷底还是鞍点:把 Hessian 矩阵对角化,看特征值正负。这个习惯比死记“正定矩阵特征值全为正”有用得多,因为你能直观看到哪个方向在“托住”目标函数,哪个方向在“拉垮”它。
2. 实对称矩阵:为什么所有优雅性质都以它为前提
2.1 实对称矩阵的三个核心定理
二次型讨论到最后一定会收敛到实对称矩阵。原因很简单:只有实对称矩阵才保证特征值全部是实数,而且特征向量可以取成正交基。这三个定理是整个线性代数里对机器学习最有用的一组结论:
- 实对称矩阵的特征值都是实数。所以可以按大小排序,这对优化里判断“最小特征值是否大于零”很重要。
- 不同特征值对应的特征向量彼此正交。这保证了特征向量系可以张成整个空间。
- 存在正交矩阵 Q,使得 (Q^T A Q = \Lambda),其中 (\Lambda) 是对角阵。这就是谱分解定理。
第三条最实用。它意味着任何一个实对称矩阵,都可以通过一个旋转变换变成纯对角阵。换句话说,二次型的“交叉项”不是本质属性,只是坐标系选得不好。这个观点贯穿了主成分分析、线性判别分析、高斯分布的马氏距离等一大堆方法。
2.2 谱分解与坐标系变换
谱分解 (A = Q \Lambda Q^T) 可以重写成:
[ A = \sum_{i=1}^{n} \lambda_i q_i q_i^T ]
这个式子把矩阵拆成 n 个秩一矩阵的加权和。每一个 (q_i q_i^T) 是向第 i 个特征向量方向的投影矩阵。特征值 (\lambda_i) 就是权重。
这个展开式特别直观地解释了二次型的作用方式:
[ x^T A x = \sum_{i=1}^{n} \lambda_i (q_i^T x)^2 ]
所以二次型的值可以看成:先把 x 投影到每个特征向量方向,得到坐标 (q_i^T x),再按特征值加权平方求和。特征值越大,那个方向对二次型数值的影响就越大;特征值为负,那个方向就会让曲面下弯。
我在做高斯过程回归时,核矩阵就是一个实对称半正定矩阵。谱分解让我理解为什么有时候核矩阵的条件数会爆炸:因为某些特征值几乎归零,对应方向的信息被压扁了。这时候加一个小的 jitter 项 (\epsilon I),本质就是把所有特征值整体抬升,避免求逆时候数值不稳定。
3. 矩阵的迹:一个被低估的标量
3.1 迹的循环性与不变量
迹的定义很简单:方阵对角线元素之和,记作 (\operatorname{tr}(A))。它有三个性质是我几乎天天用的:
- (\operatorname{tr}(AB) = \operatorname{tr}(BA)),这个叫循环性,更一般地有 (\operatorname{tr}(ABC) = \operatorname{tr}(BCA) = \operatorname{tr}(CAB))。注意只能循环,不能随意交换,比如 (\operatorname{tr}(AB)) 一般不等于 (\operatorname{tr}(A)\operatorname{tr}(B))。
- 相似变换不改变迹:(\operatorname{tr}(P^{-1}AP) = \operatorname{tr}(A))。所以迹等于特征值之和:(\operatorname{tr}(A) = \sum \lambda_i)。
- 迹和弗罗贝尼乌斯范数绑定:(|A|_F^2 = \operatorname{tr}(A^T A))。
其中“迹等于特征值之和”这个结论经常被用来做数值检查。比如你用特征值分解库求出所有特征值,求和之后跟对角线元素之和核对一下,如果差别很大,说明数值分解可能出了问题。这个检查成本几乎为零,但我见过不少同学从来不做。
3.2 迹在优化和统计中的两个高频落地场景
场景一是线性回归的最小二乘。误差平方和可以写成:
[ |y - Xw|^2 = (y - Xw)^T (y - Xw) ]
如果对 w 求导并令梯度为零,得到正规方程 (X^TXw = X^T y)。这里 (X^TX) 的迹等于 (\sum |x_i|^2),其实没有直接用到迹,但在岭回归里,目标函数是:
[ |y - Xw|^2 + \lambda |w|^2 = |y - Xw|^2 + \lambda \operatorname{tr}(w^T w) ]
因为 (\operatorname{tr}(w^T w) = |w|^2)。很多教材第一行就写出这个迹形式,目的是为了利用“标量的迹等于自身”以及迹的循环性求导。
场景二是多元高斯分布里的马氏距离。多元高斯概率密度里有个二次型:
[ (x - \mu)^T \Sigma^{-1} (x - \mu) ]
这个形式的期望恰好是 (\operatorname{tr}(\Sigma^{-1} \Sigma) = \operatorname{tr}(I) = n)。这可以用来检验采样代码是否正确:当你从拟合好的高斯分布里采样大量数据点,算它们的马氏距离平均值,应该接近维度 n。如果偏差太大,说明协方差矩阵估计或者是采样过程有 bug。
迹的另一个高级用途是计算矩阵微分的“对偶”关系。如果标量函数可以写成 (\operatorname{tr}(A^T B)) 的形式,那么对 A 求梯度时直接得到 B。这个技巧在推导许多矩阵梯度时能救命。例如:
[ \frac{\partial}{\partial A} \operatorname{tr}(A^T B) = B ]
这个公式我在推导深度学习自定义层反向传播时用过很多次,比逐元素展开求导快得多。
4. 正定矩阵:判定条件不止“特征值为正”这一条
4.1 从主子式到Cholesky分解:判定正定的几条路径
正定矩阵的定义是:对任意非零向量 x,都有 (x^T A x > 0)。这个定义最清晰,但直接验证所有 x 不现实。实际判定有三条路:
- 特征值判定:A 是实对称矩阵时,所有特征值大于零 ⇔ 正定。这是最常用也最容易在代码里实现的:对 A 做特征分解,
np.linalg.eigvalsh(A),看最小值是否大于一个很小的容差。 - 顺序主子式判定:A 的所有顺序主子式都大于零 ⇔ 正定。这个方法在手动计算 2×2 或 3×3 矩阵时很有用,但数值上不建议对大矩阵用,效率低且容易累积误差。
- Cholesky 分解判定:如果能对 A 做 Cholesky 分解 (A = LL^T),其中 L 是对角元为正的下三角阵,那么 A 一定正定。实际中这是判断一个矩阵是否正定最稳健的数值手段,因为它需要开平方,一旦中间出现负数就立即失败。
我把这三种方法的使用场景列出来:
| 方法 | 适用场景 | 注意点 |
|---|---|---|
| 特征值 | 理论上分析,小规模数值验证 | 特征值接近 0 时要用阈值判断 |
| 顺序主子式 | 手算小矩阵,教学演示 | 3×3 以上计算繁琐 |
| Cholesky | 大规模数值计算、实际工程 | 会暴露矩阵半正定或数值病态问题 |
Cholesky 分解其实还有额外收益:它可以用来快速计算行列式,(\det(A) = \prod L_{ii}^2)。所以在做高斯过程时,我一般都直接对协方差矩阵做 Cholesky,一方面验证正定性,另一方面拿来求逆或采样。
4.2 正定矩阵的几何意义与“凸性”连接
正定矩阵的几何意义可以理解为:它定义了一个“椭圆形的度量”。在二维空间里,集合 ({x \mid x^T A x \le 1}) 是一个以原点为中心的椭圆。A 的特征向量是椭圆的主轴方向,特征值平方根的倒数决定主轴长度。这个椭圆是马氏距离的等高线,也是多元高斯分布置信椭球的形状。
正定矩阵和凸函数之间有直接联系。一个二阶可微函数 (f) 是凸函数,当且仅当它的 Hessian 矩阵在定义域内处处半正定。如果 Hessian 正定,则函数是严格凸。这是最优雅也最实用的桥梁:二次型的系数矩阵如果是正定的,那么对应的二次函数就是一个漂亮的碗,只有一个全局最小值。
我记得第一次学支持向量机的时候,看到对偶问题里出现 (K) 矩阵半正定的要求,其实就是在要求核矩阵定义的二次型是凸的。一旦核矩阵不正定,对偶问题就不再是凸优化,SMO 算法里的收敛性也会出问题。这也是为什么高斯核几乎永远是很多人的默认选择——它的正定性非常好,对应的 RKHS 性质也有保障。
5. Hessian矩阵:二次型理论在优化问题中的正面交锋
5.1 二阶泰勒展开:Hessian就是二次型的系数矩阵
多元函数 (f(x)) 在点 (x_0) 附近的二阶泰勒展开是:
[ f(x) \approx f(x_0) + \nabla f(x_0)^T (x - x_0) + \frac{1}{2}(x - x_0)^T H(x_0)(x - x_0) ]
其中 (H(x_0)) 就是 Hessian 矩阵,第 i 行第 j 列是 (\partial^2 f / \partial x_i \partial x_j)。只要 f 的二阶偏导数连续,混合偏导数相等,Hessian 就是实对称矩阵。这一点极其重要——它意味着上一节里所有关于实对称矩阵的性质都可以直接用在 Hessian 上。
从二次型的角度看,泰勒展开的二次项 ((x-x_0)^T H (x-x_0)) 就是函数在该点局部的弯曲程度。H 的特征值告诉你在各个方向上是凸还是凹。这也解释了为什么“Hessian 正定”是局部极小值的充分条件——如果所有方向都上弯,那么这个点就是一个谷底。
5.2 用正定性判断极值:从一元到多元
一元函数里,第一导数为零且第二导数大于零,就是极小值。多元情形推广为:梯度为零且 Hessian 正定,就是局部极小值。这里要特别注意“正定”和“半正定”的区别:如果 Hessian 是半正定,那么可能是极小值,也可能需要看高阶项,存在退化情况。
我在实际写优化代码时,遇到过不少次伪极值:梯度下降停在了某个点,梯度很小,但目标函数并不是真正的局部极小。这时候算一下 Hessian 的特征值,如果最小特征值是负的,说明你站在一个鞍点上。在高维空间里,鞍点比极小值点要多得多,这也是纯梯度下降掉进鞍点后很难逃离的原因之一。
下面是一个常见的判断流程:
- 计算梯度 (g)。如果 (|g|) 很小,进入候选。
- 计算 Hessian (H)。
- 对 (H) 做特征分解。
- 所有特征值大于 0:局部极小;所有特征值小于 0:局部极大;有正有负:鞍点;有零特征值:退化,需要更高阶判断。
5.3 Hessian在牛顿法中的角色
牛顿法是一种利用 Hessian 的优化方法。它的迭代公式是:
[ x_{k+1} = x_k - H^{-1}(x_k) \nabla f(x_k) ]
这个公式可以这样理解:在每一点用一个二次函数去近似目标函数,然后直接跳到这个二次函数的极小值。如果目标函数本身是二次正定函数,牛顿法一步就能到达极小点。
但牛顿法有两个痛点:一是 Hessian 可能是奇异阵,求逆会爆炸;二是 Hessian 可能是非正定的,迭代方向可能不是下降方向。这就是为什么工程上用 LM(Levenberg-Marquardt)或者拟牛顿法(BFGS、L-BFGS),本质上都是对 Hessian 做了“正定化”处理。BFGS 用梯度差值来逐步逼近真实 Hessian 的逆,而且保证更新后保持正定——这里正定就变成了算法稳定性的护身符。
我在调深度模型优化器时,Adam 这类自适应方法其实也隐含着对 Hessian 的粗略估计。它的二阶矩估计可以粗略看作对角化的 Hessian 近似,再用缩放的方式避免直接用二阶导。理解了正定和凸性之后,你就会明白为什么 Adam 能在大模型上表现稳定——因为对一阶矩做单位化缩放,等价于给每个参数单独的学习率,这相当于用一个正定对角矩阵做预条件。
6. 实操中的三个常见误区:等价条件、迹求导、非对称Hessian
6.1 误区一:把“顺序主子式为正”当成所有正定的判定方式
教材里经常出现“顺序主子式都大于零”这个判定条件,但它有一个隐性前提:矩阵必须是实对称的。如果拿一个非对称矩阵,顺序主子式为正并不能推出正定。我曾在一段代码里用scipy.linalg.det去循环计算子矩阵行列式来判定正定性,不仅慢,还会漏判。
更稳妥的做法是:直接用 Cholesky 分解。在 NumPy 里就是:
import numpy as np try: L = np.linalg.cholesky(A) print("A is positive definite") except np.linalg.LinAlgError: print("A is NOT positive definite")6.2 误区二:对迹求导时搞混分母布局
在矩阵求导里,常见的错误是不注意分母布局和分子布局。比如对向量 w 求导,(\frac{\partial}{\partial w}(w^T A w)) 的结果是 ((A + A^T)w)。如果 A 是对称矩阵,可以写成 (2Aw);但如果 A 不对称,必须保留 (A + A^T)。
我见过有人看到 A 是对称矩阵就顺手写 (2Aw),结果后面卷积核或协方差矩阵不是精确对称时,梯度方向就错了。宁可每次都用 (A + A^T),再根据上下文判断能不能化简,也不要默认对称。这个习惯在推反向传播时帮了大忙。
6.3 误区三:遇到Hessian矩阵不是实对称的情况
理论上二阶连续偏导保证 Hessian 对称,但数值上计算得到的 Hessian 可能不对称。原因有两个:一是浮点误差;二是在神经网络里,你用自动微分算子组装 Hessian 时,某些算子没有正确实现二阶导数交换律,导致上三角和下三角不一致。
遇到这种情况,我建议先检查实现:如果差得很小,可以对称化处理 (H \leftarrow (H + H^T)/2);如果差得很大,说明自动微分图里可能有不光滑算子或数值不稳定项。不要强行对称化,先定位差异来源。
此外,很多优化库要求传入的 Hessian 本身是实对称的,例如scipy.optimize.minimize的hess参数。如果你传入一个非对称矩阵,结果不可控。
我个人的习惯是:在推导任何涉及二次型的公式时,第一步先把矩阵的对称性写清楚;第二步把二次型化为特征值加权平方和;第三步再看是要用迹、行列式还是 Cholesky。这套流程帮我在读论文、写代码、调试优化器的时候少走了很多弯路。如果你也经常被这些概念绕晕,不妨从今天开始,遇到一个函数就先把它在关键点处的二次型写出来,再问自己一句:这个矩阵对称吗?特征值有多少是正的?答案是正的时候,很多难题会突然变得清晰。