二次型梯度推导:从逐分量展开到对称与非对称矩阵的坑 二次型$x^TAx$的梯度推导看起来是数学课本里一个很小的知识点但我在做机器学习优化的时候还真被这个公式坑过一次。当时在写L2正则化项的梯度教材上直接写了梯度等于$2Ax$我照抄进代码里结果用有限差分法做梯度检查怎么都对不上。后来才发现问题出在那个矩阵$A$——教材默认它是对称的而我的场景里它不是。这个坑让我回头把二次型求导的整个推导过程仔细捋了一遍今天就把这条完整的推导链分享出来包括逐分量展开、矩阵化整理、对称与非对称的区别以及几个高频应用场景。无论你是正在学线性代数的学生还是做优化算法、控制理论、机器学习相关工作的工程师这条推导链路都会让你少踩一些类似的坑。1. 二次型到底是什么从展开式建立直觉1.1 二维和三维的例子先从最具体的二维情况说起。设$x \begin{bmatrix} x_1 \ x_2 \end{bmatrix}$矩阵$A \begin{bmatrix} a_{11} a_{12} \ a_{21} a_{22} \end{bmatrix}$那么$$x^TAx \begin{bmatrix} x_1 x_2 \end{bmatrix}\begin{bmatrix} a_{11} a_{12} \ a_{21} a_{22} \end{bmatrix}\begin{bmatrix} x_1 \ x_2 \end{bmatrix}$$先算中间部分$Ax \begin{bmatrix} a_{11}x_1 a_{12}x_2 \ a_{21}x_1 a_{22}x_2 \end{bmatrix}$再和$x^T$做内积$$x^TAx x_1(a_{11}x_1 a_{12}x_2) x_2(a_{21}x_1 a_{22}x_2) a_{11}x_1^2 a_{12}x_1x_2 a_{21}x_2x_1 a_{22}x_2^2$$注意这里的交叉项$a_{12}x_1x_2$和$a_{21}x_2x_1$它们都含有$x_1x_2$是可以合并的。合并之后$$x^TAx a_{11}x_1^2 (a_{12} a_{21})x_1x_2 a_{22}x_2^2$$三维的情况写出来就是$$x^TAx a_{11}x_1^2 a_{22}x_2^2 a_{33}x_3^2 (a_{12} a_{21})x_1x_2 (a_{13} a_{31})x_1x_3 (a_{23} a_{32})x_2x_3$$到这里你应该能看出一个很重要的规律二次型本质上就是一个关于$x_1, x_2, \dots, x_n$的二次齐次多项式。所谓齐次就是每一项的次数都正好是2——要么是$x_i^2$这种平方项要么是$x_ix_j$这种交叉项。1.2 求和形式的通用写法把上面的规律推广到$n$维就得到二次型最标准的求和形式$$x^TAx \sum_{i1}^{n}\sum_{j1}^{n} a_{ij}x_ix_j$$这个双重求和是整个推导的基础。你要把二次型当作一个标量函数来看待——输入是向量$x$输出是一个实数。这个函数接受$n$个自变量$x_1, x_2, \dots, x_n$我们要求梯度就是要分别对每一个自变量求偏导然后把这些偏导组合成一个向量。在动手求导之前有一点要明确当你把二次型写成求和形式时$i$和$j$是独立的循环变量所以求和里面既包含$a_{ii}x_i^2$当$ij$时也包含$a_{ij}x_ix_j$和$a_{ji}x_jx_i$当$i \neq j$时。这意味着$x_ix_j$这个组合会在求和里出现两次一次是以$a_{ij}$为系数一次是以$a_{ji}$为系数。这一点在后面逐分量求导的时候特别重要很多人就是在这里搞混的导致求出来的偏导少了一项。2. 核心推导对每个分量求偏导2.1 处理平方项与交叉项现在我对第$k$个分量$x_k$求偏导。根据上面的双重求和只有当$ik$或者$jk$的时候求和项里才含有$x_k$偏导才不为零。所以我需要把所有含$x_k$的项单独拆出来。先固定$j$看那些$ik$的项$\sum_{j1}^{n} a_{kj}x_kx_j$这一整行都和$x_k$有关。再固定$i$看那些$jk$的项$\sum_{i1}^{n} a_{ik}x_ix_k$这一整列也都和$x_k$有关。但是要注意这两组求和在$ik, jk$这个交叉点上重叠了——就是$a_{kk}x_k^2$这一项。它既属于“$ik$的项”也属于“$jk$的项”所以如果直接把两个求和加起来这一项会被重复计算。所以正确的做法是$$\frac{\partial f}{\partial x_k} \sum_{j1}^{n} a_{kj}x_j \sum_{i1}^{n} a_{ik}x_i - a_{kk}x_k$$这里减去一个$a_{kk}x_k$就是因为它被上面两个求和各算了一次。理解了这个结构后面所有推导都顺畅了。我把这个看作“先算两笔账再把重复的部分剔除”跟统计交叉项时要去重是一个道理。2.2 从偏导表达式整理出通用公式上面这个式子还可以进一步化简。注意第二个求和$\sum_{i1}^{n} a_{ik}x_i$的下标是$i$本质上就是对矩阵$A$的第$k$列做加权求和。而$\sum_{j1}^{n} a_{kj}x_j$则是对$A$的第$k$行做加权求和。如果我把第二个求和里的哑指标$i$统一改写成$j$那么$$\frac{\partial f}{\partial x_k} \sum_{j1}^{n} a_{kj}x_j \sum_{j1}^{n} a_{jk}x_j - a_{kk}x_k$$再进一步如果定义$b_{kk} a_{kk}$这个式子可以重新组合成两个完整的加权和$$\frac{\partial f}{\partial x_k} \sum_{j1}^{n} a_{kj}x_j \sum_{j1}^{n} a_{jk}x_j - a_{kk}x_k \sum_{j1}^{n}(a_{kj} a_{jk})x_j - a_{kk}x_k$$嗯等一下这个表达还是有点绕。换一种更清爽的整理方式。实际上当$jk$时$a_{kj}x_j$是$a_{kk}x_k$$a_{jk}x_j$也是$a_{kk}x_k$两者相加是$2a_{kk}x_k$。所以不需要那个“减一”直接用行和列两个视角相加就可以得到$$\frac{\partial f}{\partial x_k} \sum_{j1}^{n} a_{kj}x_j \sum_{j1}^{n} a_{jk}x_j$$因为当$jk$时这一项本来就是要被算两次的——因为它对应的原始项是$a_{kk}x_k^2$对$x_k$求导自然得到$2a_{kk}x_k$。所以正确且简洁的表达式是$$\frac{\partial f}{\partial x_k} \sum_{j1}^{n} a_{kj}x_j \sum_{j1}^{n} a_{jk}x_j$$从实操的角度我更推荐直接记住这个拆法行视角加列视角不需要去重因为平方项的导数本来就是两倍。这里的差别自己在纸上推一遍就清楚了关键是别把$a_{kk}x_k^2$当成普通交叉项去“去重”。3. 从偏导到矩阵形式对称与不对称的决定性差异3.1 行视角与列视角的矩阵化有了$\frac{\partial f}{\partial x_k} \sum_{j1}^{n} a_{kj}x_j \sum_{j1}^{n} a_{jk}x_j$接下来把$k1,2,\dots,n$时的所有偏导组装成一个列向量也就是梯度$\nabla f$。第一个求和$\sum_{j1}^{n} a_{kj}x_j$正是矩阵$A$的第$k$行与$x$的内积所以当$k$遍历$1$到$n$时这一部分拼起来就是$Ax$。第二个求和$\sum_{j1}^{n} a_{jk}x_j$是矩阵$A$的第$k$列与$x$的内积。把第$k$列当作行来用这其实就是$A^T$的第$k$行与$x$的内积也就是$A^Tx$的第$k$个分量。所以第二部分拼起来就是$A^Tx$。于是$$\nabla f Ax A^Tx (A A^T)x$$这个结果不需要任何额外假设对任意实矩阵$A$都成立。它既包含了$A$的行视角也包含了$A$的列视角。如果$A$恰好是对称矩阵即$A^T A$那么就有$\nabla f 2Ax$这就是大多数教材和优化讲义里直接给出的公式。这里要特别强调$2Ax$这个简洁形式有一个隐含前提——矩阵对称。很多初学者包括当年的我没注意到这个前提直接把$2Ax$用在非对称矩阵上结果梯度算出来就是错的。后面我会专门讲这个坑的验证方法。3.2 对称分解视角为什么梯度只和对称部分有关其实还有一个更本质的视角。任何方阵$A$都可以唯一地分解为对称部分和反对称部分$$A \frac{A A^T}{2} \frac{A - A^T}{2}$$记$S \frac{A A^T}{2}$为对称部分$K \frac{A - A^T}{2}$为反对称部分即$K^T -K$。来看两个关键结论。第一反对称部分对二次型的函数值毫无贡献。因为$$x^TKx (x^TKx)^T x^TK^Tx -x^TKx$$一个标量等于自己的相反数那它只能是$0$。这说明$x^TAx x^TSx$用$A$还是用它的对称部分$S$来计算二次型取值结果完全一样。第二梯度公式$(A A^T)x 2Sx$它恰好等于对称部分的两倍乘$x$而反对称部分$K$对梯度没有贡献。所以更本质的结论是二次型对矩阵$A$的依赖完全通过$A$的对称部分来体现。函数值和梯度都只认$S$。即使你把$A$写成$S K$那个$K$既不影响取值也不影响梯度。这个结论在实际中非常有用。比如你在算法里碰到了一个非对称矩阵计算$x^TAx$的值没问题但如果你想优化这个函数你要用的梯度是$2Sx$而不必关心$K$。反过来说如果你只关心二次型的梯度直接预处理一下把矩阵替换成$(A A^T)/2$梯度公式就统一成了$2Sx$简洁且无歧义。4. 非对称矩阵这个坑教材默认与数值验证4.1 为什么教材里写$2Ax$你不会觉得有问题教材通常会在介绍二次型的梯度时直接写“若$A$为对称矩阵则$\nabla(x^TAx) 2Ax$”。但在实际阅读中很多教材在讲二次型这一章时默认$A$已经对称化了或者干脆在章节开头就声明“本文讨论的二次型矩阵均为对称矩阵”。如果你跳过了这个声明直接拿着公式去做非对称矩阵的梯度就会出问题。还有一个容易混淆的地方在很多优化和机器学习场景里二次型的矩阵本来就是对称的。比如$L2$正则化项$\lambda|w|^2 \lambda w^TIw$这里的$I$是对称的高斯分布的负对数似然里的$(x - \mu)^T\Sigma^{-1}(x - \mu)$协方差矩阵的逆也是对称的线性最小二乘的误差项$(y - Xw)^T(y - Xw)$展开后得到的二次项矩阵$X^TX$还是对称的。因为对称矩阵到处都是所以$2Ax$这个公式在绝大多数场景里都对大家也就很少去追究“如果不对称会怎样”。但一旦你自己实现一个通用矩阵的优化算法或者写数值计算库的底层函数就一定会碰上非对称的情况。4.2 用有限差分验证梯度公式的正确性验证梯度对不对最直接的办法是有限差分梯度检查gradient checking。原理很简单梯度的第$k$个分量等于函数在该方向上变化的极限所以可以用一个小扰动$\epsilon$来近似$$\frac{\partial f}{\partial x_k} \approx \frac{f(x \epsilon e_k) - f(x - \epsilon e_k)}{2\epsilon}$$这里$e_k$是第$k$个标准基向量。这个中心差分公式比单侧差分更精确误差是$O(\epsilon^2)$级别的。我用Python写过一个简单的验证脚本分享出来完整可运行import numpy as np np.random.seed(42) n 5 A np.random.randn(n, n) # 注意没有做对称化是普通非对称矩阵 x np.random.randn(n) eps 1e-6 # 用公式计算梯度 def grad_formula(A, x): return (A A.T) x # 通用公式 # 用有限差分计算梯度 def grad_numeric(A, x, eps1e-6): n x.shape[0] g np.zeros(n) for k in range(n): e_k np.zeros(n) e_k[k] 1.0 f_plus x A (x eps * e_k) f_minus x A (x - eps * e_k) g[k] (f_plus - f_minus) / (2 * eps) return g g1 grad_formula(A, x) g2 grad_numeric(A, x) print(公式梯度:, g1) print(数值梯度:, g2) print(最大误差:, np.max(np.abs(g1 - g2)))在我的测试里最大误差在$10^{-9}$量级这证明$(A A^T)x$是对的。而如果你在这个非对称$A$上使用$2Ax$误差会在$10^{-1}$量级一眼就能看出公式用错了。我建议所有做优化相关开发的朋友都把这段脚本留在自己的工具库里。在你写任何复杂梯度之前先跑一下数值梯度比对五秒钟能帮你省下数小时的排错时间。还有一个技巧如果不想写数值梯度脚本也可以用自动微分框架来做梯度检查。PyTorch的torch.autograd.gradcheck就是干这个的。但我不建议把自动微分作为唯一验证手段因为自动微分本身的实现也可能有bug。手动有限差分虽然慢但它只依赖函数取值是最底层的“裁判”。5. 梯度四连二次型求导在高频场景中的实战5.1 线性最小二乘与正规方程线性最小二乘的目标函数是$$J(w) |Xw - y|^2 (Xw - y)^T(Xw - y)$$展开$$J(w) w^TX^TXw - 2y^TXw y^Ty$$第一项$w^TX^TXw$就是二次型其中$A X^TX$。注意$X^TX$天然是对称矩阵所以直接用$\nabla (w^TX^TXw) 2X^TXw$。第二项$-2y^TXw$对$w$求导因为$y^TXw$是一个标量且$y^TX$是行向量所以$\nabla(-2y^TXw) -2X^Ty$。合起来$$\nabla J(w) 2X^TXw - 2X^Ty 2X^T(Xw - y)$$令梯度为零得到$$X^TXw X^Ty$$这就是最小二乘的正规方程。整个推导中二次型梯度公式是第一步也是最基础的一步。很多同学学到这里只是背下了正规方程却不清楚它是从二次型梯度来的。其实有了上面的推导链整个过程是水到渠成的事。5.2 L2正则化的梯度带L2正则化的损失函数通常是$$\tilde{J}(w) J(w) \lambda|w|^2$$其中$|w|^2 w^Tw w^TIw$$I$是单位矩阵当然是对称的。根据梯度公式$$\nabla(\lambda|w|^2) \lambda \cdot 2Iw 2\lambda w$$于是整个损失函数的梯度就是$$\nabla \tilde{J}(w) 2X^T(Xw - y) 2\lambda w$$在梯度下降更新时这一项会自然地产生权重衰减weight decay的效果。你看L2正则化为什么常被称为“权重衰减”从梯度公式里就能直接看出来每一步更新都在往$w$里减去一个$2\lambda w$的项相当于对权重做了一个缩放。如果你自己实现过带L2正则的线性回归或者逻辑回归大概率对这个形式不陌生。但知道它是从二次型梯度推过来的再去调整正则化系数时心里会更有底。5.3 多元高斯分布中的二次型多元高斯分布的概率密度函数包含这样一个项$$-\frac{1}{2}(x - \mu)^T\Sigma^{-1}(x - \mu)$$这里$\Sigma$是协方差矩阵$\Sigma^{-1}$也是对称矩阵。如果要对$x$求这个对数似然的梯度设$u x - \mu$则$$\nabla_u \left( -\frac{1}{2}u^T\Sigma^{-1}u \right) -\frac{1}{2} \cdot 2\Sigma^{-1}u -\Sigma^{-1}(x - \mu)$$这个结果在最大似然估计、高斯混合模型、卡尔曼滤波等场景里反复出现。特别是在计算高斯分布的充分统计量或者做变分推断时这个梯度是很多推导起点的关键一步。另外如果你要最大化$\log \mathcal{N}(x;\mu, \Sigma)$在求梯度时注意二次型项的负号处理——因为外面有一个$-1/2$所以最终梯度方向是朝$\mu$靠拢的。这些细节都很小但确实影响整体理解。5.4 拉格朗日乘子法中的二次型约束还有一个我最近在写约束优化问题时用到的场景。考虑二次规划问题$$\min_x \frac{1}{2}x^TQx c^Tx \quad \text{s.t.} \quad Ax b$$拉格朗日函数对$x$求梯度时第一项同样是二次型$$\nabla_x \left( \frac{1}{2}x^TQx \right) \frac{1}{2} \cdot 2Qx Qx$$这里如果$Q$不对称那就要先对$Q$做对称化处理求稳的做法是直接写成$\frac{1}{2}(Q Q^T)x$。在工程实现里许多二次规划求解器如OSQP会预先检查并对称化$Q$原因就在这里。如果你自己造轮子第一步就应该做同样的预处理否则后面所有KKT条件的推导和求解都会建立在一个错误的梯度上。二次型之外的延伸几个值得记住的推论把上面的推导再往前推一步还有一些会经常用到的小结论一并放在这里省得你以后再去翻书。第一对于标准二次型如果$A$对称则$$\nabla^2 \left( \frac{1}{2}x^TAx \right) A$$也就是Hessian矩阵正好等于$A$。这解释了为什么在优化算法里二次函数通常被拿来当“模型函数”因为它的一阶、二阶信息都特别干净。牛顿法在二次函数上一步收敛本质原因就在这里。第二对平移后的二次型设$f(x) (x - b)^TA(x - b)$则$$\nabla f(x) (A A^T)(x - b)$$如果$A$对称则$\nabla f(x) 2A(x - b)$。这个结论在高斯分布、马氏距离、罚函数法里用得很频繁。第三如果$A$是正定矩阵二次型$x^TAx$是凸函数。正定意味着对所有非零$x$$x^TAx 0$加上Hessian即$2A$正定所以全局最优解唯一。许多机器学习算法的收敛性证明都是建立在这个凸性基础上的。第四如果遇到的是复数域上的二次型即$x^HAx$这种形式$H$表示共轭转置梯度公式会变成$\nabla f 2\operatorname{Re}(Ax)$处理方式略有不同。工程中涉及到FFT、波束形成、无线通信优化时会遇到我暂时不在这里展开但提醒你注意区分别在复数域直接套实数域的公式。最后的实操心法我自己用二次型梯度公式这么多次有一个习惯是拿到任何矩阵先看一眼它是不是对称的。张量/矩阵的对称性检查在NumPy里就一行np.allclose(A, A.T)。如果是对称的直接写$2Ax$如果不是对称的使用$(A A^T)x$。这个习惯帮我避开了很多写代码时的隐性错误。如果你正在手推某个机器学习算法的梯度我的建议是不要只满足于背下最终公式。自己动手把二次型展开成求和形式对每个分量求偏导再拼成矩阵形式整个过程推一遍你的理解就会完全不一样。这个推导链不光是解决一个知识点它对矩阵求导的直觉培养帮助很大——以后再遇到$x^TAy$、$x^TAx b^Tx$这类复合形式都能很快地上手拆解。最后再分享一个小技巧当你在化简梯度结果时先画出行视角和列视角的对应关系再决定用哪种矩阵表达。行视角对应$Ax$列视角对应$A^Tx$两个视角结合就是$(A A^T)x$。把这个映射关系记在脑子里矩阵求导里的很多困惑都能迎刃而解。