共轭梯度法(CG)详解
这篇文章写得不错,建议收藏。想要了解 CG,把它认认真真读一遍,就很清楚了。
之前写过几个关于共轭梯度法的注记,譬如:
- https://blog.csdn.net/lusongno1/article/details/78550803
- https://blog.csdn.net/lusongno1/article/details/68942821
但事实上很多人反应,看得一头雾水,基于此,本篇文章旨在对于共轭梯度方法从优化的角度给一个干净的描述。
线性共轭梯度法
线性共轭梯度方法是 Hestenes 和 Stiefel 在 20 世纪 50 年代提出来的的一个迭代方法,用于求解正定系数矩阵的线性系统。
假定
A
A
A 是对称正定的矩阵,求解线性方程组
A
x
=
b
A x=b
Ax=b
等价于求解如下凸优化问题:
min
ϕ
(
x
)
≡
1
2
x
T
A
x
−
b
T
x
\min \phi(x) \equiv \frac{1}{2} x^{T} A x-b^{T} x
minϕ(x)≡21xTAx−bTx
该问题的梯度便是原线性系统的残差,
∇
ϕ
(
x
)
=
A
x
−
b
≡
r
(
x
)
\nabla \phi(x)=A x-b \equiv r(x)
∇ϕ(x)=Ax−b≡r(x)
在
x
=
x
k
x=x_k
x=xk 点,
r
k
=
A
x
k
−
b
r_{k}=A x_{k}-b
rk=Axk−b。
共轭方向
定义 对于非零向量集合
{
p
0
,
p
1
,
⋯
,
p
t
}
\left\{p_{0}, p_{1}, \cdots, p_{t}\right\}
{p0,p1,⋯,pt} 关于对称正定矩阵
A
A
A 是共轭的,若
p
i
T
A
p
j
=
0
,
for all
i
≠
j
.
p_{i}^{T} A p_{j}=0, \quad \text { for all } i \neq j .
piTApj=0, for all i=j.
容易证明,共轭向量之间是线性独立的。
假设已经有了一组共轭向量,我们把未知量表示为它们的线性组合
x
=
∑
i
=
1
n
α
i
p
i
x=\sum_{i=1}^{n} \alpha^{i} p_{i}
x=∑i=1nαipi,我们希望能够寻找一组系数,去极小化
ϕ
(
x
)
=
∑
i
=
1
n
(
(
α
i
)
2
2
p
i
T
A
p
i
−
α
i
p
i
T
b
)
\phi(x)=\sum_{i=1}^{n} \left(\frac{\left(\alpha^{i}\right)^{2}}{2} p_{i}^{T} A p_{i}-\alpha^{i} p_{i}^{T} b\right)
ϕ(x)=i=1∑n(2(αi)2piTApi−αipiTb)
求和中的每一项都是独立的,极小化之,那么我们就可以得到
α
i
=
p
i
T
b
p
i
T
A
p
i
\alpha^{i}=\frac{p_{i}^{T} b}{p_{i}^{T} A p_{i}}
αi=piTApipiTb
通过共轭方向,把一个 n 维问题,拆解成了 n 个一维问题。
从矩阵的角度来看这个问题,我们把自变量做一个变换,
x
^
=
S
−
1
x
\hat{x}=S^{-1} x
x^=S−1x
其中,
S
S
S 由共轭向量张成,
S
=
[
p
0
,
p
1
,
⋯
,
p
n
−
1
]
S=\left[p_{0}, p_{1}, \cdots, p_{n-1}\right]
S=[p0,p1,⋯,pn−1]
那么二次问题变为,
ϕ
^
(
x
^
)
≡
ϕ
(
S
x
^
)
=
1
2
x
^
T
(
S
T
A
S
)
x
^
−
(
S
T
b
)
T
x
^
\hat{\phi}(\hat{x}) \equiv \phi(S \hat{x})=\frac{1}{2} \hat{x}^{T}\left(S^{T} A S\right) \hat{x}-\left(S^{T} b\right)^{T} \hat{x}
ϕ^(x^)≡ϕ(Sx^)=21x^T(STAS)x^−(STb)Tx^
由共轭性,我们知道矩阵
S
T
A
S
S^{T} A S
STAS 是个对角矩阵,那么久变成了一个对角矩阵系数的极简方程。
共轭方向法
所谓的共轭方向法,就是给定初值点
x
0
x_0
x0 和一组共轭方向,我们通过如下方式迭代更新
x
k
x_k
xk:
x
k
+
1
=
x
k
+
α
k
p
k
x_{k+1}=x_{k}+\alpha_{k} p_{k}
xk+1=xk+αkpk
α
k
=
−
r
k
T
p
k
p
k
T
A
p
k
\alpha_{k}=-\frac{r_{k}^{T} p_{k}}{p_{k}^{T} A p_{k}}
αk=−pkTApkrkTpk
1、这里的步长 α k \alpha_k αk 是二次函数 ϕ \phi ϕ 沿着 x k + α p k x_{k}+\alpha p_{k} xk+αpk 的一维的极小化,我们一般称之为精确线搜索步长。
2、理论上,精确线搜索方法至多 n 步收到到线性系统的解。忽略证明。
对于共轭方向法来说,有如下定理。
定理:
x
0
∈
ℜ
n
x_{0} \in \Re^{n}
x0∈ℜn 是任意起点,
{
x
k
}
\left\{x_{k}\right\}
{xk} 通过共轭方向法生成,那么
r
k
T
p
i
=
0
,
for
i
=
0
,
1
,
⋯
,
k
−
1
,
r_{k}^{T} p_{i}=0, \text { for } i=0,1, \cdots, k-1,
rkTpi=0, for i=0,1,⋯,k−1,
且
x
k
x_{k}
xk 在集合
{
x
∣
x
=
x
0
+
span
{
p
0
,
p
1
,
⋯
,
p
k
−
1
}
}
.
\left\{x \mid x=x_{0}+\operatorname{span}\left\{p_{0}, p_{1}, \cdots, p_{k-1}\right\}\right\} .
{x∣x=x0+span{p0,p1,⋯,pk−1}}.
上,关于
ϕ
(
x
)
=
1
2
x
T
A
x
−
b
T
x
\phi(x)=\frac{1}{2} x^{T} A x-b^{T} x
ϕ(x)=21xTAx−bTx 的极小化。
CG 方法
共轭方向法的共轭方向如何得到呢?共轭梯度方法(Conjugate Gradient,CG)方法是一个特别的共轭方向法:它的共轭方向是在 x k x_k xk 的迭代中一个一个生成出来的,并且 p k p_k pk 的计算只用到 p k − 1 p_{k-1} pk−1。
它的思想在于,选取当前共轭方向为负梯度方向和前一个共轭方向的线性组合,
p
k
=
−
r
k
+
β
k
p
k
−
1
p_{k}=-r_{k}+\beta_{k} p_{k-1}
pk=−rk+βkpk−1
将其左乘
p
k
−
1
T
A
p_{k-1}^{T} A
pk−1TA,由
p
k
p_k
pk 与
p
k
−
1
p_{k-1}
pk−1 的共轭性,可以得到组合系数:
β
k
=
r
k
T
A
p
k
−
1
p
k
−
1
T
A
p
k
−
1
\beta_{k}=\frac{r_{k}^{T} A p_{k-1}}{p_{k-1}^{T} A p_{k-1}}
βk=pk−1TApk−1rkTApk−1
在这个过程中,选择
p
0
p_0
p0 为
x
0
x_0
x0 处负梯度方向,结合前面的介绍,就可以得到线性共轭梯度方法。
注意到梯度和共轭方向的一些关系:
r
k
T
r
i
=
0
,
∀
i
=
0
,
⋯
,
k
−
1
span
{
r
0
,
r
1
,
⋯
,
r
k
}
=
span
{
r
0
,
A
r
0
,
⋯
,
A
k
r
0
}
span
{
p
0
,
p
1
,
⋯
,
p
k
}
=
span
{
r
0
,
A
r
0
,
⋯
,
A
k
r
0
}
p
k
T
A
p
i
=
0
,
∀
i
=
0
,
1
,
⋯
,
k
−
1.
\begin{aligned} r_{k}^{T} r_{i} &=0, \quad \forall i=0, \cdots, k-1 \\ \operatorname{span}\left\{r_{0}, r_{1}, \cdots, r_{k}\right\} &=\operatorname{span}\left\{r_{0}, A r_{0}, \cdots, A^{k} r_{0}\right\} \\ \operatorname{span}\left\{p_{0}, p_{1}, \cdots, p_{k}\right\} &=\operatorname{span}\left\{r_{0}, A r_{0}, \cdots, A^{k} r_{0}\right\} \\ p_{k}^{T} A p_{i} &=0, \quad \forall i=0,1, \cdots, k-1 . \end{aligned}
rkTrispan{r0,r1,⋯,rk}span{p0,p1,⋯,pk}pkTApi=0,∀i=0,⋯,k−1=span{r0,Ar0,⋯,Akr0}=span{r0,Ar0,⋯,Akr0}=0,∀i=0,1,⋯,k−1.
通过一些简单的推导,替换掉 CG 算法中的一些表达,就得到了如下的 CG 方法的更加经济的实用形式,
收敛率
定义条件数:
κ
(
A
)
=
∥
A
∥
2
∥
A
−
1
∥
2
=
λ
n
λ
1
\kappa(A)=\|A\|_{2}\left\|A^{-1}\right\|_{2}=\frac{\lambda_{n}}{\lambda_{1}}
κ(A)=∥A∥2∥
∥A−1∥
∥2=λ1λn
那么,CG 的收敛率可以表达为:
∥
x
k
−
x
∗
∥
A
≤
2
(
κ
(
A
)
−
1
κ
(
A
)
+
1
)
k
∥
x
0
−
x
∗
∥
A
\left\|x_{k}-x^{*}\right\|_{A} \leq 2\left(\frac{\sqrt{\kappa(A)}-1}{\sqrt{\kappa(A)}+1}\right)^{k}\left\|x_{0}-x^{*}\right\|_{A}
∥xk−x∗∥A≤2(κ(A)+1κ(A)−1)k∥x0−x∗∥A
由表达式可以看出,当 A A A 条件数很大的时候,前面的系数趋近于 1,收敛速度无法保证。
预条件
所谓的预条件,就是希望对矩阵 A A A 做一个改造,改进特征值分布,让它的条件数小一些。
具体地,引入一个非奇异矩阵
C
C
C,做变量替换,
x
^
=
C
x
.
\hat{x}=C x .
x^=Cx.
二次问题就变为了,
ϕ
^
(
x
^
)
=
1
2
x
^
T
(
C
−
T
A
C
−
1
)
−
1
x
^
−
(
C
−
T
b
)
T
x
^
\hat{\phi}(\hat{x})=\frac{1}{2} \hat{x}^{T}\left(C^{-T} A C^{-1}\right)^{-1} \hat{x}-\left(C^{-T} b\right)^{T} \hat{x}
ϕ^(x^)=21x^T(C−TAC−1)−1x^−(C−Tb)Tx^
其对应的线性系统是,
(
C
−
T
A
C
−
1
)
x
^
=
C
−
T
b
\left(C^{-T} A C^{-1}\right) \hat{x}=C^{-T} b
(C−TAC−1)x^=C−Tb
我们要做的,就是找一个逆比较好求的
C
C
C,使得
C
−
T
A
C
−
1
C^{-T} A C^{-1}
C−TAC−1 特征值分布更集中。落实到实用算法上,得到:
注意到,这里没有显式用到
C
C
C,而是用到了
M
=
C
T
C
M = C^TC
M=CTC
性质中的残差的正交性表达也发生了改变,
r
i
T
M
−
1
r
j
=
0
for all
i
≠
j
r_{i}^{T} M^{-1} r_{j}=0 \text { for all } i \neq j
riTM−1rj=0 for all i=j
非线性共轭梯度法
求解非线性极小化问题:
min
f
(
x
)
\min f(x)
minf(x)
f f f 此时是非线性函数。
FR 方法
相对于共轭梯度法,我们做两点改动:
-
对于步长 α k \alpha_k αk,我们需要采取一种线搜索方法沿着 p k p_k pk 去逼近非线性目标函数 f f f 的极小。(满足所谓的强 wolfe 条件的步长)
-
残差 r r r 原来是线性 CG 方法的梯度,现在需要用 f f f 的梯度来替代它。
那么我们就得到了第一个非线性共轭梯度法,它是 Fletcher 和 Reeves 在 20 世纪 60 年代搞的。
对于 FR 方法,如果某步的方向不太好或者步长太小,那么下一步的方向和步长也会很糟糕。
其他非线性 CG
除了 PR 方法,我们选取不同的组合系数 β \beta β,就能得到不同的非线性 CG 方法。
PR 方法:
β
k
+
1
P
R
=
∇
f
k
+
1
T
(
∇
f
k
+
1
−
∇
f
k
)
∥
∇
f
k
∥
2
.
\beta_{k+1}^{P R}=\frac{\nabla f_{k+1}^{T}\left(\nabla f_{k+1}-\nabla f_{k}\right)}{\left\|\nabla f_{k}\right\|^{2}} .
βk+1PR=∥∇fk∥2∇fk+1T(∇fk+1−∇fk).
HS 方法:
β
k
+
1
H
S
=
∇
f
k
+
1
T
(
∇
f
k
+
1
−
∇
f
k
)
(
∇
f
k
+
1
−
∇
f
k
)
T
p
k
\beta_{k+1}^{H S}=\frac{\nabla f_{k+1}^{T}\left(\nabla f_{k+1}-\nabla f_{k}\right)}{\left(\nabla f_{k+1}-\nabla f_{k}\right)^{T} p_{k}}
βk+1HS=(∇fk+1−∇fk)Tpk∇fk+1T(∇fk+1−∇fk)
DY 方法:
β
k
+
1
D
Y
=
∇
f
k
+
1
T
∇
f
k
+
1
(
∇
f
k
+
1
−
∇
f
k
)
T
p
k
\beta_{k+1}^{D Y}=\frac{\nabla f_{k+1}^{T} \nabla f_{k+1}}{\left(\nabla f_{k+1}-\nabla f_{k}\right)^{T} p_{k}}
βk+1DY=(∇fk+1−∇fk)Tpk∇fk+1T∇fk+1
容易观察到,这四种方法无非是两个分子和两个分母的四种组合。
我们指出以下几点:
- DY 方法是我们所的戴彧虹和袁亚湘老师提出的。
- 对于 f f f 是强凸的二次问题,若采用精确想搜索,那么 PR-CG 和 HS-CG 是一个东西。
- 数值实验表明,PR 更鲁棒更有效。
- PR 方法其实就是在 FR 的基础上,当遇到前后两步梯度变化比较小的坏条件的时候,重新开始梯度下降的 “重启动” 方法。
- PR 方法可能不收敛。
PR+ 方法
若要保证
p
k
p_k
pk 是下降方向,我们只需要为 PR 的
β
\beta
β 进行微调:
β
k
+
1
+
=
max
{
β
k
+
1
P
R
,
0
}
\beta_{k+1}^{+}=\max \left\{\beta_{k+1}^{P R}, 0\right\}
βk+1+=max{βk+1PR,0}
称之为 PR+ 方法。
重启动
一个重启动的方式是,每迭代 n n n 步,就设置 β k = 0 \beta_{k}=0 βk=0,即取迭代方向为最速下降方向。重启动能抹掉一些旧的信息。但是这种重启动,没有什么实际的意义,只能说是一种理论的贡献。因为大部分情况下 n n n 很大,可能不需要迭代多少个 n n n 步,差不多就达到了比较好的逼近解。
另外一个重新启动是基于前后两步的梯度不正交的考虑,即当遇到
∣
∇
f
k
T
∇
f
k
−
1
∣
∥
∇
f
k
∥
2
≥
0.1
\frac{\left|\nabla f_{k}^{T} \nabla f_{k-1}\right|}{\left\|\nabla f_{k}\right\|^{2}} \geq 0.1
∥∇fk∥2∣
∣∇fkT∇fk−1∣
∣≥0.1
我们进行一个重启动。