用Python实现最速下降法求极值的方法


Posted in Python onJuly 10, 2019

对于一个多元函数用Python实现最速下降法求极值的方法,用最速下降法(又称梯度下降法)求其极小值的迭代格式为

用Python实现最速下降法求极值的方法

其中用Python实现最速下降法求极值的方法为负梯度方向,即最速下降方向,αkαk为搜索步长。

一般情况下,最优步长αkαk的确定要用到线性搜索技术,比如精确线性搜索,但是更常用的是不精确线性搜索,主要是Goldstein不精确线性搜索和Wolfe法线性搜索。

为了调用的方便,编写一个Python文件,里面存放线性搜索的子函数,命名为linesearch.py,这里先只编写了Goldstein线性搜索的函数,关于Goldstein原则,可以参看最优化课本。

线性搜索的代码如下(使用版本为Python3.3):

'''
线性搜索子函数
'''

import numpy as np
import random

def goldsteinsearch(f,df,d,x,alpham,rho,t):

  flag=0

  a=0
  b=alpham
  fk=f(x)
  gk=df(x)

  phi0=fk
  dphi0=np.dot(gk,d)

  alpha=b*random.uniform(0,1)

  while(flag==0):
    newfk=f(x+alpha*d)
    phi=newfk
    if(phi-phi0<=rho*alpha*dphi0):
      if(phi-phi0>=(1-rho)*alpha*dphi0):
        flag=1
      else:
        a=alpha
        b=b
        if(b<alpham):
          alpha=(a+b)/2
        else:
          alpha=t*alpha
    else:
      a=a
      b=alpha
      alpha=(a+b)/2
  return alpha

上述函数的输入参数主要包括一个多元函数f,其导数df,当前迭代点x和当前搜索方向d,返回值是根据Goldstein准则确定的搜索步长。

我们仍以Rosenbrock函数为例,即有

用Python实现最速下降法求极值的方法

于是可得函数的梯度为

用Python实现最速下降法求极值的方法

最速下降法的代码如下:

"""
最速下降法
Rosenbrock函数
函数 f(x)=100*(x(2)-x(1).^2).^2+(1-x(1)).^2
梯度 g(x)=(-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1)),200*(x(2)-x(1)^2))^(T)
"""

import numpy as np
import matplotlib.pyplot as plt
import random
import linesearch
from linesearch import goldsteinsearch

def rosenbrock(x):
  return 100*(x[1]-x[0]**2)**2+(1-x[0])**2

def jacobian(x):
  return np.array([-400*x[0]*(x[1]-x[0]**2)-2*(1-x[0]),200*(x[1]-x[0]**2)])


X1=np.arange(-1.5,1.5+0.05,0.05)
X2=np.arange(-3.5,2+0.05,0.05)
[x1,x2]=np.meshgrid(X1,X2)
f=100*(x2-x1**2)**2+(1-x1)**2; # 给定的函数
plt.contour(x1,x2,f,20) # 画出函数的20条轮廓线

def steepest(x0):

  print('初始点为:')
  print(x0,'\n')  
  imax = 20000
  W=np.zeros((2,imax))
  W[:,0] = x0
  i = 1   
  x = x0
  grad = jacobian(x)
  delta = sum(grad**2) # 初始误差


  while i<imax and delta>10**(-5):
    p = -jacobian(x)
    x0=x
    alpha = goldsteinsearch(rosenbrock,jacobian,p,x,1,0.1,2)
    x = x + alpha*p
    W[:,i] = x
    grad = jacobian(x)
    delta = sum(grad**2)
    i=i+1

  print("迭代次数为:",i)
  print("近似最优解为:")
  print(x,'\n')  
  W=W[:,0:i] # 记录迭代点
  return W

x0 = np.array([-1.2,1])
W=steepest(x0)

plt.plot(W[0,:],W[1,:],'g*',W[0,:],W[1,:]) # 画出迭代点收敛的轨迹
plt.show()

为了实现不同文件中函数的调用,我们先用import函数导入了线性搜索的子函数,也就是下面的2行代码

import linesearch
from linesearch import goldsteinsearch

当然,如果把定义goldsteinsearch函数的代码直接放到程序里面,就不需要这么麻烦了,但是那样的话,不仅会使程序显得很长,而且不便于goldsteinsearch函数的重用。

此外,Python对函数式编程也支持的很好,在定义goldsteinsearch函数时,可以允许抽象的函数f,df作为其输入参数,只要在调用时实例化就可以了。与Matlab不同的是,传递函数作为参数时,Python是不需要使用@将其变为函数句柄的。

运行结果为

初始点为:

[-1.2 1. ] 

迭代次数为: 1504

近似最优解为:

[ 1.00318532 1.00639618]

迭代点的轨迹为

用Python实现最速下降法求极值的方法

由于在线性搜索子程序中使用了随机函数,初始搜索点是随机产生的,因此每次运行的结果不太相同,比如再运行一次程序,得到

初始点为:
[-1.2 1. ] 

迭代次数为: 1994

近似最优解为:
[ 0.99735222 0.99469882]

所得图像为

用Python实现最速下降法求极值的方法

以上这篇用Python实现最速下降法求极值的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python网络编程学习笔记(一)
Jun 09 Python
python人人网登录应用实例
Sep 26 Python
matplotlib绘制符合论文要求的图片实例(必看篇)
Jun 02 Python
python 实现tar文件压缩解压的实例详解
Aug 20 Python
Odoo中如何生成唯一不重复的序列号详解
Feb 10 Python
django认证系统实现自定义权限管理的方法
Jul 16 Python
用python3教你任意Html主内容提取功能
Nov 05 Python
Python3按一定数据位数格式处理bin文件的方法
Jan 24 Python
如何使用Flask-Migrate拓展数据库表结构
Jul 24 Python
解决pycharm最左侧Tool Buttons显示不全的问题
Dec 17 Python
解决ROC曲线画出来只有一个点的问题
Feb 28 Python
使用Python获取字典键对应值的方法
Apr 26 Python
python networkx 根据图的权重画图实现
Jul 10 #Python
python networkx 包绘制复杂网络关系图的实现
Jul 10 #Python
python卸载后再次安装遇到的问题解决
Jul 10 #Python
Python求离散序列导数的示例
Jul 10 #Python
Python Matplotlib 基于networkx画关系网络图
Jul 10 #Python
我们为什么要减少Python中循环的使用
Jul 10 #Python
详解Python中的各种转义符\n\r\t
Jul 10 #Python
You might like
PHP5中新增stdClass 内部保留类
2011/06/13 PHP
PHP生成验证码时“图像因其本身有错无法显示”的解决方法
2013/08/07 PHP
PHP临时文件的安全性分析
2014/07/04 PHP
PHP判断IP并转跳到相应城市分站的方法
2015/03/25 PHP
在PHP程序中使用Rust扩展的方法
2015/07/03 PHP
PHP abstract 抽象类定义与用法示例
2018/05/29 PHP
js 图片轮播(5张图片)
2008/12/30 Javascript
Javascript之旅 对象的原型链之由来
2010/08/25 Javascript
jQuery的运行机制和设计理念分析
2011/04/05 Javascript
js冒泡、捕获事件及阻止冒泡方法详细总结
2014/05/08 Javascript
javaScript中两个等于号和三个等于号之间的区别介绍
2014/06/27 Javascript
详解JavaScript的Polymer框架中的通知交互
2015/07/29 Javascript
JQuery对ASP.NET MVC数据进行更新删除
2016/07/13 Javascript
angular.js之路由的选择方法
2016/09/24 Javascript
微信小程序  audio音频播放详解及实例
2016/11/02 Javascript
js模糊查询实例分享
2016/12/26 Javascript
JavaScript中数组Array方法详解
2017/02/27 Javascript
简单快速的实现js计算器功能
2017/08/17 Javascript
JS实现带导航城市列表以及输入搜索功能
2018/01/04 Javascript
webpack4+Vue搭建自己的Vue-cli项目过程分享
2018/08/29 Javascript
vue 界面刷新数据被清除 localStorage的使用详解
2018/09/16 Javascript
javascript中函数的写法实例代码详解
2018/10/28 Javascript
vue-cli中安装方法(图文详细步骤)
2018/12/12 Javascript
在vue中利用全局路由钩子给url统一添加公共参数的例子
2019/11/01 Javascript
vue+element获取el-table某行的下标,根据下标操作数组对象方式
2020/08/07 Javascript
Python编程中用close()方法关闭文件的教程
2015/05/24 Python
Jupyter Notebook远程登录及密码设置操作
2020/04/10 Python
HTML5各种头部meta标签的功能(推荐)
2017/03/13 HTML / CSS
俄罗斯购买自行车网站:Vamvelosiped
2021/01/29 全球购物
weblogic面试题
2016/03/07 面试题
大学生职业规划前言模板
2013/12/27 职场文书
幼儿园英语教学反思
2014/01/30 职场文书
2016年大学生党员承诺书
2016/03/24 职场文书
python 下载文件的几种方式分享
2021/04/07 Python
MySQL运行报错:“Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre”解决方法
2022/06/14 MySQL
Java实现HTML转为Word的示例代码
2022/06/28 Java/Android