☰
二次型 x^T A x 梯度推导:从矩阵求导到对称性陷阱全解析
2026/10/2 10:08:49 网站建设 项目流程

你没看错,标题写的确实是“二次型 x^T A x 梯度(求导)推导过程”。这可能是很多人在机器学习、最优化理论、控制理论甚至数值计算里遇到的第一个矩阵求导题。网上答案一搜一大把,但大多数直接甩一个结论:如果 A 对称,梯度是 2Ax。可问题是,凭什么?如果 A 不对称又怎么办?为什么有的地方写 (A + A^T)x?我最初学的时候也被这些版本绕晕过。这篇文章我就把这个推导过程彻底摊开,从最原始的分量展开讲到矩阵微分,再把对称性这个坑单独拎出来说清楚。不管你是刚接触矩阵求导,还是用到的时候想回头确认一下,这篇都值得你花十分钟看完。

1. 先搞清楚二次型和梯度到底是什么

1.1 二次型的定义与矩阵形式

先说二次型。所谓二次型,就是所有项都是二次的多变量多项式。比如两个变量的二次型是:

f(x1, x2) = a11 x1^2 + a12 x1 x2 + a21 x2 x1 + a22 x2^2

注意这里我把“x1 x2”和“x2 x1”分开写了。合并同类项的话,二次项系数通常是 a12 + a21,但用矩阵表示时,我们保留分开的形式,这样能对应到矩阵的每个元素。

用矩阵写就更紧凑了。设向量 x = (x1, x2, ..., xn)^T,矩阵 A 是 n×n 的实矩阵,那么二次型可以写成:

f(x) = x^T A x = Σ_{i=1}^n Σ_{j=1}^n a_ij x_i x_j

这个求和式是理解所有推导的基础。很多教材直接从矩阵形式开始算,但初学者容易懵,因为不知道 x^T A x 展开后到底长什么样。所以第一步一定要自己在纸上把 n=2、n=3 的展开写一遍。比如 n=2 时:

x^T A x = (x1, x2) [[a11, a12], [a21, a22]] (x1, x2)^T = a11 x1^2 + a12 x1 x2 + a21 x2 x1 + a22 x2^2

看到没有,矩阵里 a12 和 a21 是分别跟着 x1 x2 和 x2 x1 走的。这解释了为什么 A 对称与否会直接影响梯度表达式。如果不先把这个来源搞清楚,后面的推导都像空中楼阁。

1.2 梯度的含义

梯度在物理上就是函数值增长最快的方向,在数学上就是函数对每个自变量求偏导后组成的向量。对于 f(x1, x2, ..., xn),梯度定义为:

∇f = (∂f/∂x1, ∂f/∂x2, ..., ∂f/∂xn)^T

注意梯度是个列向量。在机器学习的梯度下降里,x 通常代表参数向量,f(x) 是损失函数,梯度方向就是参数更新的反方向。所以求梯度是优化问题的第一步。

二次型的梯度为什么值得专门推导?因为它是一个最基础但又不那么显然的矩阵求导例子。它牵扯出三个关键点:求和号下的求导、矩阵对称性的处理、矩阵微分法的引入。这三个点理解了,后面所有矩阵求导公式都能自己推,不用死记硬背。

2. 分量展开推导:从最基本定义出发

2.1 用求和符号展开

我们从求和式 x^T A x = Σ_i Σ_j a_ij x_i x_j 出发。为了对第 k 个分量 x_k 求偏导,我们需要先观察这个双重求和里,哪些项包含 x_k。

一共有三种情况:

第一,当 i = k 且 j ≠ k 时,项是 a_kj x_k x_j; 第二,当 i ≠ k 且 j = k 时,项是 a_ik x_i x_k; 第三,当 i = k 且 j = k 时,项是 a_kk x_k^2。

其他所有不含 x_k 的项,对 x_k 求偏导都等于零,可以直接忽略。这一步是很多教程省略的关键,自己动手写一遍才知道为什么后面出现 a_ik + a_ki。

为了更直观,我们可以写一个小例子。n=3 时展开:

f = a11 x1^2 + a12 x1 x2 + a13 x1 x3 + a21 x2 x1 + a22 x2^2 + a23 x2 x3 + a31 x3 x1 + a32 x3 x2 + a33 x3^2

如果对 x1 求偏导,你只需要关注含 x1 的项:a11 x1^2、a12 x1 x2、a13 x1 x3、a21 x2 x1、a31 x3 x1。求导结果是 2a11 x1 + a12 x2 + a13 x3 + a21 x2 + a31 x3。看到这里,a12 和 a21 都出现了,这就是矩阵求导不对称来源的雏形。

2.2 对第k个分量求偏导

现在正式对 x_k 求偏导。根据上面的分类,我们有:

∂f/∂x_k = Σ_{j ≠ k} a_kj x_j + Σ_{i ≠ k} a_ik x_i + 2a_kk x_k

注意第一个求和来自 i=k 的项,第二个求和来自 j=k 的项。把 j 和 i 都写成哑指标,合并起来:

∂f/∂x_k = Σ_{j=1, j≠k}^n a_kj x_j + Σ_{i=1, i≠k}^n a_ik x_i + 2a_kk x_k

= Σ_{j=1}^n a_kj x_j + Σ_{i=1}^n a_ik x_i

因为当 j=k 时,加上的 a_kk x_k 恰好和 2a_kk x_k 凑成两项?我们来验证一下。原式是 a_kj 那项求和只加非 k 的,再加上 2a_kk x_k,等价于 Σ_j a_kj x_j + a_kk x_k。而第二项 Σ_i a_ik x_i(全求和)中,当 i=k 时是 a_kk x_k。所以总结果是:

∂f/∂x_k = Σ_j a_kj x_j + Σ_i a_ik x_i = (A x)_k + (A^T x)_k

这里 (A x)_k 表示向量 A x 的第 k 个分量,(A^T x)_k 表示向量 A^T x 的第 k 个分量。这个结果非常漂亮,它说:f 对第 k 个变量的偏导,等于向量 A x 的第 k 个分量加上向量 A^T x 的第 k 个分量。

2.3 写成向量形式

既然每个分量的偏导都是 (A x)_k + (A^T x)_k,那么把所有分量堆叠成列向量,就得到梯度:

∇f = A x + A^T x = (A + A^T)x

这个公式对任意实矩阵 A 都成立,不需要对称性假设。如果 A 恰好是对称矩阵,即 A^T = A,那么:

∇f = 2A x

这就是大家最熟悉的“二次型梯度等于 2Ax”的由来。注意,这里的 2 不是平白无故出现的,它是由“两个交叉项方向各自贡献一个 x_j/x_i”凑出来的。当你把非对称矩阵强制替换成对称矩阵时,交叉项被合并,梯度中的二倍关系就是对称化带来的结果。

我在初学的时候,看到 (A + A^T)x 总觉得它和 2Ax 是矛盾的。其实不矛盾,只是 A 的对称性不同。更准确地说,对于任何一个矩阵 A,我们总可以把它分解成对称部分和反对称部分:

A = (A + A^T)/2 + (A - A^T)/2

其中第一项是对称矩阵,第二项是反对称矩阵。而反对称部分对二次型的贡献是零,因为 x^T (A - A^T) x = 0。所以二次型 x^T A x 实际上只取决于 A 的对称部分。这个性质在下面还会用到。

3. 矩阵微分法:更简练的推导路径

3.1 矩阵微分的定义

分量推导虽然直观,但每次都要展开求和号,步骤多、容易写错。实际工作中我更推荐用矩阵微分法。这个方法的核心思路是:对函数 f(x) 求全微分,然后凑成 df = (某向量)^T dx 的形式,那么括号里的那个向量就是梯度。

为什么可以这样?因为对任意可微函数 f(x),它的全微分可以写成:

df = Σ_i (∂f/∂x_i) dx_i = (∇f)^T dx

所以反过来,如果我们能算出 df,并且整理成 “df = g^T dx” 的形式,那么 g 就是梯度 ∇f。这个方法不需要展开求和,只需要熟悉矩阵微分的基本运算法则。

矩阵微分的运算法则和普通一元微分类似,但要注意乘法顺序。常用的有:

  • d(X^T) = (dX)^T
  • d(XY) = (dX)Y + X(dY)
  • d(a^T X b) = a^T dX b,其中 a、b 是与 X 无关的向量

这些规则我一开始也不太敢用,因为矩阵乘法不交换,很怕顺序写错。其实只要记住“d 像莱布尼茨法则一样作用,并且保持原来的矩阵乘法顺序”就行了。

3.2 对二次型求微分并提取梯度

现在对 f = x^T A x 求微分。注意这里 x 是变量,A 是常数矩阵。根据莱布尼茨法则:

df = d(x^T) A x + x^T A d(x)

因为 d(x^T) = (dx)^T,所以第一项可以写成 (dx)^T A x。第二项是 x^T A dx。于是:

df = (dx)^T A x + x^T A dx

现在的问题是,我们想要把 df 整理成 g^T dx 的样子。第一项已经有点像了: (dx)^T A x 是一个标量,而标量的转置等于它本身,所以:

(dx)^T A x = ( (dx)^T A x )^T = x^T A^T dx

这一步非常关键,很多人卡在这里。因为 (dx)^T A x 是 1×1 的矩阵,转置以后是 x^T A^T dx,而 dx 被放到了右边。于是:

df = x^T A^T dx + x^T A dx = x^T (A^T + A) dx

也就是:

df = ( (A^T + A) x )^T dx

对照 df = (∇f)^T dx,直接得到:

∇f = (A^T + A) x = (A + A^T) x

和分量推导的结果完全一致,但整个推导只需要三行。这就是矩阵微分法的威力。一旦你习惯它,再去推更复杂的矩阵函数,比如 f = ||Ax - b||^2,也会顺畅很多。

3.3 完整过程与结果

把上面三步完整写下来就是:

设 f(x) = x^T A x,A 为 n×n 实矩阵,x 为 n 维实向量。

  1. 求微分: df = d(x^T) A x + x^T A d(x) = (dx)^T A x + x^T A dx

  2. 把第一项转置: (dx)^T A x = x^T A^T dx

  3. 合并: df = x^T (A^T + A) dx

  4. 因此: ∇f = (A^T + A) x

如果 A 对称,即 A^T = A,那么:

∇f = 2A x

这就是最终结果。注意第二步中“标量转置等于自身”这个技巧,是矩阵求导里最常用的手法。以后遇到 (dx)^T 开头的项,第一步就想想能不能转置成 dx 结尾,这样才能统一提取 dx。

4. 对称矩阵与非对称矩阵:最容易踩的坑

4.1 为什么对称性如此关键

很多教材在讲二次型时,默认 A 是对称矩阵,甚至有些教材定义二次型时直接要求 A 对称。这样做的好处是,二次型只由对称部分决定,所以假设对称不会失去一般性。但问题在于,实际应用中你遇到的矩阵不一定对称,比如某些迭代算法中的矩阵可能不是对称的。如果你不管三七二十一,直接把公式套成 2Ax,就会得到错误结果。

我举个例子。设:

A = [[1, 2], [3, 4]],x = (x1, x2)^T

那么 f = x^T A x = x1^2 + 2x1 x2 + 3x2 x1 + 4x2^2 = x1^2 + 5x1 x2 + 4x2^2

对 x1 求偏导:2x1 + 5x2。对 x2 求偏导:5x1 + 8x2。所以梯度是 (2x1 + 5x2, 5x1 + 8x2)^T。

如果用 (A + A^T)x 算:

A + A^T = [[2, 5], [5, 8]]

(A + A^T)x = [[2, 5], [5, 8]] (x1, x2)^T = (2x1 + 5x2, 5x1 + 8x2)^T

一致。但如果用 2Ax 算:

2A x = 2 [[1, 2], [3, 4]] (x1, x2)^T = (2x1 + 4x2, 6x1 + 8x2)^T

明显不对。所以对称性不是可有可无的假设,而是公式适用条件的一部分。

4.2 非对称情况下的梯度公式

非对称时,梯度公式是 ∇f = (A + A^T)x。这个公式可以再拆成两部分:

(A + A^T)x = A x + A^T x

直观理解:A x 来自 x^T A (dx) 项,A^T x 来自 (dx)^T A x 转置后的贡献。当 A 不对称时,Ax 和 A^T x 通常不相等,所以两者都必须保留。

还有一个常见的等价处理:把 A 替换成它的对称部分。因为:

x^T A x = x^T [(A + A^T)/2] x

设 B = (A + A^T)/2,那么 B 是对称矩阵,且 f = x^T B x。这时候梯度可以写为:

∇f = 2Bx = (A + A^T)x

这个视角很重要。它说明在讨论二次型时,我们其实只关心矩阵的对称部分,反对称部分对函数值的贡献是零。这也解释了为什么优化问题中的二次型通常是“对称正定矩阵”——因为只有对称部分起作用,那就干脆用对称矩阵来表示,顺便还能保证正定性、特征值实数性等好性质。

这个性质在判断函数凹凸性时特别有用。f(x) = x^T A x 的 Hessian 矩阵就是 A + A^T(如果梯度是 (A + A^T)x,再求导就是 A + A^T)。当且仅当 A + A^T 半正定时,f 是凸函数。如果你错误地假设 Hessian 是 2A,那对于非对称 A 可能会得到错误的凹凸性判断。

4.3 例子:2维二次型验证

我们再用一个对称矩阵的例子验证 2Ax 的正确性,顺便展示用梯度公式求最小值点的过程。设:

A = [[2, 1], [1, 3]],这是一个对称正定矩阵。二次型 f = 2x1^2 + 2x1 x2 + 3x2^2。

梯度 ∇f = 2Ax = 2 [[2, 1], [1, 3]] (x1, x2)^T = (4x1 + 2x2, 2x1 + 6x2)^T。

验证分量求导:

∂f/∂x1 = 4x1 + 2x2,正确。 ∂f/∂x2 = 2x1 + 6x2,正确。

令梯度为零,解方程组:4x1 + 2x2 = 0,2x1 + 6x2 = 0。解得 x1 = x2 = 0。因为 A 正定,原点就是唯一的全局最小值点。这是二次型优化的标准场景。

如果你在编程时想验证自己的推导,可以随便取一个非对称矩阵,比如 A = [[0, 1], [-1, 0]]。这个矩阵是反对称的,所以 x^T A x = 0 恒成立,梯度为 (A + A^T)x = 0。这也是为什么反对称矩阵的二次型总是零的原因。用数值方法检验时,这种例子可以帮你确认程序有没有写错。

5. 常见问题与排查技巧实录

5.1 为什么结果有两种写法?2Ax 还是 (A+A^T)x?

这是初学者问得最多的问题。答案就一句话:取决于 A 是否对称。如果题目明确说 A 是对称矩阵(很多数学书默认如此),用 2Ax;如果没说,用 (A + A^T)x 最保险。如果你拿到一个实际问题,不知道 A 是否对称,先检查 A 的转置是否等于 A。如果你可以自由定义矩阵,比如设计一个二次罚函数,那么直接定义对称矩阵会更省事。

为了快速判断,我给你一个自查表:

条件梯度表达式使用场景
A 对称2Ax标准二次型、QP 问题、RBF 核相关推导
A 非对称(A + A^T)x一般矩阵、数值计算、推导时未作假设
只关心函数值可先将 A 换成 (A+A^T)/2分析凹凸性、简化推导

5.2 用数值差分验证梯度时怎么选步长?

我经常用小步长有限差分来验证自己的梯度实现是否正确。核心公式是:

∂f/∂x_k ≈ (f(x + h e_k) - f(x - h e_k)) / (2h)

其中 e_k 是第 k 个分量为 1 的单位向量。步长 h 的选择很微妙:太大则截断误差大,太小则数值舍入误差大。我的经验是,在双精度浮点下,h 取 1e-6 左右比较合适。比如验证二维二次型时,取 x = (1, 2),A 用非对称矩阵,分别用解析公式和差分算一遍,误差在 1e-8 以内就说明公式用对了。

更稳妥的做法是同时检查多个 x 点,避免某些点偶然抵消误差。我自己写优化代码时,会把“梯度验证”写成一个独立函数,每次改完损失函数都跑一遍,省得后面调参时被一个方向错的梯度坑到怀疑人生。

5.3 Hessian 矩阵和梯度之间是什么关系?

二次型 f = x^T A x 的梯度是 g(x) = (A + A^T)x,这是一个线性函数。对 x 再求一次梯度,得到 Hessian 矩阵:

H = ∇^2 f = A + A^T

如果 A 对称,H = 2A。在很多结论里,比如牛顿法的更新公式,都会用到 Hessian。如果你用公式 2Ax 当作梯度,对应 Hessian 就是 2A,这两者是自洽的。但是如果我看到有人拿非对称 A 算梯度时用 2Ax,那他的 Hessian 也会跟着错。所以记住:梯度公式和 Hessian 公式必须配套,用的都是同一个对称性假设。

5.4 在机器学习损失函数里,为什么常常出现 (X^T X) 这种对称矩阵?

最小二乘损失通常是 ||y - Xw||^2,展开后有一项 w^T (X^T X) w。这里 X^T X 天然是对称矩阵,所以梯度是 2X^T X w,而完整损失对 w 的梯度是 -2X^T(y - Xw)。很多推导直接写 2X^T X w,没有解释为什么没有 (X^T X)^T 那一项,原因就是 X^T X 对称。这一点在推导正规方程时尤其容易让人困惑。

另外,神经网络里的二次正则项 λ/2 ||w||^2 其实就是 λ/2 w^T I w,这里的 I 是对称的,梯度是 λw。平时看多了 1/2 系数,其实是故意设的,用来抵消求导产生的 2。这种做法在优化里很常见,目的就是让梯度表达式简洁。

5.5 我该记哪个公式?

我个人的建议是,只记最通用的公式:∇(x^T A x) = (A + A^T)x。遇到对称矩阵时自动退化为 2Ax。这样你只需要记一个,到用的时候先判断对称性,再决定要不要加前面的系数 2。我见过有些人把两个公式分开记,结果遇到半对称问题就蒙了。其实通用公式包含了特殊情况,还是从根本原理上理解更稳妥。

如果你想在推导时避免出错,还有一个技巧:在纸上用 n=2 的分量展开验证一下。不要嫌麻烦,二次型是矩阵求导里最基础的砖块,慢就是快。

6. 最后再分享一点实际操作的体会

我在实际推导和编码中踩过几次坑之后,最大的教训是:不要懒于验证对称性。拿到一个矩阵,先检查它是方阵、看它转置后是否相等,这个动作几乎零成本,但能避免大量低级错误。特别是当你从论文里抄公式时,原作者可能已经默认了矩阵对称,而你没注意到,傻乎乎地把别人的 2Ax 用在非对称矩阵上,结果数值怎么都对不上。

另一个体会是,矩阵微分法真的值得花半天时间熟练掌握。它不只是用来推二次型,像 tr(A^T B)、log det(X)、||AX - B||_F^2 这些常见的矩阵函数,用微分法推起来思路高度统一。我第一次用微分法推出复杂表达式的梯度时,感觉自己以前在求和符号里挣扎的时代一下子结束了。如果你学二次型梯度是为了后续学优化或深度学习,建议尽早把微分法作为主要工具,分量展开当作验证工具,两者配合使用效率最高。

最后,如果你在写代码时想快速确认梯度是否正确,可以试试 PyTorch 或 TensorFlow 的自动求导接口。随便定义一个对称或非对称矩阵 A,初始化一个 x 张量,计算 x^T A x 后反向传播,把得到的梯度和你手推的公式做对比。这个验证方式比手算快得多,也能增强你对公式的信任感。等对比通过了,再去手工推导或者分析性质,心里就踏实很多。

希望这篇推导过程能帮你把二次型梯度这件事彻底搞明白。以后看到 x^T A x,你脑子里应该能直接浮现出 (A + A^T)x,然后条件反射地问一句:A 对称吗?如果是,那就是 2Ax。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询