【优化理论】 共轭梯度下降算法实现

实验目的

在这里插入图片描述

实验步骤

  此次实验要求采用共轭梯度下降来解决二次优化问题,在解决此问题前,首先分析下什么是共轭梯度法,共轭梯度法能解决什么问题。
  我们来看一个线性方程组Ax=b,求解此方程组的过程可以看成是形如公式(1)的优化问题:
arg min x A x b 2 ( 1 ) \mathop{\arg\min_{x}} \parallel Ax-b\parallel^2…………………………………………(1)
  其又可转化为公式(2):
A x b 2 = ( A x b ) T ( A x b ) = x T A T A x 2 b T A x + b 2 ( 2 ) \parallel Ax-b\parallel ^2 =(Ax-b)^T (Ax-b)=x^T A^T Ax-2b^T Ax+\parallel b\parallel ^2………(2)
  令 H = A T A , g = b T A H H=A^T A,g=b^T A,H正定,
  则上述优化问题等价于公式(3):
arg min x f ( x ) = 1 2 x T H x g T x ( 3 ) \mathop{\arg\min_{x}}f(x)=\frac{1}{2} x^T Hx-g^T x……………………………………(3)
  如此一来,求解线性方程组转化为二次优化问题,那么如何求解公式(3)的优化问题呢?让我们先来看一些定义和性质。
  定义1. 给定一个正定矩阵?,我们可以定义?−内积:
x , y H = x T H y , x , y R n ( 4 ) ⟨x,y⟩_H=x^T Hy,∀x,y∈R^n……………………………………(4)
  定义2.H 是一个n×n的正定矩阵,x,y∈R^n,如果⟨x,y⟩_H=0,则称 x 与 y 是H-共轭的。
  性质1. 设非零向量d_1,d_2,…,d_n 两两H-共轭,则它们线性无关。
  通过定义1、2和性质1,我们可以得出如下结论:
x : x = i = 1 n α i d i ( 5 ) 空间任意向量 x可以用这组向量基表示:x= ∑_{i=1}^nα_i d_i………………(5)
  将公式(5)代入公式(3)可得:
g T x = α 1 g T d 1 + α 2 g T d 2 + + α n g T d n ( 6 ) x T H x = i = 1 n α i 2 d i , d i H = i = 1 n α i 2 d i T H d i ( 7 ) f ( x ) = g T x + 1 2 x T H x = i = 1 n ( 1 2 α i 2 d i T H d i α i g T d i ) ( 8 ) g^T x=α_1 g^T d_1+α_2 g^T d_2+⋯+α_n g^T d_n…………………………(6) \\ x^T Hx=∑_{i=1}^nα_i^2 ⟨d_i,d_i ⟩_H =∑_{i=1}^nα_i^2 d_i^T Hd_i …………………………(7) \\ f(x)=g^T x+\frac{1}{2}x^T Hx=∑_{i=1}^n(\frac{1}{2}α_i^2 d_i^T Hd_i-α_i g^T d_i ) …………………(8)
  现在的目标就是求公式(8)的最小值,如果参与求和的每一项都取最小值,则f (x)达到最小值,所以对公式(8)中求和的每一项进行求导可得解向量的第i个分量:
α i = g T d i d i T H d i , i = 1 , 2 , 3 , , n ( 9 ) α_i=\frac {g^T d_i}{d_i^T Hd_i }, i=1,2,3,…,n…………………………………(9)
  注意:上面的解法中求每一个α_i是独立的步骤,只用到一个向量d_i,因此我们并不需要一开始就有n个共轭向量,只需要一个向量就可以启动,而每一次都能求解得到解向量的一个分量,所以理论上当循环次数至多到n次(n指H的维度)时,梯度必降为0,求解完毕。

基本实现原理

  对于本题具体的求解算法如图1所示:
在这里插入图片描述

图 1 共轭梯度法具体算法
  算法图中循环终止条件是梯度降为0,符合之前理论上的分析,但在实际计算过程中,由于舍入误差或其他噪声常常导致算法无法有限步收敛,因此停止条件修改为公式(10):

η = f ( x ) < ε . ( 10 ) \parallelη\parallel=\parallel∇f(x)\parallel<ε.…………………………………(10)

实现代码

代码如下,也可观看我GitHub

# -*- coding: utf-8 -*-  
""" 
Created on Sat Nov 17 13:39:12 2018 
 
@author: YLC 
"""  
import numpy as np  
x = np.array([0,0,0,0]).T #.T表示转置,下同  
H = np.array([[158,20,90,101],[20,36,46,61],[90,46,306,156],[101,61,156,245]])  
g = np.array([8,-5,1,6]).T  
def grad(H,x,g): #梯度计算公式,由原方程求导得到  
    return np.dot(H,x)-g  
eta = grad(H,x,g) #梯度  
d = -eta #梯度方向  
i = 1 #迭代次数  
while(np.linalg.norm(eta,ord=2) > 1e-10):  
    alpha = -np.dot(eta.T,d)/np.dot(np.dot(d.T,H),d)  
    x = x + np.dot(alpha,d)  
    eta = grad(H,x,g)  
    d = -eta + np.dot(np.dot(np.dot(eta.T,H),d)/np.dot(np.dot(d.T,H),d),d)  
    #print("========================================")  
    #print("迭代第"+str(i)+"次||eta||的值为:",np.linalg.norm(eta,ord=2))      
    #print("迭代第"+str(i)+"次alpha的值为:\n",alpha)  
    #print("迭代第"+str(i)+"次eta的值为:\n",eta)  
    #print("迭代第"+str(i)+"次d的值为:\n",d)      
    print("迭代第"+str(i)+"次x的值为:\n",x)  
    i = i + 1  

实验结果及分析

实验结果如下:
迭代第1次x的值为:
[ 0.03675345 -0.0229709 0.00459418 0.02756508]
迭代第2次x的值为:
[ 0.07945184 -0.09736974 -0.03609274 0.03706019]
迭代第3次x的值为:
[ 0.05512625 -0.28123105 0.00293889 0.06041221]
迭代第4次x的值为:
[ 0.03590246 -0.30049431 -0.00770042 0.08940927]
  从实验结果可以看出,整个算法迭代了四次结束,符合前面理论的分析,H为4*4的矩阵,因而n=4,迭代4次结束。在具体实现的过程中要注意阈值ε的取值,不同于前一个实验,这里的ε要非常小,其次用python做矩阵点积预算的时候是dot函数,而不是之间用乘号。

发现与收获

  初学时,共轭梯度法较于简单的梯度下降更难以理解,对于数学上的公式、定义、性质要都有了解才好理解。这里的共轭梯度法,共轭指的不是复数的共轭,而是全新的定义H-共轭,有了H-共轭才有了线性无关的向量组d,从而转化为参数的最优化问题。同时,更应该掌握的是共轭梯度法的运用,其根本目的是为了解线性方程组,这说明不同的问题可以采取不同的梯度下降手段,从而降低算法的时空开销,提高算法性能。

发布了22 篇原创文章 · 获赞 6 · 访问量 4151

猜你喜欢

转载自blog.csdn.net/qq_34862636/article/details/99412385