57-机器学习与大模型开发数学教程-5-4 共轭梯度法

一句话版:当你要解一个对称正定(SPD)的线性方程 A x = b Ax=b Ax=b(或等价最小化二次函数)而矩阵又很大很稀疏 时,共轭梯度法 能做到"只用矩阵--向量乘 、占用内存小、收敛快**",并且第 k k k 次迭代给出在 Krylov 子空间里的"最优"解。


1. 任务与直觉:顺着"最圆的路"下山

  • 问题 :解 A x = b Ax=b Ax=b,其中 A ∈ R n × n A\in\mathbb{R}^{n\times n} A∈Rn×n 对称且正定(Symmetric Positive Definite, SPD)。

  • 等价优化

    min ⁡ x    ϕ ( x ) = 1 2 x ⊤ A x − b ⊤ x . \min_{x} \; \phi(x)=\tfrac12 x^\top A x - b^\top x. xminϕ(x)=21x⊤Ax−b⊤x.

    这是一个"碗口向上"的二次凸函数。

类比 :普通梯度下降像在"狭长的峡谷"里之字形走;共轭梯度 会为你挑选一组"互不干扰 "的下山方向(在 A A A-度量下彼此正交),这样每条方向只走一次就不回头,因此比最速下降快得多。


2. 核心思想:A-共轭方向与 Krylov 子空间

  • A-共轭(A-正交) :两方向 p i , p j p_i,p_j pi,pj 若 p i ⊤ A p j = 0 p_i^\top A p_j=0 pi⊤Apj=0( i ≠ j i\neq j i=j),称它们 A-共轭

    与欧氏正交不同,这里用的是 A A A 诱导的内积 ⟨ u , v ⟩ A = u ⊤ A v \langle u,v\rangle_A=u^\top A v ⟨u,v⟩A=u⊤Av。

  • Krylov 子空间 :以初始残差 r 0 = b − A x 0 r_0=b-Ax_0 r0=b−Ax0 为种子,

    K k ( A , r 0 ) = span { r 0 , A r 0 , A 2 r 0 , ... , A k − 1 r 0 } . \mathcal{K}_k(A,r_0)=\text{span}\{r_0,Ar_0,A^2r_0,\ldots,A^{k-1}r_0\}. Kk(A,r0)=span{r0,Ar0,A2r0,...,Ak−1r0}.

    CG 的第 k k k 次迭代给出的 x k x_k xk 是在 K k \mathcal{K}_k Kk 中使 ϕ ( x ) \phi(x) ϕ(x) 最小的点。

  • 一次一维最优 :每一步都在当前搜索方向 p k p_k pk 上做精确线搜索 ,因此更新幅度 α k \alpha_k αk 有闭式。


3. 公式与算法:三行更新,快到飞起

设 r k = b − A x k r_k=b-Ax_k rk=b−Axk 为残差, p k p_k pk 为搜索方向,初始 x 0 x_0 x0 任取, r 0 = b − A x 0 r_0=b-Ax_0 r0=b−Ax0, p 0 = r 0 p_0=r_0 p0=r0。则

α k = r k ⊤ r k p k ⊤ A p k , x k + 1 = x k + α k p k , r k + 1 = r k − α k A p k , \alpha_k=\frac{r_k^\top r_k}{p_k^\top A p_k},\quad x_{k+1}=x_k+\alpha_k p_k,\quad r_{k+1}=r_k-\alpha_k A p_k, αk=pk⊤Apkrk⊤rk,xk+1=xk+αkpk,rk+1=rk−αkApk,

β k + 1 = r k + 1 ⊤ r k + 1 r k ⊤ r k , p k + 1 = r k + 1 + β k + 1 p k . \beta_{k+1}=\frac{r_{k+1}^\top r_{k+1}}{r_k^\top r_k},\quad p_{k+1}=r_{k+1}+\beta_{k+1} p_k. βk+1=rk⊤rkrk+1⊤rk+1,pk+1=rk+1+βk+1pk.

  • 每步只需 :一次 A p k A p_k Apk 的矩阵--向量乘,外加几个向量内积与 SAXPY(线性组合)。
  • 存储量 : O ( n ) O(n) O(n) 级别,只需 3--4 个向量。



初始化 x0
计算 r0=b-Ax0
设置 p0=r0
收敛?
计算 Ap=A p
计算 alpha, 更新 x 与 r
计算 beta, 更新 p
输出解 x

说明:每次循环只做一次稀疏矩阵--向量乘(SpMV),因此适合大规模稀疏问题与"矩阵--自由(只提供 A·v 算子)"场景。


4. 为什么快:误差界与"κ 的平方根"

令误差 KaTeX parse error: Undefined control sequence: \* at position 11: e_k=x_k-x^\̲*̲,在 A A A-范数下有经典界

∥ e k ∥ A ≤ 2 ( κ − 1 κ + 1 ) k ∥ e 0 ∥ A , κ = λ max ⁡ ( A ) λ min ⁡ ( A ) . \|e_k\|A \le 2\Big(\frac{\sqrt{\kappa}-1}{\sqrt{\kappa}+1}\Big)^k \|e_0\|A,\quad \kappa=\frac{\lambda{\max}(A)}{\lambda{\min}(A)}. ∥ek∥A≤2(κ +1κ −1)k∥e0∥A,κ=λmin(A)λmax(A).

  • 对比最速下降 :最速下降的收敛比率是 κ − 1 κ + 1 \frac{\kappa-1}{\kappa+1} κ+1κ−1(更慢),而 CG 是它的"平方根改良"。
  • 理论上 n n n 步精确到达 :无限精度下, n n n 维 SPD 系统,CG 最多 n n n 步得到精确解。
  • 实践中 :有限精度 + 条件数大 → 需要更多步,预条件能显著提速(见 §6)。

5. 与最速下降的关系(顺便复习 5-3)

  • 最速下降:每次沿负梯度方向做一维最优,但下一步可能"走回老路"。
  • 共轭梯度 :构造一组 A-共轭 的方向,保证每条方向只用一次,因此"不会拉扯前功尽弃"。

6. 预条件共轭梯度(PCG):把峡谷"拉圆"

当 A A A 条件数很大,收敛变慢。找一个 SPD 的预条件器 M ≈ A M\approx A M≈A(或者近似 A − 1 A^{-1} A−1),改造系统为

M − 1 A x = M − 1 b . M^{-1}Ax=M^{-1}b. M−1Ax=M−1b.

实践算法写成:把残差 r k r_k rk 经过"预条件求解" M z k = r k M z_k=r_k Mzk=rk,再用 z k z_k zk 替换各处的 r k r_k rk。

  • PCG 更新(只写关键差异):

    α k = r k ⊤ z k p k ⊤ A p k , β k + 1 = r k + 1 ⊤ z k + 1 r k ⊤ z k , p k + 1 = z k + 1 + β k + 1 p k . \alpha_k=\frac{r_k^\top z_k}{p_k^\top A p_k},\quad \beta_{k+1}=\frac{r_{k+1}^\top z_{k+1}}{r_k^\top z_k},\quad p_{k+1}=z_{k+1}+\beta_{k+1}p_k. αk=pk⊤Apkrk⊤zk,βk+1=rk⊤zkrk+1⊤zk+1,pk+1=zk+1+βk+1pk.

  • 预条件器选择(从轻到重)

    • Jacobi/对角缩放 : M = diag ( A ) M=\text{diag}(A) M=diag(A),零成本起步。
    • 不完全 Cholesky (IC) :稀疏近似 A ≈ L L ⊤ A\approx LL^\top A≈LL⊤,求解 M z = r Mz=r Mz=r 只需三角回代。
    • 块对角/多级(AMG):更强但实现复杂,图拉普拉斯与 PDE 常用。

直觉:预条件把"细长的谷底"拉"圆",让 κ \kappa κ 变小,从而指数级加速收敛。


7. 与机器学习/大模型的连接

  • 最小二乘 / 线性回归 :解 min ⁡ ∥ X w − y ∥ 2 2 \min\|Xw-y\|_2^2 min∥Xw−y∥22 的正规方程 ( X ⊤ X ) w = X ⊤ y (X^\top X)w=X^\top y (X⊤X)w=X⊤y 是 SPD。

    • 不建议显式形成 X ⊤ X X^\top X X⊤X(会使条件数平方),而是用矩阵--自由方式:

      • 给定向量 v v v,实现 A v = ( X ⊤ X ) v = X ⊤ ( X v ) A v=(X^\top X) v = X^\top(X v) Av=(X⊤X)v=X⊤(Xv)。
      • 这就是CGNR/CGNE 或直接用 LSQR/LSMR(数值更稳)。
  • 核方法 / 高斯过程 :核矩阵 K + λ I K+\lambda I K+λI 是 SPD,PCG 是核回归、GP 拟合的重要求解器(配合 MVM 加速、近似核)。

  • 图学习 / 图拉普拉斯 :解 L x = b Lx=b Lx=b( L L L SPD),CG + 预条件(如 AMG)是标准配置。

  • 二阶方法的内循环 :在逻辑回归/深度学习的牛顿/拟牛顿中,需要解 H Δ = − g H \Delta=-g HΔ=−g( H H H 近似 SPD),可用PCG 作为内层线性求解器。

  • 大模型训练 :在分布式二阶近似 (K-FAC、Shampoo 等)里,也常见到"预条件 + 共轭"的影子。


8. 实现要点与数值细节

  1. 矩阵--自由 :只实现 Av(v),不要显式存 A A A。稀疏或算子形式都可。

  2. 停止准则 : ∥ r k ∥ 2 / ∥ b ∥ 2 ≤ tol \|r_k\|_2/\|b\|_2 \le \text{tol} ∥rk∥2/∥b∥2≤tol 或 ∥ r k ∥ M ≤ tol \|r_k\|_M \le \text{tol} ∥rk∥M≤tol。

  3. 重启与正交丢失 :有限精度下 A-共轭会逐渐被破坏;可周期重启 (重新置 p = r p=r p=r),或保存/再正交化(成本较高)。

  4. 非 SPD 的情况

    • 非对称:用 GMRES/BiCGSTAB
    • 对称但不定:用 MINRESSYMMLQ
  5. 溢出与稳健 :向量内积和标量更新要用双精度;必要时做残差替换 (间或重新计算 r k = b − A x k r_k=b-Ax_k rk=b−Axk)。


9. 迷你代码(矩阵--自由 + 预条件,NumPy 伪码)

python 复制代码
import numpy as np

def pcg(Av, b, Msolve=None, x0=None, tol=1e-8, maxit=None):
    """
    Av:    函数,返回 A @ v
    Msolve:函数,解 M z = r 的近似(预条件器),默认为恒等
    """
    n = len(b)
    if x0 is None: x = np.zeros(n)
    else: x = x0.copy()
    if Msolve is None: Msolve = lambda r: r
    if maxit is None: maxit = 2*n

    r = b - Av(x)
    z = Msolve(r)
    p = z.copy()
    rz_old = np.dot(r, z)
    bnorm = np.linalg.norm(b)
    if bnorm == 0: bnorm = 1.0

    for k in range(maxit):
        Ap = Av(p)
        alpha = rz_old / np.dot(p, Ap)
        x += alpha * p
        r -= alpha * Ap

        if np.linalg.norm(r) / bnorm < tol:
            break

        z = Msolve(r)
        rz_new = np.dot(r, z)
        beta = rz_new / rz_old
        p = z + beta * p
        rz_old = rz_new
    return x, k
  • Jacobi 预条件Msolve = lambda r: r / diagA(元素除法)。

  • 矩阵--自由示例(正规方程):

    python 复制代码
    Av = lambda v: X.T @ (X @ v) + lam * v
    b  = X.T @ y

    避免显式形成 X ⊤ X X^\top X X⊤X。


10. 小示例(思路版)

  • 数据 X ∈ R 10 6 × 100 X\in\mathbb{R}^{10^6\times 100} X∈R106×100 稀疏,求岭回归:

    • Av(v)=X.T @ (X @ v) + lam * vb=X.T @ y
    • Msolvediag(X.T@X)+lam 的对角近似(可用一次遍历估出对角)。
    • tol=1e-6,几十到上百步内即可得到可用精度的解。

11. 选择线性求解器的"路线图"

对称正定
对称不定
非对称


待解方程 Ax=b
矩阵类型
共轭梯度
MINRES
GMRES 或 BiCGSTAB
条件数大?
加预条件: Jacobi IC AMG
直接 CG
考虑右预条件

说明:先辨别矩阵类型,再选 Krylov 方法;条件数大就上预条件。


12. 常见坑与排错

  1. 用在非 SPD 上 → 可能发散或震荡。

    • 排错:先检查对称性与正定性;若不满足,改用 GMRES/MINRES。
  2. 形成 X ⊤ X X^\top X X⊤X → 条件数平方放大、数值不稳。

    • 排错:用矩阵--自由 v ↦ X ⊤ ( X v ) v\mapsto X^\top(Xv) v↦X⊤(Xv) 或直接 LSQR。
  3. A-共轭丢失 → 收敛变慢。

    • 排错:周期性重算残差、降低容差、改进预条件。
  4. 预条件过强/过弱

    • 过强:构造和求解 M z = r Mz=r Mz=r 太贵;过弱:加速有限。
    • 折中:先用对角/块对角,必要时 IC/AMG。
  5. 停止准则过松/过严

    • 过松:解不够准;过严:迭代时间长。
    • 建议:相对残差 \|r\|_2/\|b\|_2 + 任务容忍度。

13. 练习(含提示)

  1. 从最优性推导 α k , β k \alpha_k,\beta_k αk,βk

    • 用一维最优 min ⁡ α ϕ ( x k + α p k ) \min_\alpha \phi(x_k+\alpha p_k) minαϕ(xk+αpk) 导出 α k \alpha_k αk;
    • 用 A-共轭与残差正交性导出 β k + 1 \beta_{k+1} βk+1 的闭式。
  2. 误差界 :证明二次型上 ∥ e k ∥ A \|e_k\|_A ∥ek∥A 的收敛率与 κ \sqrt{\kappa} κ 有关。

  3. PCG 收敛改善 :随机生成条件数为 10 4 10^4 104 的 SPD 矩阵,对比无预条件 vs Jacobi vs IC。

  4. 矩阵--自由 :在稀疏 X X X 的岭回归上,用 Av(v)=X.T@(X@v)+lam*v 实现 PCG,画迭代次数--容差曲线。

  5. 非 SPD 场景:在对称不定矩阵上尝试 CG 与 MINRES,对比收敛行为。

  6. 残差替换 :实现"每 10 次迭代重算一次 r = b − A x r=b-Ax r=b−Ax"的变体,观察稳定性变化。


14. 小结

  • 共轭梯度 专治 SPD + 大规模稀疏 的线性系统:矩阵--自由、每步只要一次 SpMV、内存友好。
  • 收敛速度由条件数主导 ,PCG 能显著加速;与最速下降相比,CG 的收敛因子相当于取了平方根
  • 在 ML/GP/图学习/二阶优化的内循环中,CG/PCG 是可靠"工作马"。
  • 工程要点:矩阵--自由实现、恰当预条件、稳健停止准则、周期重启
    记住这句:"能 CG 就别 LU,能 PCG 就别裸跑。"
相关推荐
z_lices2 小时前
倪仁勇:K线语言破译者,技术分析体系的建构者与传播者
大数据·人工智能
半问2 小时前
AI知识库,是捷径吗?
人工智能·ai·互联网·产品经理
瑶光守护者2 小时前
【Rockchip RK3576】边缘计算与 AIoT 领域的全能架构深度解析
人工智能·架构·边缘计算
信创天地2 小时前
信创运维核心技术:国产化软硬件适配与故障排查全解析
运维·人工智能·开源·dubbo·运维开发·risc-v
DS随心转小程序2 小时前
ai转pdf
人工智能·pdf·aigc·deepseek·ds随心转
做科研的周师兄2 小时前
【机器学习入门】9.3:一文吃透感知机(神经网络的 “地基“)
人工智能·神经网络·机器学习
点云SLAM2 小时前
Imposed 英文单词学习
人工智能·英文单词学习·雅思备考·imposed·强加 / 施加·征收 / 征税
言無咎2 小时前
RPA财务机器人已OUT?2026掌金AI以多模态LLM重构财税自动化
人工智能·机器人·rpa
zhangfeng11332 小时前
大语言模型训练不用bpe算法可以不可以 ,BPE 是算法,SentencePiece 是工具箱
人工智能·语言模型·自然语言处理