一、BFGS算法简介

    BFGS算法是使用较多的一种拟牛顿方法,是由BroydenFletcherGoldfarbShanno四个人分别提出的,故称为BFGS校正。
    同DFP校正的推导公式一样,DFP校正见博文“优化算法——拟牛顿法之DFP算法”。对于拟牛顿方程:

优化算法——拟牛顿法之BFGS算法

可以化简为:

优化算法——拟牛顿法之BFGS算法

优化算法——拟牛顿法之BFGS算法,则可得:

优化算法——拟牛顿法之BFGS算法

BFGS校正方法中,假设:

优化算法——拟牛顿法之BFGS算法

二、BFGS校正公式的推导

    令优化算法——拟牛顿法之BFGS算法,其中优化算法——拟牛顿法之BFGS算法均为优化算法——拟牛顿法之BFGS算法的向量。优化算法——拟牛顿法之BFGS算法优化算法——拟牛顿法之BFGS算法
    则对于拟牛顿方程优化算法——拟牛顿法之BFGS算法可以化简为:

优化算法——拟牛顿法之BFGS算法

优化算法——拟牛顿法之BFGS算法代入上式:

优化算法——拟牛顿法之BFGS算法

优化算法——拟牛顿法之BFGS算法代入上式:

优化算法——拟牛顿法之BFGS算法

优化算法——拟牛顿法之BFGS算法

    已知:优化算法——拟牛顿法之BFGS算法为实数,优化算法——拟牛顿法之BFGS算法优化算法——拟牛顿法之BFGS算法的向量。上式中,参数优化算法——拟牛顿法之BFGS算法优化算法——拟牛顿法之BFGS算法解的可能性有很多,我们取特殊的情况,假设优化算法——拟牛顿法之BFGS算法优化算法——拟牛顿法之BFGS算法。则

优化算法——拟牛顿法之BFGS算法

代入上式:

优化算法——拟牛顿法之BFGS算法

优化算法——拟牛顿法之BFGS算法

优化算法——拟牛顿法之BFGS算法优化算法——拟牛顿法之BFGS算法,则:

优化算法——拟牛顿法之BFGS算法

优化算法——拟牛顿法之BFGS算法

则最终的BFGS校正公式为:

优化算法——拟牛顿法之BFGS算法

三、BFGS校正的算法流程

    设优化算法——拟牛顿法之BFGS算法对称正定,优化算法——拟牛顿法之BFGS算法由上述的BFGS校正公式确定,那么优化算法——拟牛顿法之BFGS算法对称正定的充要条件是优化算法——拟牛顿法之BFGS算法
    在博文优化算法——牛顿法(Newton Method)”中介绍了非精确的线搜索准则:Armijo搜索准则,搜索准则的目的是为了帮助我们确定学习率,还有其他的一些准则,如Wolfe准则以及精确线搜索等。在利用Armijo搜索准则时并不是都满足上述的充要条件,此时可以对BFGS校正公式做些许改变:

优化算法——拟牛顿法之BFGS算法

BFGS拟牛顿法的算法流程:
优化算法——拟牛顿法之BFGS算法

四、求解具体优化问题

   求解无约束优化问题

优化算法——拟牛顿法之BFGS算法

其中,优化算法——拟牛顿法之BFGS算法
python程序实现:
  1. function.py
    [python] view plain copy
    1. #coding:UTF-8  
    2. ''''' 
    3. Created on 2015年5月19日 
    4.  
    5. @author: zhaozhiyong 
    6. '''  
    7.   
    8. from numpy import *  
    9.   
    10. #fun  
    11. def fun(x):  
    12.     return 100 * (x[0,0] ** 2 - x[1,0]) ** 2 + (x[0,0] - 1) ** 2  
    13.   
    14. #gfun  
    15. def gfun(x):  
    16.     result = zeros((21))  
    17.     result[00] = 400 * x[0,0] * (x[0,0] ** 2 - x[1,0]) + 2 * (x[0,0] - 1)  
    18.     result[10] = -200 * (x[0,0] ** 2 - x[1,0])  
    19.     return result  

  2. bfgs.py
    [python] view plain copy
    1. #coding:UTF-8  
    2.   
    3. from numpy import *  
    4. from function import *  
    5.   
    6. def bfgs(fun, gfun, x0):  
    7.     result = []  
    8.     maxk = 500  
    9.     rho = 0.55  
    10.     sigma = 0.4  
    11.     m = shape(x0)[0]  
    12.     Bk = eye(m)  
    13.     k = 0  
    14.     while (k < maxk):  
    15.         gk = mat(gfun(x0))#计算梯度  
    16.         dk = mat(-linalg.solve(Bk, gk))  
    17.         m = 0  
    18.         mk = 0  
    19.         while (m < 20):  
    20.             newf = fun(x0 + rho ** m * dk)  
    21.             oldf = fun(x0)  
    22.             if (newf < oldf + sigma * (rho ** m) * (gk.T * dk)[0,0]):  
    23.                 mk = m  
    24.                 break  
    25.             m = m + 1  
    26.           
    27.         #BFGS校正  
    28.         x = x0 + rho ** mk * dk  
    29.         sk = x - x0  
    30.         yk = gfun(x) - gk  
    31.         if (yk.T * sk > 0):  
    32.             Bk = Bk - (Bk * sk * sk.T * Bk) / (sk.T * Bk * sk) + (yk * yk.T) / (yk.T * sk)  
    33.           
    34.         k = k + 1  
    35.         x0 = x  
    36.         result.append(fun(x0))  
    37.       
    38.     return result  

  3. testBFGS.py
    [python] view plain copy
    1. #coding:UTF-8  
    2. ''''' 
    3. Created on 2015年5月19日 
    4.  
    5. @author: zhaozhiyong 
    6. '''  
    7.   
    8. from bfgs import *  
    9.   
    10. import matplotlib.pyplot as plt    
    11.   
    12. x0 = mat([[-1.2], [1]])  
    13. result = bfgs(fun, gfun, x0)  
    14.   
    15. n = len(result)  
    16. ax = plt.figure().add_subplot(111)  
    17. x = arange(0, n, 1)  
    18. y = result  
    19. ax.plot(x,y)  
    20.   
    21. plt.show()  


五、实验结果

优化算法——拟牛顿法之BFGS算法

相关文章: