二次型优化问题 - 6 - 共轭梯度法

本文最后更新于:2022年8月10日 上午

本文介绍二次型优化方法中比较优秀的迭代方法——共轭梯度法。

问题描述

重述我们需要优化的问题:

$$
f({\bf{x} }) = \frac{1}{2}{\bf{x^TAx} } - { {\bf{b} }^{\bf{T} } }{\bf{x} } + {\bf{c} } \tag{1} \label{1}
$$

  • 矩阵$\bf{A}$正定对称
  • 目标为优化$\bf{x}$,使得$f(\bf{x})$取得最小值

最速下降法的问题

  • 贪心计算局部最小值
  • 没有全局视野,没有使用真正的模型建模
  • 导致优化过程需要反复迭代才能逐步逼近最优值

轭是一个汉字,读作è,本意是指驾车时套在牲口脖子上的曲木,引申义是束缚,控制。该文字在《仪礼·既夕礼》和《荀子·正论》等文献均有记载。 ——百度百科

  • 数学中很多轭相关的内容,此处的共轭表示相互约束,在某个条件下可以相互作用的意思。

共轭梯度法思想来源

  • 为解决最速下降法来回往复的问题,人们开始思考是否有可以直接在需要优化的二次函数定义下直接对其进行优化,是否可以通过有限步计算得到真正的最优解
  • 那么假设我们使用关于该问题精确的模型而不是近似的局部最优模型,我们如果可以在某个N维空间中,分别计算出最优解的各个维度的坐标,就可以达到上述目的
  • 那么如何设计这个空间,如何可以分步计算并且可以整合成真正的结果,是共轭梯度法来解决的问题
  • 该方法的核心思想是建立一组N维空间线性无关的一组基,理论上这组基的线性组合可以表示空间中任意一点,共轭梯度法通过多次计算,精确求解目标在空间中位置在这组基空间中的各个系数分量,达到求解最优值的目的
  • 该方法和最速下降法却别在精确建模,有了上帝视角,每次迭代计算将该方向需要调整的分量值调整到极致,也就是说之后的计算再也不用考虑该方向上的运动分量了,这是一个精确求解问题的过程,不是逐步简单建模向最优值挪动的逼近过程

共轭基的定义

设$\bf{A}$为$n$阶实对称正定矩阵,如果有两个$n$维列向量$\bf{s}_1$和$\bf{s}_2$满足

$$ {\bf{s}}_1^T{\bf{A}}{{\bf{s}}_2} = 0 \tag{2} \label{2} $$

则称向量$\bf{s}_1$和$\bf{s}_2$对于矩阵$\bf{A}$共轭。如果$\bf{A}$为单位矩阵,则式$\eqref{2}$即成为$\bf{s}_1$$\bf{s}_2$,这样两个向量的点积为零,此二向量在几何上是正交的,它是共轭的一种特例。

设A为对称正定矩阵,若一组非零向量$\bf{s}_1$,$\bf{s}_2$,…,$\bf{s}_n$满足

$$ {\bf{s}}_i^T{\bf{A}}{{\bf{s}}_j} = 0 (i≠j) \tag{3} $$ 则称向量系${{\bf{s}}_i}(1 \le i \le n)$为关于矩阵$\bf{A}$共轭。 若${{\bf{s}}_i}(1 \le i \le n)$之间线性无关,那么我们称该向量集合为$n$维空间中关于矩阵$\bf{A}$的一组共轭基。

共轭基的作用

  • 假设有一组关于矩阵$\bf{A}$的共轭基$\bf{D}$:

$$
\bf{D}={ {\bf{d}_1},{\bf{d}_2},…,{\bf{d}_n}} \tag{4}
$$

  • 设二次型函数$\eqref{1}$的极值为$\bf{x}^*$,用$\bf{D}$表似为:
$$ { {\bf{x} }^*} = {\lambda _1}{ {\bf{d} }_1} + {\lambda _2}{ {\bf{d} }_2} + \cdots + {\lambda _n}{ {\bf{d} }_n} \tag{5} $$
  • 因为函数极值处在各个方向的导数为0有:
$$ \begin{array}{l} f'({{\bf{x}}^*}) = {\bf{A}}{{\bf{x}}^*} - {\bf{b}} = 0\\ \Rightarrow {\bf{A}}{{\bf{x}}^*} = {\bf{b}} \end{array} \tag{6} $$
  • 我们计算${\bf{d}}_i^T{\bf{A}}{{\bf{x}}^*}$,根据不同共轭基之间相互共轭:
$$ \begin{array}{l} {\bf{d}}_i^T{\bf{A}}{{\bf{x}}^*} &= {\bf{d}}_i^T{\bf{A}}\left( {{\lambda _0}{{\bf{d}}_0} + \ldots + {\lambda _{n - 1}}{{\bf{d}}_{n - 1}}} \right)\\ &= {\lambda _i}{\bf{d}}_i^T{\bf{A}}{{\bf{d}}_i} + 0\\ \tag{7} \end{array} $$
  • 得到:
$$ {\lambda _i} = \frac{{{\bf{d}}_i^T{\bf{A}}{{\bf{x}}^*}}}{{{\bf{d}}_i^T{\bf{A}}{{\bf{d}}_i}}} = \frac{{{\bf{d}}_i^T{\bf{b}}}}{{{\bf{d}}_i^T{\bf{A}}{{\bf{d}}_i}}} \tag{8} \label{8} $$
  • 对于${\lambda _i}$的求解,我们已知的变量为$\bf{b}$和$\bf{A}$,如果我们已经得到了空间中关于$\bf{A}$的共轭基(任意一组),我们都可以直接解得${\lambda _i}$
  • 这是一个令人振奋的结论,所以我们当前的工作重点转为了如何快速地求得一组关于$\bf{A}$的共轭基

根据定义获取共轭基

  • 有了定义,我们不难想到暴力获取共轭基的方法:
graph TB
    A(随机生成n个n维向量)
    B{i=1-n循环}
    C[剔除向量j=1-i的分量]
    E[收集向量1-n]
    D[得到向量i]	
    A-->B
    C --> D
    D --> B
    B-- 循环结束 --> E --> F(输出共轭基)
    B-- 循环未结束 -->C
  • 这套方法下来,我们就可以得到根据定义计算出来的共轭基,带入$\eqref{8}$计算得到极值,没有任何问题
  • 但事实上这个运算量与代数法解${\bf{A}}{{\bf{x}}} = {\bf{b}}$的过程具有相当的运算复杂度,没有给该优化问题带来性能收益

共轭梯度法

此算法核心步骤与最速下降法相同,分别为寻找共轭方向与计算运动步长。

寻找共轭方向

由于计算梯度简单,寻找共轭梯度的过程依附于梯度方向的计算。

  • 优化目标为$\bf{x}^*$,初始位置为$\bf{x}_1$,需要求得的共轭基为 $\bf{D}={ {\bf{d}_1},{\bf{d}_2},…,{\bf{d}_n}}$
  • 计算初始$\bf{x}_1$位置的梯度,第一个共轭基为梯度的反方向:
$$ {{\bf{d}}_1} = - {{\bf{g}}_1} = - ({\bf{A}}{{\bf{x}}_1} - {\bf{b}}) = {\bf{b}} - {\bf{A}}{{\bf{x}}_1} \tag{9} $$
  • 第$i$个梯度若要剔除掉第$j$个共轭基$(j<i)$方向的分量,需要减去该方向的$\beta_j $分量:
$$ \begin{array}{l} {\bf{d}}_j^T{\bf{A}}({{\bf{g}}_i} - \beta_j {{\bf{d}}_j}) = 0\\ {\bf{d}}_j^T{\bf{A}}{{\bf{g}}_i} = \beta_j {\bf{d}}_j^T{\bf{A}}{{\bf{d}}_j}\\ \beta_j = \frac{{{\bf{d}}_j^T{\bf{A}}{{\bf{g}}_i}}}{{{\bf{d}}_j^T{\bf{A}}{{\bf{d}}_j}}} \end{array} \tag{10} \label{10} $$
  • 因此第$k$个共轭基为:
$$ \begin{array}{l} {{\bf{d}}_k} = {{\bf{g}}_k} - \sum\limits_{i = 1}^{k - 1} {\frac{{{\bf{d}}_i^T{\bf{A}}{{\bf{g}}_k}}}{{{\bf{d}}_i^T{\bf{A}}{{\bf{d}}_i}}}{{\bf{d}}_i}} \\ {{\bf{d}}_k}={{\bf{g}}_k} -\sum\limits_{i = 1}^{k - 1}\beta_i{{\bf{d}}_i} \end{array} \tag{11} \label{11} $$
  • 目前,我们如果可以确定每一次迭代移动的$\bf{x}_i$的位置,求得$\bf{g}_i$,那么就可以根据第1到第$i-1$个共轭基确定当前第$i$个共轭基
  • 因此当前我们的目标是在有了共轭方向后,如何确定在该方向上的运动距离

确定运动距离

已经运动到了$\bf{x}_k$的位置,下一个前进方向为${{\bf{d}}_k}$,前进步长${\alpha _k}$,误差为$\bf{e}_{k}=\bf{x}^*-x_{k}$,也就是说: $$ {{\bf{x}}_{k + 1}}={{\bf{x}}_k} + {\alpha _k}{{\bf{d}}_k} \tag{12} $$

这里介绍两种求前进步长${\alpha _k}$的思路。

方法一

确定第$k$步的运动步长${\alpha _k}$,也就是一个共轭基的系数,限制该系数的条件为:

  • 当前共轭基的方向$\bf{d}_{k}$与误差向量$\bf{e}_{k+1}=\bf{x}^*-x_{k+1}$共轭: $$ \begin{aligned} \bf{d}_{k}^{T^{\prime}} A e_{k+1} &=\bf{d}_{k}^{T} A\left(x^{*}-x_{k+1}\right) \\ &=\bf{d}_{k}^{T} A\left(x^{*}-x_{k}+x_{k}-x_{k+1}\right) \\ &=\bf{d}_{k}^{T} A\left(e_{k}-\alpha_{k} \bf{d}_{k}\right) \\ &=\bf{d}_{k}^{T} A e_{k}-\alpha_{k} \bf{d}_{k}^{T} A \bf{d}_{k}=0 \end{aligned} \tag{13} \label{13} $$
  • 有:

$$ \begin{aligned} \alpha_{k} &=\frac{\bf{d}_{k}^{T} A e_{k}}{\bf{d}_{k}^{T} A \bf{d}_{k}} \\ &=\frac{\bf{d}_{k}^{T} A\left(x^{*}-x_{k}\right)}{\bf{d}_{k}^{T} A \bf{d}_{k}} \\ &=\frac{\bf{d}_{k}^{T}\left(A x^{*}-A x_{k}\right)}{\bf{d}_{k}^{T} A \bf{d}_{k}} \\ &=\frac{\bf{d}_{k}^{T}\left(b-A x_{k}\right)}{\bf{d}_{k}^{T} A \bf{d}_{k}} \\ &=-\frac{\bf{d}_{k}^{T} g_{k}}{\bf{d}_{k}^{T} A \bf{d}_{k}} \end{aligned} \tag{14} $$
方法二
对$f({{\bf{x}}_{k + 1}})$中的${\alpha _k}$求导,使得导数为0,计算${\alpha _k}$:
  • 用${{\bf{x}}_k}$表示${{\bf{x}}_{k+1}}$: $$ \begin{array}{l} f({{\bf{x}}_{k + 1}}) &= f({{\bf{x}}_k} + {\alpha _k}{{\bf{d}}_k})\\ &= \frac{1}{2}{\bf{x}}_{k + 1}^T{\bf{A}}{{\bf{x}}_{k + 1}} - {{\bf{b}}^T}({{\bf{x}}_k} + {\alpha _k}{{\bf{d}}_k}) + c \end{array} \tag{15} $$
  • 对$f({{\bf{x}}_{k + 1}})$中${\alpha _k}$求导: $$ \begin{array}{l} f'({{\bf{x}}_{k + 1}}|{\alpha _k}) &= \frac{{\partial f({{\bf{x}}_{k + 1}})}}{{\partial {{\bf{x}}_{k + 1}}}}\frac{{\partial {{\bf{x}}_{k + 1}}}}{{\partial {\alpha _k}}}\\ &= {({\bf{A}}{{\bf{x}}_{k + 1}} - {\bf{b}})^T}{{\bf{d}}_k}\\ &= {({\bf{A}}{{\bf{x}}_k} + {\alpha _k}{\bf{A}}{{\bf{d}}_k} - {\bf{b}})^T}{{\bf{d}}_k}\\ &= {({\alpha _k}{\bf{A}}{{\bf{d}}_k} + {{\bf{g}}_k})^T}{{\bf{d}}_k}\\ &= {\alpha _k}{\bf{d}}_k^TA{{\bf{d}}_k} + {\bf{g}}_k^T{{\bf{d}}_k} \end{array} \tag{16} $$
  • 使导数为0,有: $$ \begin{array}{l} {\alpha _k}{\bf{d}}_k^TA{{\bf{d}}_k} + {\bf{g}}_k^T{{\bf{d}}_k} = 0\\ {\alpha _k} = - \frac{{{\bf{g}}_k^T{{\bf{d}}_k}}}{{{\bf{d}}_k^TA{{\bf{d}}_k}}} = - \frac{{{\bf{d}}_k^T{{\bf{g}}_k}}}{{{\bf{d}}_k^TA{{\bf{d}}_k}}} \end{array} \tag{17} $$

此时我们已经计算得到了一系列计算共轭梯度的方法,能够依次求得一套共轭基了,但是其中有些步骤仍然可以继续简化计算。

简化计算与一些推论

推论一
  • 第$k$步计算的梯度$\bf{g}_k$和前$k-1$步的共轭向量${\bf{d}_1,\bf{d}_1,...,\bf{d}_{k-1}}$正交:
  • 证明,当$i < j$时: $$ \begin{array}{l} \bf{d}_i^T{g_j} &= \bf{d}_i^T(A{x_j} - b)\\ &= \bf{d}_i^T(A{x_j} - A{x^*})\\ &= - \bf{d}_i^T(A{x^*} - {x_{i + 1}} + {x_{i + 1}} - {x_j})\\ &= - \bf{d}_i^TA({e_{i + 1}} - \sum\limits_{k = i + 1}^{j - 1} {{\alpha _k}{d_k})} \\ &= - \bf{d}_i^TA{e_{i + 1}} + \sum\limits_{k = i + 1}^{j - 1} {{\alpha _k}d_i^TA{d_k}} \end{array} \tag{18} \label{18} $$
  • 式$\eqref{18}$左边由于$\bf{d}_i$计算过程$\eqref{13}$为0,右边由于不同的共轭向量间两两共轭值为0,所以最终的值也为0

  • 因此证明了:第$ k $步计算的梯度 $ \bf{g}_k$ 和前$k-1$步的共轭向量 $ { \bf{d}_1,\bf{d}_1,...,\bf{d}_{k-1}}$正交。
推论二
  • 第$k$步计算的梯度$\bf{g}_k$和前$k-1$步的梯度${\bf{g}_1,\bf{g}_1,...,\bf{g}_{k-1}}$正交:
  • 证明,当$i < j$时:
  • 由$\eqref{11}$得:

$$ {{\bf{g}}_i}={{\bf{d}}_i} +\sum\limits_{k = 1}^{i - 1}\beta_k{{\bf{d}}_k} \tag{19} $$
  • 有:
$$ \begin{array}{l} {\bf{g}}_i^T{{\bf{g}}_j} &= {({{\bf{d}}_i} + \sum\limits_{k = 1}^{i - 1} {{\beta _k}} {{\bf{d}}_k})^T}{{\bf{g}}_j}\\ &= \sum\limits_{k = 1}^i {{\beta _k}} {{\bf{d}}_k}^T{{\bf{g}}_j} \qquad ({\beta _i} = 1) \tag{20} \label{20} \end{array} $$
  • 根据推论一,式$\eqref{20}$值为0
  • 证得结论:第$k$步计算的梯度$\bf{g}_k$和前$k-1$步的梯度${\bf{g}_1,\bf{g}_1,...,\bf{g}_{k-1}}$正交。
  • 那么对于两个不同的梯度$\bf{g}_i, \bf{g}_j(i \ne j)$,那么二者必分前后,因此各个梯度之间相互正交,即${\bf{G}} = \{ {{\bf{g}}_{1,}}{{\bf{g}}_2},...,{{\bf{g}}_n}\} $组成了$n$维空间中的一组正交基
推论三
  • 计算${\bf{g}}_{j + 1}^T{{\bf{g}}_i}$: $$ \begin{array}{l} {\bf{g}}_{j + 1}^T{{\bf{g}}_i} &= {({\bf{A}}{{\bf{x}}_{j + 1}} - {\bf{b}})^T}{{\bf{g}}_i}\\ &= {({\bf{A}}({{\bf{x}}_j} + {\alpha _j}{{\bf{d}}_j}) - {\bf{b}})^T}{{\bf{g}}_i}\\ &= {({\bf{A}}{{\bf{x}}_j} - {\bf{b}} + {\alpha _j}{\bf{A}}{{\bf{d}}_j})^T}{{\bf{g}}_i}\\ & = {({{\bf{g}}_j} + {\alpha _j}{\bf{A}}{{\bf{d}}_j})^T}{{\bf{g}}_i}\\ &= {\bf{g}}_j^T{{\bf{g}}_i} + {\alpha _j}{\bf{d}}_j^TA{{\bf{g}}_i}\\ {\bf{d}}_j^TA{{\bf{g}}_i}& = \frac{1}{{{\alpha _j}}}({\bf{g}}_{j + 1}^T{{\bf{g}}_i} - {\bf{g}}_j^T{{\bf{g}}_i}) \end{array} \tag{21} \label{21} $$
  • 根据式$\eqref{21}$和推论二,由于一般情况下$\alpha _j$不为0,因此对于所有情况为保证$\eqref{20}$成立,需要当$i \ne j$且$i \ne j+1$时,${\bf{d}}_j^TA{{\bf{g}}_i}=0$

  • 这意味着当前的梯度方向与上一个共轭方向之前的和当前之后的所有共轭方向共轭正交

简化计算
  • 对于式$\eqref{11}$中,在求解$\bf{d}_k$过程中产生的系数$\beta$,此处强调一下$\eqref{10}$:
$$ {\beta _i} = \frac{{{\bf{d}}_i^T{\bf{A}}{{\bf{g}}_k}}}{{{\bf{d}}_i^T{\bf{A}}{{\bf{d}}_i}}} $$
  • 推论三,$\eqref{10}$中当$i\ne k$且$i \ne k-1$时,${{\bf{d}}_i^T{\bf{A}}{{\bf{g}}_k}}$值为0

  • 因此式$\eqref{11}$可以简化为: $$ \begin{array}{l} {{\bf{d}}_k} &= {{\bf{g}}_k} - \sum\limits_{i = 1}^{k - 1} {{\beta _i}} {{\bf{d}}_i}\\ &= {{\bf{g}}_k} - {{\beta _{k-1}}} {{\bf{d}}_{k-1}} \end{array} \tag{22} \label{22} $$
  • 即在求解第$k$个共轭基时,仅需要在当前梯度$\bf{g}_k$上减去第$k-1$个共轭基的共轭分量即可

推论四
  • 根据简化计算的公式$\eqref{22}$,有:
$$ \begin{array}{l} {{\bf{d}}_k} &= {{\bf{g}}_k} - {\beta _{k - 1}}{{\bf{d}}_{k - 1}}\\ &= {{\bf{g}}_k} - {\beta _{k - 1}}({{\bf{g}}_{k - 1}} - {\beta _{k - 2}}{{\bf{d}}_{k - 2}})\\ &= {{\bf{g}}_k} + {\gamma _{k - 1}}{{\bf{g}}_{k - 1}} + {\gamma _{k - 2}}{{\bf{g}}_{k - 2}} + \cdots {\gamma _1}{{\bf{g}}_1}\\ &= \sum\limits_{i = 1}^k {{\gamma _i}{{\bf{g}}_i}} \end{array} \tag{23} $$
  • 其中固定的常数系数用$\gamma$表示
  • 那么有:
$$ \begin{array}{l} {\bf{g}}_i^T{{\bf{d}}_j} &= {\bf{g}}_i^T\sum\limits_{k = 1}^j {{\gamma _k}{{\bf{g}}_k}} \\ & = \sum\limits_{k = 1}^j {{\gamma _k}{\bf{g}}_i^T{{\bf{g}}_k}} \end{array} \tag{24} \label{24} $$
  • 式$\eqref{24}$根据推论二的结论,值为:
$$ {\bf{g}}_i^T{{\bf{d}}_j} = \left\{ {\begin{array}{*{20}{c}} {0,i > j}\\ {\gamma_i{\bf{g}}_i^T{{\bf{g}}_i},i \le j} \end{array}} \right. \tag{25} $$
  • 即某个梯度与所有共轭基的投影为0或一个常数(对该方法来说不是一个有实用性的结论)

共轭梯度法实操步骤

  • 初始条件:已知$\bf{A}, \bf{b}$,初始位置$\bf{x}_1$
  • $\bf{g}_1=\bf{A}\bf{x}_1-\bf{b}$
  • ${{\bf{d}}_1} = - {{\bf{g}}_{\bf{1}}}$
  • $k=1$
  • $while \quad k \le n:$
    • $\alpha_{k} = - \frac{{{\bf{d}}_k^T{{\bf{g}}_k}}}{{{\bf{d}}_k^TA{{\bf{d}}_k}}}$
    • $\bf{x}_{k+1}=\bf{x}_k+\alpha_{k}{\bf{d}}_k$
    • $\bf{g}_{k+1}=\bf{A}\bf{x}_{k+1}-\bf{b}$
    • ${\beta _k} = \frac{{{\bf{d}}_k^T{\bf{A}}{{\bf{g}}_{k+1}}}}{{{\bf{d}}_k^T{\bf{A}}{{\bf{d}}_k}}}$
    • ${{\bf{d}}_{k+1}}={{\bf{g}}_{k+1}} - {{\beta _{k}}} {{\bf{d}}_{k}}$
    • $k=k+1$
  • $return \quad \bf{x}_{n+1}$

参考资料


二次型优化问题 - 6 - 共轭梯度法
https://www.zywvvd.com/notes/study/machine-learning/conjugate-gradient-algorithm/conjugate-alg/conjugate-alg/
作者
Yiwei Zhang
发布于
2020年12月26日
许可协议