最优化方法Python计算:秩1拟牛顿法

对二次型函数 f ( x ) = 1 2 x ⊤ H x − x ⊤ b f(\boldsymbol{x})=\frac{1}{2}\boldsymbol{x}^\top\boldsymbol{Hx}-\boldsymbol{x}^\top\boldsymbol{b} f(x)=21xHxxb,其中 H \boldsymbol{H} H对称正定。 f ( x ) f(\boldsymbol{x}) f(x)的梯度 g ( x ) = ∇ f ( x ) = H x − b \boldsymbol{g}(\boldsymbol{x})=\nabla f(\boldsymbol{x})=\boldsymbol{Hx}-\boldsymbol{b} g(x)=f(x)=Hxb,Hesse阵 ∇ 2 f ( x ) = H \nabla^2f(\boldsymbol{x})=\boldsymbol{H} 2f(x)=H。取定初始点 x 1 \boldsymbol{x}_1 x1,牛顿法的迭代式为 x k + 1 = x k − H − 1 g k \boldsymbol{x}_{k+1}=\boldsymbol{x}_k-\boldsymbol{H}^{-1}\boldsymbol{g}_k xk+1=xkH1gk,其中 g k = g ( x k ) \boldsymbol{g}_k=\boldsymbol{g}(\boldsymbol{x}_k) gk=g(xk)。由 g k = H x k − b \boldsymbol{g}_k=\boldsymbol{Hx}_k-\boldsymbol{b} gk=Hxkb,有
g k + 1 − g k = H x k + 1 − H x k = H ( x k + 1 − x k ) \boldsymbol{g}_{k+1}-\boldsymbol{g}_k=\boldsymbol{Hx}_{k+1}-\boldsymbol{Hx}_k=\boldsymbol{H}(\boldsymbol{x}_{k+1}-\boldsymbol{x}_k) gk+1gk=Hxk+1Hxk=H(xk+1xk)

H − 1 ( g k + 1 − g k ) = x k + 1 − x k . \boldsymbol{H}^{-1}(\boldsymbol{g}_{k+1}-\boldsymbol{g}_k)=\boldsymbol{x}_{k+1}-\boldsymbol{x}_k. H1(gk+1gk)=xk+1xk.
若记
{ Δ x k = x k + 1 − x k Δ g k = g k + 1 − g k \begin{cases} \Delta\boldsymbol{x}_k=\boldsymbol{x}_{k+1}-\boldsymbol{x}_k\\ \Delta\boldsymbol{g}_k=\boldsymbol{g}_{k+1}-\boldsymbol{g}_k \end{cases} {Δxk=xk+1xkΔgk=gk+1gk
则称
Δ g k = H Δ x \Delta\boldsymbol{g}_k=\boldsymbol{H}\Delta\boldsymbol{x} Δgk=HΔx

H − 1 Δ g k = Δ x k \boldsymbol{H}^{-1}\Delta\boldsymbol{g}_k=\Delta\boldsymbol{x}_k H1Δgk=Δxk
牛顿方程
牛顿法能正确工作的一个重要前提是初始点 x 1 \boldsymbol{x}_1 x1需与最优解点 x 0 \boldsymbol{x}_0 x0充分接近。因为这时迭代式 x k + 1 = x k − H k − 1 g k \boldsymbol{x}_{k+1}=\boldsymbol{x}_k-\boldsymbol{H}_k^{-1}\boldsymbol{g}_k xk+1=xkHk1gk可能使得 f ( x k + 1 ) f(\boldsymbol{x}_{k+1}) f(xk+1)未必小于 f ( x k ) f(\boldsymbol{x}_k) f(xk) k = 1 , 2 , ⋯ k=1,2,\cdots k=1,2,。这可以通过选取合理的步长 α k \alpha_k αk加以改善,即把迭代式改为
x k + 1 = x k − α k H k − 1 g k \boldsymbol{x}_{k+1}=\boldsymbol{x}_k-\alpha_k\boldsymbol{H}_k^{-1}\boldsymbol{g}_k xk+1=xkαkHk1gk
其中 g k = ∇ f ( x k ) \boldsymbol{g}_k=\nabla f(\boldsymbol{x}_k) gk=f(xk) H k = ∇ 2 f ( x k ) \boldsymbol{H}_k=\nabla^2f(\boldsymbol{x}_k) Hk=2f(xk)。选取合适的 α k \alpha_k αk,譬如, α k \alpha_k αk ϕ k ( α ) = f ( x k − α H k − 1 g k ) \phi_k(\alpha)=f(\boldsymbol{x}_k-\alpha\boldsymbol{H}_k^{-1}\boldsymbol{g}_k) ϕk(α)=f(xkαHk1gk)的最小值点,使得 f ( x k + 1 ) < f ( x k ) f(\boldsymbol{x}_{k+1})<f(\boldsymbol{x}_k) f(xk+1)<f(xk) k = 1 , 2 , ⋯ k=1,2,\cdots k=1,2,。另一方面,有如下事实
定理1 设函数 f ( x ) , x ∈ R n f(\boldsymbol{x}),\boldsymbol{x}\in\text{ℝ}^n f(x),xRn一阶连续可微, Q ∈ R n × n \boldsymbol{Q}\in\text{ℝ}^{n\times n} QRn×n Q ⊤ = Q \boldsymbol{Q}^\top=\boldsymbol{Q} Q=Q且正定。对 x k ∈ R n \boldsymbol{x}_k\in\text{ℝ}^n xkRn,若 g k = ∇ f ( x k ) ≠ o \boldsymbol{g}_k=\nabla f(\boldsymbol{x}_k)\not=\boldsymbol{o} gk=f(xk)=o,记 α k = arg ⁡ min ⁡ α > 0 f ( x k − α Q g k ) \alpha_k=\arg\min\limits_{\alpha>0}f(\boldsymbol{x}_k-\alpha\boldsymbol{Q}\boldsymbol{g}_k) αk=argα>0minf(xkαQgk) x k + 1 = x k − α k Q g k \boldsymbol{x}_{k+1}=\boldsymbol{x}_k-\alpha_k\boldsymbol{Q}\boldsymbol{g}_k xk+1=xkαkQgk。则
f ( x k + 1 ) < f ( x k ) . f(\boldsymbol{x}_{k+1})<f(\boldsymbol{x}_k). f(xk+1)<f(xk).
对于非二次型函数 f ( x ) f(\boldsymbol{x}) f(x)而言,其Hesse矩阵 H = ∇ 2 f ( x ) \boldsymbol{H}=\nabla^2f(\boldsymbol{x}) H=2f(x),将依赖于 x \boldsymbol{x} x。当 n n n很大时,在牛顿算法的迭代计算中更新 H k = ∇ 2 f ( x k ) \boldsymbol{H}_k=\nabla^2f(\boldsymbol{x}_k) Hk=2f(xk)会消耗大量资源。我们的目标是对迭代点 x k \boldsymbol{x}_k xk寻求 H k \boldsymbol{H}_k Hk的一个近似对称正定矩阵 Q k \boldsymbol{Q}_k Qk,使得在迭代中更新 Q k \boldsymbol{Q}_{k} Qk比更新 H k \boldsymbol{H}_{k} Hk更高效,且矩阵 Q k \boldsymbol{Q}_{k} Qk应满足牛顿方程 Q k − 1 Δ g k − 1 ≈ Δ x k − 1 \boldsymbol{Q}_{k}^{-1}\Delta\boldsymbol{g}_{k-1}\approx\Delta\boldsymbol{x}_{k-1} Qk1Δgk1Δxk1 g k − 1 ≈ Q k Δ x k − 1 \boldsymbol{g}_{k-1}\approx\boldsymbol{Q}_{k}\Delta\boldsymbol{x}_{k-1} gk1QkΔxk1。其中, Δ x k − 1 = x k − x k − 1 \Delta\boldsymbol{x}_{k-1}=\boldsymbol{x}_{k}-\boldsymbol{x}_{k-1} Δxk1=xkxk1 Δ g k − 1 = g k − g k − 1 \Delta\boldsymbol{g}_{k-1}=\boldsymbol{g}_{k}-\boldsymbol{g}_{k-1} Δgk1=gkgk1。这样改造牛顿法所得算法称为拟牛顿法
实现拟牛顿法最简单的是秩1法。
定理2 设目标函数 f ( x ) f(\boldsymbol{x}) f(x) x ∈ ∈ R n \boldsymbol{x}\in\in\text{ℝ}^n x∈∈Rn有最小值点 x 0 \boldsymbol{x}_0 x0且一阶连续可微。 k = 1 k=1 k=1时,令对称正定阵 Q 1 = I \boldsymbol{Q}_1=\boldsymbol{I} Q1=I。对 k > 1 k>1 k>1,令 Q k − 1 = Q k − 1 − 1 + E k − 1 \boldsymbol{Q}^{-1}_{k}=\boldsymbol{Q}^{-1}_{k-1}+\boldsymbol{E}_{k-1} Qk1=Qk11+Ek1,其中,
E k − 1 = ( Δ x k − 1 − Q k − 1 − 1 Δ g k − 1 ) ( Δ x k − 1 − Q k − 1 − 1 Δ g k − 1 ) ⊤ ( Δ x k − 1 − Q k − 1 − 1 Δ g k − 1 ) ⊤ Δ g k − 1 \boldsymbol{E}_{k-1}=\frac{(\Delta\boldsymbol{x}_{k-1}-\boldsymbol{Q}^{-1}_{k-1}\Delta\boldsymbol{g}_{k-1})(\Delta\boldsymbol{x}_{k-1}-\boldsymbol{Q}^{-1}_{k-1}\Delta\boldsymbol{g}_{k-1})^\top}{(\Delta\boldsymbol{x}_{k-1}-\boldsymbol{Q}^{-1}_{k-1}\Delta\boldsymbol{g}_{k-1})^\top\Delta\boldsymbol{g}_{k-1}} Ek1=(Δxk1Qk11Δgk1)Δgk1(Δxk1Qk11Δgk1)(Δxk1Qk11Δgk1)
则迭代式
Q k − 1 = Q k − 1 − 1 + E k − 1 \boldsymbol{Q}^{-1}_k=\boldsymbol{Q}^{-1}_{k-1}+\boldsymbol{E}_{k-1} Qk1=Qk11+Ek1
满足牛顿方程 Q k − 1 Δ g k − 1 ≈ Δ x k − 1 \boldsymbol{Q}_{k}^{-1}\Delta\boldsymbol{g}_{k-1}\approx\Delta\boldsymbol{x}_{k-1} Qk1Δgk1Δxk1
利用定理1和定理2。得到秩1法搜索点序列的迭代式
x k + 1 = x k − α k Q k − 1 g k \boldsymbol{x}_{k+1}=\boldsymbol{x}_k-\alpha_k\boldsymbol{Q}_k^{-1}\boldsymbol{g}_k xk+1=xkαkQk1gk
其中, α k = arg ⁡ min ⁡ α > 0 f ( x k − α Q g k ) \alpha_k=\arg\min\limits_{\alpha>0}f(\boldsymbol{x}_k-\alpha\boldsymbol{Q}\boldsymbol{g}_k) αk=argα>0minf(xkαQgk)。下列Python函数实现秩1算法。

import numpy as np
from scipy.optimize import minimize_scalar,OptimizeResult
def rank1(f, x1, gtol, **options):
    n=x1.size
    xk=x1
    gk=grad(f,xk)
    Qk=np.eye(n)
    dk=-np.matmul(Qk,gk)
    phi=lambda a: f(xk+a*dk)
    k=1
    while np.linalg.norm(gk)>gtol:
        ak=minimize_scalar(phi).x
        dx=ak*dk
        xk=xk+dx
        dg=grad(f,xk)-gk
        vk=dx-np.matmul(Qk,dg)
        Ek=np.matmul(vk.reshape(n,1),vk.reshape(1,n))/np.dot(vk,dg)
        Qk+=Ek
        gk+=dg
        dk=-np.matmul(Qk,gk)
        k+=1
    bestx=xk
    besty=f(bestx)
    return OptimizeResult(fun=besty, x=bestx, nit=k)

程序中第3~24行定义的rank1函数实现对称秩1算法。参数f表示目标函数 f ( x ) f(\boldsymbol{x}) f(x),x1表示初始点 x 1 \boldsymbol{x}_1 x1,eps表示容错误差 ε \varepsilon ε,options实现minimize与本函数的信息交换机制。
第4~10行执行初始化操作:第4行读取自变量维数n。第5行将表示迭代点的xk初始化为x1。第6行调用计算梯度的函数grad(见博文《最优化方法Python计算:n元函数梯度与Hesse阵的数值计算》)计算目标函数的梯度
g k = ∇ f ( x k ) \boldsymbol{g}_k=\nabla f(\boldsymbol{x}_k) gk=f(xk)
赋予变量gk。第7行调用numpy的eye函数将正定阵 Q k − 1 \boldsymbol{Q}_k^{-1} Qk1初始化为单位阵 I n \boldsymbol{I}_n In赋予Qk。第8行调用numpy的matmul函数计算
d k = − Q k − 1 g k \boldsymbol{d}_k=-\boldsymbol{Q}_k^{-1}\boldsymbol{g}_k dk=Qk1gk
赋予表示搜索刚想的变量dk。第9行用{\bf{lambda}}运算符定义一元函数
ϕ ( α ) = f ( x k + α d k ) \phi(\alpha)=f(\boldsymbol{x}_k+\alpha\boldsymbol{d}_k) ϕ(α)=f(xk+αdk)
为phi。
第11~21行执行迭代的while循环中,第12行调用scipy.optimize的minimize_scalar函数(第2行导入),计算
α k = arg ⁡ min ⁡ α > 0 ϕ ( α ) \alpha_k=\arg\min\limits_{\alpha>0}\phi(\alpha) αk=argα>0minϕ(α)
赋予ak。第13行计算
Δ x = x k + 1 − x k = x k + α k d k − x k = α k d k \Delta\boldsymbol{x}=\boldsymbol{x}_{k+1}-\boldsymbol{x}_k=\boldsymbol{x}_k+\alpha_k\boldsymbol{d}_k-\boldsymbol{x}_k=\alpha_k\boldsymbol{d}_k Δx=xk+1xk=xk+αkdkxk=αkdk
赋予dx。第14行计算
x k + 1 = x k + α d k = x k + Δ x k \boldsymbol{x}_{k+1}=\boldsymbol{x}_k+\alpha\boldsymbol{d}_k=\boldsymbol{x}_k+\Delta\boldsymbol{x}_k xk+1=xk+αdk=xk+Δxk
更新迭代点xk。第15行计算
Δ g k = g k + 1 − g k \Delta\boldsymbol{g}_k=\boldsymbol{g}_{k+1}-\boldsymbol{g}_k Δgk=gk+1gk
dg。第16行调用numpy的matmul函数计算向量
v k = Δ x k − Q k Δ g k \boldsymbol{v}_k=\Delta\boldsymbol{x}_k-\boldsymbol{Q}_k\Delta\boldsymbol{g}_k vk=ΔxkQkΔgk
赋予vk。第17行计算矩阵
E k = v k ⊤ v k v k Δ g ⊤ \boldsymbol{E}_k=\frac{\boldsymbol{v}_k^\top\boldsymbol{v}_k}{\boldsymbol{v}_k\Delta\boldsymbol{g}^\top} Ek=vkΔgvkvk
赋予Ek。第18行计算
Q k + 1 − 1 = Q k − 1 + E k \boldsymbol{Q}_{k+1}^{-1}=\boldsymbol{Q}_{k}^{-1}+\boldsymbol{E}_k Qk+11=Qk1+Ek
更新Qk。第19行计算
g k + 1 = Δ g k − g k \boldsymbol{g}_{k+1}=\Delta\boldsymbol{g}_k-\boldsymbol{g}_k gk+1=Δgkgk
更新gk。第20行计算
Q k + 1 − 1 g k + 1 \boldsymbol{Q}_{k+1}^{-1}\boldsymbol{g}_{k+1} Qk+11gk+1
更新dk。\par
第22~24用 f ( x k ) f(\boldsymbol{x}_k) f(xk) x k \boldsymbol{x}_k xk以及 k k k构造OptimizeResult(第2行导入)对象并返回。以下例子说明函数rank1的应用。
例1 设初始点 x 1 = ( 100 100 ) \boldsymbol{x}_1=\begin{pmatrix}100\\100\end{pmatrix} x1=(100100),用rank1函数计算Rosenbrock函数的最优解,给定容错误差 ε = 1 0 − 8 \varepsilon=10^{-8} ε=108
:下列代码完成本例计算。

import numpy as np                                      #导入numpy
from scipy.optimize import rosen, minimize              #导入rosen, minimize
x=np.array([100,100])                                   #设置初始点
res=minimize(rosen,x,method=rank1,options={'gtol':1e-8})#计算最优解
print(res)

第3行设置初始点 x 1 = ( 100 100 ) \boldsymbol{x}_1=\begin{pmatrix}100\\100\end{pmatrix} x1=(100100)。第4行调用scipy.optimize的minimize函数(第2行导入),传递rank1给参数method,计算rosen(第2行导入)表示的Rosenbrock函数的最优解。运行程序,输出

 fun: 4.889083789243004e-26
 nit: 49
   x: array([1., 1.])

即以 x 1 = ( 100 100 ) \boldsymbol{x}_1=\begin{pmatrix}100\\100\end{pmatrix} x1=(100100)为初始点, ε = 1 0 − 8 \varepsilon=10^{-8} ε=108为容错误差,实现对称秩1算法的rank1函数迭代49次,算得Rosenbrock函数的最优解 x 0 = ( 1 1 ) \boldsymbol{x}_0=\begin{pmatrix}1\\1\end{pmatrix} x0=(11)。需提请注意的是,对牛顿法而言,以 x 1 = ( 100 100 ) \boldsymbol{x}_1=\begin{pmatrix}100\\100\end{pmatrix} x1=(100100)为初始点是得不到最优解 x 0 \boldsymbol{x}_0 x0的,读者可自行验证。
写博不易,敬请支持:
如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值