共轭梯度法
最速下降法以及牛顿法都具有其自身的局限性。本文将要介绍的共轭梯度法是介于最速下降法与牛顿法之间的一种无约束优化算法,它具有超线性的收敛速度,而且算法结构简单,容易编程实现。此外,根最速下降法相类似,共轭梯度法只用到了目标函数及其梯度值,避免了二阶导数的计算,从而降低了计算量和存储量,因此它是求解无约束优化问题的一种比较有效而使用的算法。
一、共轭方向发
共轭方向法的基本思想是在求解n nn维正定二次目标函数极小点时产生一组共轭方向作为搜索方向,在线搜索条件下算法之多迭代n nn步即能求得极小点。京故宫适当修正后共轭方向法可以推广到求解一般非二次目标函数情形。下面先介绍共轭方向的概念。
定义1:设G GG是n nn阶对称正定矩阵,若n nn维向量组d 1 , d 2 , ⋯ , d m ( m ≤ n ) 满 足 d_1,d_2,\cdots,d_m(m\le n)满足d1,d2,⋯,dm(m≤n)满足d i T G d j = 0 , i ≠ j d_i^TGd_j=0,i\neq jdiTGdj=0,i=j,则乘d 1 , d 2 , ⋯ , d m d_1,d_2,\cdots,d_md1,d2,⋯,dm是G GG共轭的。
显然,向量组的共轭是正交的推广,即当G = I G=IG=I(单位阵)时,上述定义变成了向量组正交的定义。此外,不难证明,对称正定矩阵G GG的共轭向量组必然是线性无关的。
下面我们考虑求解正定二次目标函数极小点的共轭方向法。设
min f ( x ) = 1 2 x T G x + b T x + c (1) \min f(x)=\frac{1}{2}x^TGx+b^Tx+c\tag{1}minf(x)=21xTGx+bTx+c(1)
其中G GG是n nn阶对称正定阵,b bb为n nn为常向量,c cc为常数。我们有下面的算法:
算法1:共轭方向法
0. 给定迭代精度0 ≤ ϵ ≤ 1 0\le\epsilon\le 10≤ϵ≤1和初始点x 0 x_0x0。计算g 0 = ∇ f ( x 0 ) g_0=\nabla f(x_0)g0=∇f(x0)。选取初始方向d 0 d_0d0使得d 0 T g 0 < 0 d_0^Tg_0\lt 0d0Tg0<0。令k = 0 k=0k=0.
- 若∣ ∣ g k ∣ ∣ ≤ ϵ ||g_k||\le\epsilon∣∣gk∣∣≤ϵ,停算,输出x ∗ ≈ x k x^*\approx x_kx∗≈xk.
- 利用线搜索方法确定步长α k \alpha_kαk
- 令x k + 1 = x k + α k d k x_{k+1}=x_k+\alpha_kd_kxk+1=xk+αkdk,并计算g k + 1 = ∇ f ( x k + 1 ) g_{k+1}=\nabla f(x_{k+1})gk+1=∇f(xk+1).
- 选取d k + 1 d_{k+1}dk+1满足下降性和共轭性条件:d k + 1 T g k + 1 < 0 , d k + 1 T G d i = 0 , , i = 0 , 1 , ⋯ , k d_{k+1}^Tg_{k+1}\lt 0,d_{k+1}^TGd_i=0,\quad,i=0,1,\cdots,kdk+1Tgk+1<0,dk+1TGdi=0,,i=0,1,⋯,k.
- 令k = k + 1 k=k+1k=k+1,转步1
该算法的收敛性证明略过,如果感兴趣,可以去查找相应的数值优化专著。这里直接给出结论,在精确线搜索下,算法1求解正定二次目标函数极小化问题,之多在n nn步内即可求得其唯一极小点。这种能在有限步内求得二次函数极小点的性质通常称为二次终止性。
二、共轭梯度法
共轭梯度法是在每一步迭代利用当前点处的最速下降方向来生成关于凸二次函数f ff的海塞阵G GG的共轭方向,并建立求f ff在R n \mathbb{R^n}Rn上的极小点的方法。这一方法最早是由Hesteness和Stiefel于1952年为求解正定线性方程组而提出来的,后经Fletcher等人研究并应用于无约束优化问题取得了丰富的成果,共轭梯度法也因此成为当前求解无约束优化问题的重要算法类。
设函数如(1)式所定义,则f ff的梯度和海塞矩阵为
g ( x ) = ∇ f ( x ) = G x + b , G ( x ) = ∇ 2 f ( x ) = G (2) g(x)=\nabla f(x)=Gx+b,\quad G(x)=\nabla^2 f(x)=G\tag{2}g(x)=∇f(x)=Gx+b,G(x)=∇2f(x)=G(2)
下面我们讨论算法(1)中共轭方向的构造。我们取初始方向d 0 d_0d0为初始点x 0 x_0x0处的负梯度方向,即
d 0 = − ∇ f ( x 0 ) = − g 0 (3) d_0=-\nabla f(x_0)=-g_0 \tag{3}d0=−∇f(x0)=−g0(3)
从x 0 x_0x0出发沿d 0 d_0d0方向进行线搜索得到步长α 0 \alpha_0α0,令
x 1 = x 0 + α 0 d 0 x_1=x_0+\alpha_0d_0x1=x0+α0d0
其中α 0 \alpha_0α0满足条件
∇ f ( x 1 ) T d 0 = g 1 T d 0 (4) \nabla f(x_1)^Td_0=g_1^Td_0 \tag{4}∇f(x1)Td0=g1Td0(4)
在x 1 x_1x1处,用f ff在x 1 x_1x1的负梯度方向− g 1 -g_1−g1与d 0 d_0d0的组合来生成d 1 d_1d1,即
d 1 = − g 1 + β 0 d 0 (5) d_1=-g_1+\beta_0d_0 \tag{5}d1=−g1+β0d0(5)
然后选取系数β 0 \beta_0β0使d 1 d_1d1与d 0 d_0d0关于G共轭,即令
d 1 T G d 0 = 0 (6) d_1^TGd_0 = 0 \tag{6}d1TGd0=0(6)
来确定β 0 \beta_0β0,将(6)代入(5)得
β 0 = g 1 T G d 0 d 0 T G d 0 (7) \beta_0 = \frac{g_1^TGd_0}{d_0^TGd_0} \tag{7}β0=d0TGd0g1TGd0(7)
由(2)得
g 1 − g 0 = G ( x 1 − x 0 ) = α 0 G d 0 (8) g_1-g_0=G(x_1-x_0)=\alpha_0Gd_0 \tag{8}g1−g0=G(x1−x0)=α0Gd0(8)
故由(3)~(5)可得
g 2 T g 0 = 0 , g 2 T g 1 = 0 , d 0 T g 0 = − g 0 T g 0 , d 1 T g 1 = − g 1 T g 1 g_2^Tg_0=0,g_2^Tg_1=0,d_0^Tg_0=-g_0^Tg_0,d_1^Tg_1=-g_1^Tg_1g2Tg0=0,g2Tg1=0,d0Tg0=−g0Tg0,d1Tg1=−g1Tg1
现假设已得到互相共轭得搜索方向d 1 , d 2 , ⋯ , d k − 1 d_1,d_2,\cdots,d_{k-1}d1,d2,⋯,dk−1,精确线搜索得到得步长为α 0 , α 1 , ⋯ , α k − 1 \alpha_0,\alpha_1,\cdots,\alpha_{k-1}α0,α1,⋯,αk−1,且满足
{ d k − 1 T G d i = 0 , i = 0 , 1 , ⋯ , k − 2 , d i T g i = − g i T g i , i = 0 , 1 , ⋯ , k − 1 , g k T g i = 0 , g k T d i = 0 , i = 0 , 1 , ⋯ , k − 1. (9) \left\{ \begin{array}{rcl} d_{k-1}^TGd_i=0, &i=0,1,\cdots,k-2,\\ d_i^Tg_i=-g_i^Tg_i,&i=0,1,\cdots,k-1,\\ g_k^Tg_i=0,g_k^Td_i=0,&i=0,1,\cdots,k-1. \end{array} \right. \tag{9}⎩⎨⎧dk−1TGdi=0,diTgi=−giTgi,gkTgi=0,gkTdi=0,i=0,1,⋯,k−2,i=0,1,⋯,k−1,i=0,1,⋯,k−1.(9)
现令
d k = − g k + β k − 1 d k − 1 + ∑ i = 0 k − 1 β k ( i ) d i (10) d_k=-g_k+\beta_{k-1}d_{k-1}+\sum_{i=0}^{k-1}\beta_{k}^{(i)}d_i\tag{10}dk=−gk+βk−1dk−1+i=0∑k−1βk(i)di(10)
其中β k − 1 , β k ( i ) ( i = 0 , 1 , ⋯ , k − 2 ) \beta_{k-1},\beta_k^{(i)}(i=0,1,\cdots,k-2)βk−1,βk(i)(i=0,1,⋯,k−2)得选择要满足
d k T G d i = 0 , i = 0 , 1 , ⋯ , k − 1 (11) d_k^TGd_i=0,i=0,1,\cdots,k-1\tag{11}dkTGdi=0,i=0,1,⋯,k−1(11)
用d i T G ( i = 0 , 1 , ⋯ , k − 1 ) d_i^TG(i=0,1,\cdots,k-1)diTG(i=0,1,⋯,k−1)左乘(10)得
β k − 1 = g k T G d k − 1 d k − 1 T G d k − 1 , β k ( 1 ) = g k T G d i d i T G d i , i = 0 , 1 , ⋯ , k − 2 (12) \beta_{k-1}=\frac{g_k^TGd_{k-1}}{d_{k-1}^TGd_{k-1}},\beta_k^{(1)}=\frac{g_k^TGd_i}{d_i^TGd_i},i=0,1,\cdots,k-2\tag{12}βk−1=dk−1TGdk−1gkTGdk−1,βk(1)=diTGdigkTGdi,i=0,1,⋯,k−2(12)
类似于(8),我们有
g i + 1 − g i = G ( x i + 1 − x i ) = α i G d i , i = 0 , 1 , ⋯ , k − 1 g_{i+1}-g_i=G(x_{i+1}-x_i)=\alpha_iGd_i,i=0,1,\cdots,k-1gi+1−gi=G(xi+1−xi)=αiGdi,i=0,1,⋯,k−1
及
α i G d i = g i + 1 − g i , i = 0 , 1 , ⋯ , k − 1 (13) \alpha_iGd_i=g_{i+1}-g_i,i=0,1,\cdots,k-1\tag{13}αiGdi=gi+1−gi,i=0,1,⋯,k−1(13)
于是由归纳法假设(9)可得
β k ( i ) = g k T G d i d i T G d i = g k T ( g i + 1 − g i ) d i T ( g i + 1 − g i ) = 0 , i = 0 , 1 , ⋯ , k − 2. \beta_k^{(i)}=\frac{g_k^TGd_i}{d_i^TGd_i}=\frac{g_k^T(g_{i+1}-g_i)}{d_i^T(g_{i+1}-g_i)}=0,i=0,1,\cdots,k-2.βk(i)=diTGdigkTGdi=diT(gi+1−gi)gkT(gi+1−gi)=0,i=0,1,⋯,k−2.
于是,第k步得搜索方向为
d k = − g k + β k − 1 d k − 1 , (14) d_k=-g_k+\beta_{k-1}d_{k-1},\tag{14}dk=−gk+βk−1dk−1,(14)
其中β k − 1 \beta_{k-1}βk−1由(12)确定,即
β k − 1 = g k T G d k − 1 d k − 1 T G d k − 1 (15) \beta_{k-1}=\frac{g_k^TGd_{k-1}}{d_{k-1}^TGd_{k-1}}\tag{15}βk−1=dk−1TGdk−1gkTGdk−1(15)
同时有d k T g k = − g k T g k d_k^Tg_k=-g_k^Tg_kdkTgk=−gkTgk。这样确定了一组由负梯度方向形成得共轭方向,而把沿着这组方向进行迭代得方向称为共轭梯度法。其证明过程这里略过。
下面我们给出共轭梯度法求解无约束优化问题(1)极小点得算法步骤
算法2:共轭梯度法
0. 给定迭代精度0 ≤ ϵ < 1 0\le\epsilon\lt 10≤ϵ<1和初始点x 0 x_0x0。计算g 0 = ∇ f ( x 0 ) g_0=\nabla f(x_0)g0=∇f(x0)。令k = 0 k=0k=0
- 若∣ ∣ g k ∣ ∣ ≤ ϵ ||g_k||\le\epsilon∣∣gk∣∣≤ϵ,停算,输出x ) ≈ x k x^)\approx x_kx)≈xk
- 计算搜索方向d k d_kdk:
KaTeX parse error: Unknown column alignment: s at position 29: …\begin{array}{ls̲c} -g_k,&k=0,\\…
其中当k ≥ 1 k\ge 1k≥1时,β k − 1 \beta_{k-1}βk−1由(15)确定 - 利用线搜索方法确定搜索步长α k \alpha_kαk
- 令x k + 1 = x k + α k d k x_{k+1}=x_k+\alpha_kd_kxk+1=xk+αkdk,并计算g k + 1 = ∇ f ( x k + 1 ) g_{k+1}=\nabla f(x_{k+1})gk+1=∇f(xk+1)
- 令k = k + 1 k=k+1k=k+1,转步1
计算公式(15)是由Fletcher和Reeves给出得,故称之为FR公式,算法2也称之为FR共轭梯度法。除FR工诗外,尚有下列著名公式:
β k = g k + 1 T g k + 1 − d k T g k , ( D i x o n 公 式 ) β k = g k + 1 T g k + 1 d k T ( g k + 1 − g k ) , ( D a i − Y u a n 公 式 ) β k = g k + 1 T ( g k + 1 − g k ) d k T ( g k + 1 − g k ) , ( C r o w d e r − W o l f e 公 式 ) β k = g k + 1 T ( g k + 1 − g k ) g k T g k , ( P o l a k , R i b i e r e , P l o y a k , P R P 公 式 ) \begin{aligned} \beta_k&=\frac{g_{k+1}^Tg_{k+1}}{-d_k^Tg_k}, (Dixon公式) \\ \beta_k&=\frac{g_{k+1}^Tg_{k+1}}{d_k^T(g_{k+1}-g_k)}, (Dai-Yuan公式) \\ \beta_k&=\frac{g_{k+1}^T(g_{k+1}-g_k)}{d_k^T(g_{k+1}-g_k)}, (Crowder-Wolfe公式) \\ \beta_k&=\frac{g_{k+1}^T(g_{k+1}-g_k)}{g_k^Tg_k}, (Polak,Ribiere,Ployak,PRP公式) \\ \end{aligned}βkβkβkβk=−dkTgkgk+1Tgk+1,(Dixon公式)=dkT(gk+1−gk)gk+1Tgk+1,(Dai−Yuan公式)=dkT(gk+1−gk)gk+1T(gk+1−gk),(Crowder−Wolfe公式)=gkTgkgk+1T(gk+1−gk),(Polak,Ribiere,Ployak,PRP公式)
三、共轭梯度法得matlab实现
在共轭梯度法得实际使用中,通常在迭代n步或n+1步之后,重新选取负梯度方向作为搜索方向,我们称之为再开始共轭梯度法。这是因为对于一般非二次函数而言,n步迭代后共轭梯度法产生得搜索方向往往不再具有共轭性。而对于大规模问题,常常每m ( m < n 或 m ≪ n ) m (m<n或m\ll n)m(m<n或m≪n)步就进行再开始。此外,当搜索方向不是下降方向时,也插入负梯度方向所作为搜索方向。
这里给出基于Armijo-rule非精确线搜索得再开始FR共轭梯度法得matlab程序。
function [fmin, xmin] = frcg(fun, gfun, x0, epsilon)
maxk = 5000;
rho = 0.6;
sigma = 0.4;
k = 0;
n = length(x0);
while k < maxk
g = feval(gfun, x0);
itern = k - (n+1) * floor(k / (n + 1));
itern = itern + 1;
if (itern == 1)
d = -g;
else
beta = (g' * g) / (g0' * g0);
d = -g + beta * d0; gd = g' * d;
if (gd >= 0.0)
d = -g;
end
end
if (norm(g) < epsilon), break; end
m = 0; mk = 0;
while (m < 20) % armijo-rule
if (feval(fun, x0 + rho^m*d) < feval(fun, x0) + sigma * rho^m*g'*d)
mk = m; break;
end
m = m + 1;
end
x0 = x0 + rho^mk*d;
val = feval(fun, x0);
fprintf('kIter = %d, fmin = %f\n', k, val);
g0 = g; d0 = d;
k = k+1;
end
x = x0;
val = feval(fun, x);
xmin = x;
fmin = val;
end
利用程序求解无约束优化问题
min x ∈ R 2 f ( x ) = 100 ( x 1 2 − x 2 ) 2 + ( x 1 − 1 ) 2 \min_{x\in\mathbb{R^2}}\quad f(x)=100(x_1^2-x_2)^2+(x_1-1)^2x∈R2minf(x)=100(x12−x2)2+(x1−1)2
该问题由精确解x ∗ = ( 1 , 1 ) T , f ( x ∗ ) = 0 x^*=(1,1)^T,f(x^*)=0x∗=(1,1)T,f(x∗)=0
求解main函数
x0 = [0, 0]';
epsilon = 1e-4;
[fmin, xmin] = frcg('func', 'gfunc', x0, epsilon);
fprintf('frcg: fmin = %f, xmin = (%f, %f)\n', fmin, xmin(1), xmin(2));
[x, f] = fminsearch('func', x0);
fprintf('build-in search: fmin = %f, xmin = (%f, %f)\n', f, x(1), x(2));
函数定义以及梯度求解
function f = func(x)
f = 100 * (x(1)^2 - x(2))^2 + (x(1) - 1)^2;
end
function grad = gfunc(x)
grad = [400 * x(1) * (x(1)^2-x(2))+2*(x(1)-1); ...
-200 * (x(1)^2-x(2))];
end
求解结果为:
frcg: fmin = 0.000000, xmin = (0.999921, 0.999841)
build-in search: fmin = 0.000000, xmin = (1.000004, 1.000011)