Introduction to Optimization(四): 拟牛顿法
来源:互联网 发布:伊斯兰教在中国知乎 编辑:程序博客网 时间:2024/05/18 15:07
本节介绍:
- hessian matrix 近似
- DFP算法
- bfgs算法
hessian matrix 近似
牛顿法的基本思路是用二次函数来局部逼近目标函数
但是牛顿法的缺陷是需要计算hessian矩阵,及其逆矩阵,但是实际上我们如果能保证
在
为了保证
拟牛顿法
拟牛顿法的迭代思路是
第二条件
对于正定矩阵
并且当它们满足以上条件的时候,可以证明(P135 定理 11.1)
由以上可以看到,
下面讲两种算法,分别是DFP和BFGS
DFP算法
- 选择初始点
x0,对称正定矩阵H0 - 计算
gk , 如果||gk||<ϵ 停止迭代- 计算
dk=−Hkgk
计算αk=argminα≥0f(xk+αdk)
xk+1=xk+αkdk
Δxk=αkdk
Δgk=gk+1−gk
tmp=HkΔgk
Hk+1=Hk+ΔxkΔxTkΔxTkΔgk−tmptmpTΔgTkHkΔgk
这里得证明这样构造的
定理11.3
用DFP算法求解 二次型问题时,Hessian matrix
因证明过程较为难写,故这里直接给出书上证明:
定理11.4
假定
书上说,DFP 算法处理某些较大的非二次型问题是容易被’卡’ 住,所以后面有四个大牛提出了一种BFGS算法解决这一问题
BFGS
BFGS取自4个人的名字
图片来源于码农场
前面提到的
利用互补的概念,应用DFP算法中的更新公式我们可以得到
因此
关于这个式子我们有如下引理
引理11.1
如果
直接计算可证
因此应用两次引理,可得
BFGS在实践中较为常用scipy.optimize 里面也有实现.以下是我的实现
代码实现
def dfp(fun, grad, x0, args=(), g_args=(), tol=1e-8, max_iter=5000): h0 = np.eye(len(x0)) g_0 = grad(*((x0,) + g_args)) alpha = lambda a, x, d: fun(*((x + a * d,) + args)) for i in range(max_iter): if is_stop(g_0, np.zeros(g_0.shape), tol): break d = -h0.dot(g_0) alp = minimize_scalar(alpha, bounds=(0, 10000), args=(x0, d), method='brent', tol=1e-4) alp = alp.x x_next = x0 + alp * d delta_x = (alp * d).reshape((len(x0), 1)) g_next = grad(*((x_next,) + g_args)) delta_g = g_next - g_0 delta_g = delta_g.reshape((delta_x.shape)) tmp = h0.dot(delta_g) h0 = h0 + delta_x.dot(delta_x.T) / (delta_x.T.dot(delta_g)) - tmp.dot(tmp.T) / (delta_g.T.dot(tmp)) x0 = x_next g_0 = g_next return OptimizeResult({'nit': i, 'x': x0, 'jac': g_0, 'fun': fun(*((x0,) + args))})def bfgs(fun, grad, x0, args=(), g_args=(), tol=1e-8, max_iter=5000): h0 = np.eye(len(x0)) g_0 = grad(*((x0,) + g_args)) alpha = lambda a, x, d: fun(*((x + a * d,) + args)) for i in range(max_iter): if is_stop(g_0, np.zeros(g_0.shape), tol): break d = -h0.dot(g_0) alp = minimize_scalar(alpha, bounds=(0, 10000), args=(x0, d), method='brent', tol=1e-4) alp = alp.x x_next = x0 + alp * d delta_x = (alp * d).reshape((len(x0), 1)) g_next = grad(*((x_next,) + g_args)) delta_g = g_next - g_0 delta_g = delta_g.reshape((delta_x.shape)) tmp = h0.dot(delta_g).dot(delta_x.T) tmp1 = (1+delta_g.T.dot(h0).dot(delta_g)/(delta_g.T.dot(delta_x)))*delta_x.dot(delta_x.T)/(delta_x.T.dot(delta_g)) tmp2 = (tmp + tmp.T)/(delta_g.T.dot(delta_x)) h0 = h0 + tmp1 - tmp2 x0 = x_next g_0 = g_next return OptimizeResult({'nit': i, 'x': x0, 'jac': g_0, 'fun': fun(*((x0,) + args))})
DFP 与bfgs除了更新公式以外其他几乎完全一样
以下是在rosen 函数下的实验效果
bfgs result fun: 6.0875493993460361e-23 jac: array([ -2.87637469e-10, 1.46505030e-10]) nit: 17 x: array([ 1., 1.])dfp result fun: 2.4549731009788525e-23 jac: array([ -1.82560633e-10, 9.29922805e-11]) nit: 17 x: array([ 1., 1.])
两次均优于共轭梯度算法.
实际使用
在实际使用中我们用的最多的还是SGD这样的用梯度来优化的算法,因为可以看到二阶项的一个重要的弊端就是空间复杂度太高,需要存贮二阶项,这对于
本文链接http://blog.csdn.net/Dylan_Frank/article/details/78287680
- Introduction to Optimization(四): 拟牛顿法
- Introduction to Optimization(一):一维最优化方法
- Introduction to Optimization(三): 共轭梯度算法
- Introduction to Optimization(二):基于梯度的优化
- 再谈 牛顿法/Newton's Method In Optimization
- 牛顿法与拟牛顿法学习笔记(四)BFGS 算法
- 牛顿法与拟牛顿法学习笔记(四)BFGS 算法
- 牛顿法与拟牛顿法学习笔记(四)BFGS 算法
- 牛顿法与拟牛顿法学习笔记(四)BFGS 算法
- 牛顿法与拟牛顿法学习笔记(四)BFGS 算法
- 牛顿法与拟牛顿法学习笔记(四)BFGS 算法
- 牛顿法与拟牛顿法学习笔记(四)BFGS 算法
- 牛顿法与拟牛顿法学习笔记(四)BFGS 算法
- 牛顿法与拟牛顿法学习笔记(四)BFGS 算法
- CS231n--Introduction&Linear classifier&Optimization
- 梯度下降、牛顿法、拟牛顿法
- 牛顿法和拟牛顿法
- 牛顿法和拟牛顿法
- 从lazy binding(延迟绑定) and return to dl-resolve
- Communications link failure
- MD5的3中写法记录
- 漫谈技术—— 六年工作感悟
- Codeforces Round #441 (Div. 2, by Moscow Team Olympiad) D. Sorting the Coins
- Introduction to Optimization(四): 拟牛顿法
- 1614: [Usaco2007 Jan]Telephone Lines架设电话线
- Linux命令分析:dd
- SQL 通配符
- idea相关
- 瑞萨RX23T开发板一键设置库文件说明
- 《工作五年,决定你一生的财富》
- redis持久化
- 算法练习__二叉查找树