博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
优化算法——拟牛顿法之L-BFGS算法
阅读量:6028 次
发布时间:2019-06-20

本文共 2524 字,大约阅读时间需要 8 分钟。

一、BFGS算法

    在“”中,我们得到了BFGS算法的校正公式:

利用Sherman-Morrison公式可对上式进行变换,得到

,则得到:

二、BGFS算法存在的问题

    在BFGS算法中。每次都要存储近似Hesse矩阵,在高维数据时,存储浪费非常多的存储空间,而在实际的运算过程中。我们须要的是搜索方向。因此出现了L-BFGS算法。是对BFGS算法的一种改进算法。

L-BFGS算法中。仅仅保存近期的次迭代信息。以减少数据的存储空间。

三、L-BFGS算法思路

    令,则BFGS算法中的能够表示为:

若在初始时,假定初始的矩阵,则我们能够得到:

若此时。仅仅保留近期的步:

这样在L-BFGS算法中。不再保存完整的。而是存储向量序列。须要矩阵时,使用向量序列计算就能够得到。而向量序列也不是全部都要保存,仅仅要保存最新的步向量就可以。

四、L-BFGS算法中的方向的计算方法

五、实验仿真

lbfgs.py

#coding:UTF-8from numpy import *from function import *def lbfgs(fun, gfun, x0):    result = []#保留终于的结果    maxk = 500#最大的迭代次数    rho = 0.55    sigma = 0.4        H0 = eye(shape(x0)[0])        #s和y用于保存近期m个,这里m取6    s = []    y = []    m = 6        k = 1    gk = mat(gfun(x0))#计算梯度    dk = -H0 * gk    while (k < maxk):                     n = 0        mk = 0        gk = mat(gfun(x0))#计算梯度        while (n < 20):            newf = fun(x0 + rho ** n * dk)            oldf = fun(x0)            if (newf < oldf + sigma * (rho ** n) * (gk.T * dk)[0, 0]):                mk = n                break            n = n + 1                #LBFGS校正        x = x0 + rho ** mk * dk        #print x                #保留m个        if k > m:            s.pop(0)            y.pop(0)                    #计算最新的        sk = x - x0        yk = gfun(x) - gk                s.append(sk)        y.append(yk)                #two-loop的过程        t = len(s)        qk = gfun(x)        a = []        for i in xrange(t):            alpha = (s[t - i - 1].T * qk) / (y[t - i - 1].T * s[t - i - 1])            qk = qk - alpha[0, 0] * y[t - i - 1]            a.append(alpha[0, 0])        r = H0 * qk                    for i in xrange(t):            beta = (y[i].T * r) / (y[i].T * s[i])            r = r + s[i] * (a[t - i - 1] - beta[0, 0])                    if (yk.T * sk > 0):            dk = -r                            k = k + 1        x0 = x        result.append(fun(x0))        return result
function.py

#coding:UTF-8'''Created on 2015年5月19日@author: zhaozhiyong'''from numpy import *#fundef fun(x):    return 100 * (x[0,0] ** 2 - x[1,0]) ** 2 + (x[0,0] - 1) ** 2#gfundef gfun(x):    result = zeros((2, 1))    result[0, 0] = 400 * x[0,0] * (x[0,0] ** 2 - x[1,0]) + 2 * (x[0,0] - 1)    result[1, 0] = -200 * (x[0,0] ** 2 - x[1,0])    return result
testLBFGS.py

#coding:UTF-8'''Created on 2015年6月6日@author: zhaozhiyong'''from lbfgs import *import matplotlib.pyplot as plt  x0 = mat([[-1.2], [1]])result = lbfgs(fun, gfun, x0)print resultn = len(result)ax = plt.figure().add_subplot(111)x = arange(0, n, 1)y = resultax.plot(x,y)plt.show()
实验结果

參考文献

你可能感兴趣的文章
2017 4月5日上午
查看>>
Python中str()与__str__、repr()与__repr__、eval()、__unicode__的关系与区别
查看>>
[NOIP2011] 观光公交
查看>>
[洛谷P3203][HNOI2010]弹飞绵羊
查看>>
Google Chrome开发者工具
查看>>
第一阶段冲刺报告(一)
查看>>
使用crontab调度任务
查看>>
ctr预估论文梳理和个人理解
查看>>
【转载】SQL经验小记
查看>>
zookeeper集群搭建 docker+zk集群搭建
查看>>
Vue2.5笔记:Vue的实例与生命周期
查看>>
论JVM爆炸的几种姿势及自救方法
查看>>
联合体、结构体简析
查看>>
使用throw让服务器端与客户端进行数据交互[Java]
查看>>
java反射与代理
查看>>
深度分析Java的ClassLoader机制(源码级别)
查看>>
微服务架构选Java还是选Go - 多用户负载测试
查看>>
我的友情链接
查看>>
Javascript中的异步如何实现回调
查看>>
halcon算子介绍
查看>>