拟牛顿法之DFP算法

拟牛顿法(Quasi-Newton Methods)是求解非线性优化问题最有效的方法之一,于20世纪50年代由美国Argonne国家实验室的物理学家W. C. Davidon所提出来。Davidon设计的这种算法在当时看来是非线性优化领域最具创造性的发明之一。不久R.
Fletcher和M. J. D. Powell证实了这种新的算法远比其他方法快速和可靠,使得非线性优化这门学科在一夜之间突飞猛进。在之后的20年里,拟牛顿方法得到了蓬勃发展,出现了大量的变形公式以及数以百计的相关论文。

拟牛顿法和最速下降法(Steepest Descent Methods)一样只要求每一步迭代时知道目标函数的梯度。通过测量梯度的变化,构造一个目标函数的模型使之足以产生超线性收敛性。这类方法大大优于最速下降法,尤其对于困难的问题。另外,因为拟牛顿法不需要二阶导数的信息,所以有时比牛顿法(Newton‘s
Method)更为有效。如今,优化软件中包含了大量的拟牛顿算法用来解决无约束,约束,和大规模的优化问题。

拟牛顿法的基本思想如下。首先构造目标函数在当前迭代

的二次模型:

这里

是一个对称正定矩阵,于是我们取这个二次模型的最优解作为搜索方向,并且得到新的迭代点

,其中我们要求步长

满足Wolfe条件。这样的迭代与牛顿法类似,区别就在于用近似的Hesse矩阵

代替真实的Hesse矩阵。所以拟牛顿法最关键的地方就是每一步迭代中矩阵

的更新。现在假设得到一个新的迭代

,并得到一个新的二次模型:

我们尽可能地利用上一步的信息来选取

。具体地,我们要求

,从而得到

DFP方法

,DFP公式为

其实现如下所示:

#!/usr/bin/python
# -*- coding:utf8 -*-
import random
import numpy as np
import math

#f(x,y) = (x-2)^2+(y-1)^2 + 1
def solution(grad_func) :
    rate = 0.3
    #Gk必须保证为正定矩阵
    #Gk = np.eye(2)
    Gk = np.diag([random.uniform(0.0001, 100), random.uniform(0.0001, 100)])
    x = random.uniform(-10000,10000)
    y = random.uniform(-10000,10000)
    point = np.array([[x, y]]).transpose()

    # numpy.array中是初始化是按行的
    grad_last = grad_func(point[0][0], point[1][0]).transpose()
    if reduce(lambda a,b: math.sqrt(a*a+b*b), [grad_last[i][0] for i in xrange(grad_last.shape[0])]) < 0.000001 :
        return get_point_coordinate(point)

    for index in xrange(0, 10000) :
        pk = -1 * Gk.dot(grad_last)
        # 寻找最优的rate
        #rate = grad_last.transpose().dot(pk)[0][0] / (pk.transpose().dot(pk)[0][0]) * (-0.5);print "rate", rate

        point = point + rate * pk
        grad = grad_func(point[0][0], point[1][0]).transpose()
        print "grad", grad.transpose();#print "Gk", Gk
        if reduce(lambda a,b: math.sqrt(a*a+b*b), [grad[i][0] for i in xrange(grad.shape[0])]) < 0.000001 : break

        delta_k = rate * pk
        y_k = (grad - grad_last)
        Pk = delta_k.dot(delta_k.transpose()) / (delta_k.transpose().dot(y_k))
        Qk= Gk.dot(y_k).dot(y_k.transpose()).dot(Gk) / (y_k.transpose().dot(Gk).dot(y_k)) * (-1.)
        Gk += Pk + Qk

        grad_last = grad

    print "times of iterate : %s" % index
    return get_point_coordinate(point)
def get_point_coordinate(point):
    return point[0][0], point[1][0]

if __name__ == "__main__" :
    x, y = solution(lambda a,b: np.array([[2*(a-2), 2*(b-1)]]))
    print "minimum point of f(x,y) = (x-2)^2+(y-1)^2 + 1 : (%s,%s)" % (x, y)

执行结果为:

grad [[-165661.89194611 -109405.68739563]]
grad [[-100881.92784944  -98677.83692405]]
grad [[-86031.40619151  24003.06422296]]
grad [[-58462.97031009  16589.21632892]]
grad [[-40924.16152279  11612.14537593]]
grad [[-28646.91295682   8128.50214772]]
grad [[-20052.83906991   5689.95150292]]
grad [[-14036.98734894   3982.96605204]]
grad [[-9825.89114426  2788.07623643]]
grad [[-6878.12380098  1951.6533655 ]]
grad [[-4814.68666069  1366.15735585]]
grad [[-3370.28066248   956.3101491 ]]
grad [[-2359.19646374   669.41710437]]
grad [[-1651.43752462   468.59197306]]
grad [[-1156.00626723   328.01438114]]
grad [[-809.20438706  229.6100668 ]]
grad [[-566.44307094  160.72704676]]
grad [[-396.51014966  112.50893273]]
grad [[-277.55710476   78.75625291]]
grad [[-194.28997333   55.12937704]]
grad [[-136.00298133   38.59056393]]
grad [[-95.20208693  27.01339475]]
grad [[-66.64146085  18.90937632]]
grad [[-46.6490226   13.23656343]]
grad [[-32.65431582   9.2655944 ]]
grad [[-22.85802107   6.48591608]]
grad [[-16.00061475   4.54014126]]
grad [[-11.20043033   3.17809888]]
grad [[-7.84030123  2.22466922]]
grad [[-5.48821086  1.55726845]]
grad [[-3.8417476   1.09008792]]
grad [[-2.68922332  0.76306154]]
grad [[-1.88245632  0.53414308]]
grad [[-1.31771943  0.37390015]]
grad [[-0.9224036   0.26173011]]
grad [[-0.64568252  0.18321108]]
grad [[-0.45197776  0.12824775]]
grad [[-0.31638443  0.08977343]]
grad [[-0.2214691  0.0628414]]
grad [[-0.15502837  0.04398898]]
grad [[-0.10851986  0.03079229]]
grad [[-0.0759639  0.0215546]]
grad [[-0.05317473  0.01508822]]
grad [[-0.03722231  0.01056175]]
grad [[-0.02605562  0.00739323]]
grad [[-0.01823893  0.00517526]]
grad [[-0.01276725  0.00362268]]
grad [[-0.00893708  0.00253588]]
grad [[-0.00625595  0.00177511]]
grad [[-0.00437917  0.00124258]]
grad [[-0.00306542  0.00086981]]
grad [[-0.00214579  0.00060886]]
grad [[-0.00150205  0.0004262 ]]
grad [[-0.00105144  0.00029834]]
grad [[-0.00073601  0.00020884]]
grad [[-0.0005152   0.00014619]]
grad [[-0.00036064  0.00010233]]
grad [[ -2.52450311e-04   7.16322521e-05]]
grad [[ -1.76715217e-04   5.01425765e-05]]
grad [[ -1.23700652e-04   3.50998035e-05]]
grad [[ -8.65904565e-05   2.45698625e-05]]
grad [[ -6.06133196e-05   1.71989037e-05]]
grad [[ -4.24293237e-05   1.20392326e-05]]
grad [[ -2.97005266e-05   8.42746283e-06]]
grad [[ -2.07903686e-05   5.89922398e-06]]
grad [[ -1.45532580e-05   4.12945679e-06]]
grad [[ -1.01872806e-05   2.89061975e-06]]
grad [[ -7.13109643e-06   2.02343382e-06]]
grad [[ -4.99176750e-06   1.41640368e-06]]
grad [[ -3.49423725e-06   9.91482574e-07]]
grad [[ -2.44596608e-06   6.94037802e-07]]
grad [[ -1.71217625e-06   4.85826461e-07]]
grad [[ -1.19852338e-06   3.40078523e-07]]
grad [[ -8.38966364e-07   2.38054966e-07]]
times of iterate : 73
minimum point of f(x,y) = (x-2)^2+(y-1)^2 + 1 : (1.99999958052,1.00000011903)

可以看到最终的解与实际解(2, 1)非常接近!

参考资料:http://baike.baidu.com/link?url=O5fmCAZqayVu6vd1rKvDH8UiIdUfgEBHM3cHtDn0NBUxLjDMEXJFW7pK89lZxEuyvcJd67oRFd3FYQnAUROoLK#2

时间: 2024-08-05 21:36:13

拟牛顿法之DFP算法的相关文章

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

一.牛顿法 在博文"优化算法--牛顿法(Newton Method)"中介绍了牛顿法的思路,牛顿法具有二阶收敛性,相比较最速下降法,收敛的速度更快.在牛顿法中使用到了函数的二阶导数的信息,对于函数,其中表示向量.在牛顿法的求解过程中,首先是将函数在处展开,展开式为: 其中,,表示的是目标函数在的梯度,是一个向量.,表示的是目标函数在处的Hesse矩阵.省略掉最后面的高阶无穷小项,即为: 上式两边对求导,即为: 在基本牛顿法中,取得最值的点处的导数值为,即上式左侧为.则: 求出其中的:

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

一.BFGS算法简介 BFGS算法是使用较多的一种拟牛顿方法,是由Broyden,Fletcher,Goldfarb,Shanno四个人分别提出的,故称为BFGS校正. 同DFP校正的推导公式一样,DFP校正见博文"优化算法--拟牛顿法之DFP算法".对于拟牛顿方程: 可以化简为: 令,则可得: 在BFGS校正方法中,假设: 二.BFGS校正公式的推导 令,其中均为的向量.,. 则对于拟牛顿方程可以化简为: 将代入上式: 将代入上式: 已知:为实数,为的向量.上式中,参数和解的可能性有

牛顿法与拟牛顿法学习笔记(三)DFP 算法

机器学习算法中经常碰到非线性优化问题,如 Sparse Filtering 算法,其主要工作在于求解一个非线性极小化问题.在具体实现中,大多调用的是成熟的软件包做支撑,其中最常用的一个算法是 L-BFGS.为了解这个算法的数学机理,这几天做了一些调研,现把学习过程中理解的一些东西整理出来. 目录链接 (1) 牛顿法 (2) 拟牛顿条件 (3) DFP 算法 (4) BFGS 算法 (5) L-BFGS 算法 作者: peghoty 出处: http://blog.csdn.net/itplus/

数学软件 之 基于MATLAB的DFP算法

DFP算法是本科数学系中最优化方法的知识,也是无约束最优化方法中非常重要的两个拟Newton算法之一,上一周写了一周的数学软件课程论文,姑且将DFP算法的实现细节贴出来分享给学弟学妹参考吧,由于博客不支持数学公式,所以就不累述算法原理及推倒公式了. DFP算法流程图 先给出DFP算法迭代流程图,总体上是拟Newton方法的通用迭代步骤,唯独在校正公式的地方有所区别. MATLAB实现DFP 基于此图便可以设计DFP算法的MATLAB程序: 对分法及加步探索法的实现 首先由于DFP算法中需要利用一

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

一.BFGS算法 在"优化算法--拟牛顿法之BFGS算法"中,我们得到了BFGS算法的校正公式: 利用Sherman-Morrison公式可对上式进行变换,得到 令,则得到: 二.BGFS算法存在的问题 在BFGS算法中,每次都要存储近似Hesse矩阵,在高维数据时,存储浪费很多的存储空间,而在实际的运算过程中,我们需要的是搜索方向,因此出现了L-BFGS算法,是对BFGS算法的一种改进算法.在L-BFGS算法中,只保存最近的次迭代信息,以降低数据的存储空间. 三.L-BFGS算法思路

牛顿法|阻尼牛顿法|拟牛顿法|DFP算法|BFGS算法|L-BFGS算法

一直记不住这些算法的推导,所以打算详细点写到博客中以后不记得就翻阅自己的笔记. 泰勒展开式 最初的泰勒展开式,若  在包含  的某开区间(a,b)内具有直到n+1阶的导数,则当x∈(a,b)时,有: 令可得到如下式子: 泰勒展开我的理解就有两个式子. 参考文献:http://baike.baidu.com/link?url=E-D1MzRCjDi8qrlh2Cn64fwtz703bg-h_z2_mOXorti2_3aBKrOUY4-2gHuESowiK8aQSBFE8y0yJeGl4_yOAq

DFP算法(转载)

转载链接:http://blog.csdn.net/itplus/article/details/21896981 注意:式(2.25)中,蓝色变量之所以是实数可以根据它们的矩阵系数相乘为1*1得到.

回归- Regression

回归- Regression ------------------------------------------ 回归- Regression 线性回归Linear regression 模型表示Model representation 代价函数Cost function 目标Goal 多项式回归 加权线性回归 一般线性回归 通用的指数概率分布 伯努利分布 高斯分布 微分与导数1 微分 导数 方向导数 梯度 梯度下降算法 基本思想 流程 批量梯度下降 随机梯度下降 特征归一化 步长的选择 优缺

工程优化方法中的“最速下降法”和“DFP拟牛顿法”的 C 语言实现

这个小程序是研一上学期的“工程优化”课程的大作业.其实这题本可以用 MATLAB 实现,但是我为了锻炼自己薄弱的编码能力,改为用 C 语言实现.这样,就得自己实现矩阵的运算(加减乘除.求逆.拷贝):难点是求偏导,通过查资料,发现可以通过导数定义,即取极限的方法,来逐步逼近求得梯度:另外,没法做到输入任意公式,只能将公式硬编码为函数,而求导函数需要传入公式,就直接传入函数指针了.思考.编码.调试.测试共耗费两周左右时间,完成于 2013/01/10.虽然为了认真做这个大作业而耽误了期末考试的复习,