[工程优化]共轭方向法(Conjugate direction method)的共轭梯度法(Conjugate gradient method)实现【附python代码】


引用

Wikipeidia:Conjugate gradient method

Preliminaries

梯度与梯度下降

  1. 对于一维函数 f ( x ) f(x) f(x),其导数定义为:
    f ′ ( x ) = lim ⁡ Δ x → 0 f ( x 0 + Δ x ) − f ( x 0 ) Δ x f'(x)=\lim \limits_{\Delta x \rightarrow 0} \frac{f(x_0+\small{\Delta} x)-f(x_0)}{\small{\Delta} x} f(x)=Δx0limΔxf(x0+Δx)f(x0)
  2. 对于多维函数 f ( x 1 , . . . , x n ) f(x_1,...,x_n) f(x1,...,xn),对 x i x_i xi求导数 d f d x i \frac{df}{dx_i} dxidf,将其记为偏导数 ∂ f ∂ x I \frac{\partial f}{\partial x_I} xIf。特别的,记录梯度 ▽ f ( x ) \triangledown f(x) f(x)或简记为 ▽ f \triangledown f f为对 x i x_i xi求偏导后的列向量:
    g ( x ) = ▽ f ( x ) = ( ∂ f ∂ x 1 , ∂ f ∂ x 2 , . . . , ∂ f ∂ x 1 ) T g(x)=\triangledown f(x)=(\frac{\partial f}{\partial x_1}, \frac{\partial f}{\partial x_2},..., \frac{\partial f}{\partial x_1})^T g(x)=f(x)=(x1f,x2f,...,x1f)T
  3. 梯度下降

参见:[工程优化]梯度下降(Gradient descent):SGD/BGD

矩阵(半)正定

设有 x T A x x^TAx xTAx ∀ x = ( x 1 , ⋯   , x n ) T \forall x=(x_1,\cdots,x_n)^T x=(x1,,xn)T都有 x T A x > 0 x^TAx>0 xTAx>0,则称矩阵 A A A正定矩阵;若都有 x T A x ≥ 0 x^TAx\ge0 xTAx0,则称其为半正定矩阵

同时,若一个矩阵 A A A正定,则 A A A的特征值均为正数(半正定则为大于零的数),一定存在逆矩阵 A − 1 A^{-1} A1

线性方程组

设有对称、正定矩阵 A ∈ R n × n A \in \R^{n \times n} ARn×n和非零列向量 x , b ∈ R n x,b \in \R^n x,bRn满足 A x = b Ax=b Ax=b,称其为一个线性方程组(System of Linear Equations)。将其唯一解记为 x ∗ x^* x

正交向量

若非零列向量 a , b ∈ R n a,b \in \R^n a,bRn满足 a T b = 0 a^Tb=0 aTb=0,则将这两个向量互为正交向量。当其正交,则其在空间上互为垂直的两个向量。

Tip:亦有文献将其称为直交

共轭方向及共轭方向组

  1. 如果对于非零列向量 u , v ∈ R n u,v \in \R^n u,vRn存在 n × n n \times n n×n 对称、正定矩阵 A A A使得:
    u T A v = 0 u^TAv=0 uTAv=0则称 u , v u,v u,v为关于 A A A共轭方向

众所周知,矩阵可以看作是一种运动、映射,当 u , v u,v u,v关于 A A A共轭时,实际上是值当 u , v u,v u,v经过对称正定矩阵 A A A的运动之后在空间上互相垂直(正交)。
特别的,当 A A A取得单位阵时,实际上下文提到的二阶拟合函数就是一个圆球,共轭方向为过圆心且互相垂直的若干组直径。

  1. 设对于非零向量 p i , p j ∈ p ^ = { p 1 , ⋯   , p n } p_i ,p_j\in \hat p= \{ p_1, \cdots, p_n \} pipjp^={ p1,,pn} p i , p j ∈ R n p_i,p_j \in \R^n pi,pjRn,若 p i T A p j = 0 p_i^TAp_j=0 piTApj=0 ( i = j̸ ) (i =\not j) (i=j),则称 p 1 , ⋯   , p n p_1,\cdots,p_n p1,,pn是关于 A A A相互共轭的一组共轭方向组

引理:非0共轭方向组显然线性无关。(可用反证法证明)
证明:设有一组标量 α i \alpha_i αi使得 ∑ α i p i = 0 \sum \alpha_ip_i=0 αipi=0,则 ∀ k , p k ∈ p ^ = { p 1 , ⋯   , p n } \forall k,p_k \in \hat p=\{ p_1, \cdots, p_n\} k,pkp^={ p1,,pn},有:
p k T A ∑ α i p i = 0 α k p k T A p k = 0 \begin{aligned} p_k^TA\sum \alpha_ip_i&=0 \\ \alpha_k p_k^TAp_k&=0 \end{aligned} pkTAαipiαkpkTApk=0=0

∵ 矩阵 A A A正定有 p k T A p k > 0 p_k^TAp_k>0 pkTApk>0 ∴ α k = 0 ∴\alpha_k=0 αk=0

牛顿法(Newton’s method)

牛顿法是对二阶泛函的近似求解。

Ref:[工程优化]牛顿法的缺陷及拟牛顿法(Newton’s method)

由于共轭方向法同样采用了用二次泛函拟合函数极值微分点的做法,因此理解牛顿法对理解共轭方向法及其有效性有直接帮助。

换句话说,一般情况下,在极值点附近,原目标函数可以近似于一个二次函数。当我们对二次函数建立一个有效的模型,那么,它对非二次模型也应当是有效的。(ps:要注意,不是所有函数都可以很好地用二次函数拟合。)

>返回目录


共轭方向法

共轭方向法是一种介于梯度下降法和牛顿法之间的算法,它不像牛顿法一样需要二阶导数,又避免了梯度下降中的锯齿现象。

从几何出发说明共轭方向法的有效性

注:这一小节偏向白话,是比较形而上的理解内容。可以选择性阅读。

考虑 n n n维空间上的二次函数 ϕ ( x ) \phi(x) ϕ(x),它应当是一个超椭球体:
ϕ ( x ) ≈ f ( x ) = 1 2 x T A x + b T x + c ▽ ϕ ( x ) = A x + b T ▽ 2 ϕ ( x ) = A \begin{aligned} \phi(x) \approx f(x)&=\frac{1}{2}x^TAx+b^Tx+c \\ \triangledown \phi(x)&=Ax+b^T \\ \triangledown^2 \phi(x)&=A \end{aligned} ϕ(x)f(x)ϕ(x)2ϕ(x)=21xTAx+bTx+c=Ax+bT=A

其中,

解释:def conjugate_gradient(fun, grad, x0, iterations, tol): """ Minimization of scalar function of one or more variables using the conjugate gradient algorithm. Parameters ---------- fun : function Objective function. grad : function Gradient function of objective function. x0 : numpy.array, size=9 Initial value of the parameters to be estimated. iterations : int Maximum iterations of optimization algorithms. tol : float Tolerance of optimization algorithms. Returns ------- xk : numpy.array, size=9 Parameters wstimated by optimization algorithms. fval : float Objective function value at xk. grad_val : float Gradient value of objective function at xk. grad_log : numpy.array The record of gradient of objective function of each iteration. """ fval = None grad_val = None x_log = [] y_log = [] grad_log = [] x0 = asarray(x0).flatten() # iterations = len(x0) * 200 old_fval = fun(x0) gfk = grad(x0) k = 0 xk = x0 # Sets the initial step guess to dx ~ 1 old_old_fval = old_fval + np.linalg.norm(gfk) / 2 pk = -gfk x_log = np.append(x_log, xk.T) y_log = np.append(y_log, fun(xk)) grad_log = np.append(grad_log, np.linalg.norm(xk - x_log[-1:])) gnorm = np.amax(np.abs(gfk)) sigma_3 = 0.01 while (gnorm > tol) and (k < iterations): deltak = np.dot(gfk, gfk) cached_step = [None] def polak_ribiere_powell_step(alpha, gfkp1=None): xkp1 = xk + alpha * pk if gfkp1 is None: gfkp1 = grad(xkp1) yk = gfkp1 - gfk beta_k = max(0, np.dot(yk, gfkp1) / deltak) pkp1 = -gfkp1 + beta_k * pk gnorm = np.amax(np.abs(gfkp1)) return (alpha, xkp1, pkp1, gfkp1, gnorm) def descent_condition(alpha, xkp1, fp1, gfkp1): # Polak-Ribiere+ needs an explicit check of a sufficient # descent condition, which is not guaranteed by strong Wolfe. # # See Gilbert & Nocedal, "Global convergence properties of # conjugate gradient methods for optimization", # SIAM J. Optimization 2, 21 (1992). cached_step[:] = polak_ribiere_powell_step(alpha, gfkp1) alpha, xk, pk, gfk, gnorm = cached_step # Accept step if it leads to convergence. if gnorm <= tol: return True # Accept step if sufficient descent condition applies. return np.dot(pk, gfk) <= -sigma_3 * np.dot(gfk, gfk) try: alpha_k, fc, gc, old_fval, old_old_fval, gfkp1 = \ _line_search_wolfe12(fun, grad, xk, pk, gfk, old_fval, old_old_fval, c2=0.4, amin=1e-100, amax=1e100, extra_condition=descent_condition) except _LineSearchError: break # Reuse already computed results if possible if alpha_k == cached_step[0]: alpha_k, xk, pk, gfk, gnorm = cached_step else: alpha_k, xk, pk, gfk, gnorm = polak_ribiere_powell_step(alpha_k, gfkp1) k += 1 grad_log = np.append(grad_log, np.linalg.norm(xk - x_log[-1:])) x_log = np.append(x_log, xk.T) y_log = np.append(y_log, fun(xk)) fval = old_fval grad_val = grad_log[-1] return xk, fval, grad_val, x_log, y_log, grad_log
最新发布
06-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值