用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将阿拉伯数字转换为罗马数字的方法
Jul 10 Python
实例讲解Python设计模式编程之工厂方法模式的使用
Mar 02 Python
详解duck typing鸭子类型程序设计与Python的实现示例
Jun 03 Python
PyCharm使用教程之搭建Python开发环境
Jun 07 Python
详解如何使用Python编写vim插件
Nov 28 Python
python @property的用法及含义全面解析
Feb 01 Python
Django 跨域请求处理的示例代码
May 02 Python
Python3实现的字典、列表和json对象互转功能示例
May 22 Python
如何使用Flask-Migrate拓展数据库表结构
Jul 24 Python
python openCV自制绘画板
Oct 27 Python
PyMongo 查询数据的实现
Jun 28 Python
Python 数据可视化工具 Pyecharts 安装及应用
Apr 20 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
中国的第一台收音机
2021/03/01 无线电
PHP表单递交控件名称含有点号(.)会被转化为下划线(_)的处理方法
2013/01/06 PHP
如何用PHP实现插入排序?
2013/04/10 PHP
解析php开发中的中文编码问题
2013/08/08 PHP
php过滤HTML标签、属性等正则表达式汇总
2014/09/22 PHP
PHP中使用file_get_contents抓取网页中文乱码问题解决方法
2014/12/17 PHP
thinkPHP5使用Rabc实现权限管理
2019/08/28 PHP
Stop SQL Server
2007/06/21 Javascript
js加解密 脚本解密
2008/02/22 Javascript
javascript引导程序
2008/10/26 Javascript
JavaScript实现基于Cookie的存储类实例
2015/04/10 Javascript
AngularJS实现全选反选功能
2015/12/08 Javascript
Boostrap模态窗口的学习小结
2016/03/28 Javascript
node.js路径处理方法以及绝对路径详解
2021/03/04 Javascript
vue实现tab切换外加样式切换方法
2018/03/16 Javascript
详解vue2.0+axios+mock+axios-mock+adapter实现登陆
2018/07/19 Javascript
详解ES6 系列之异步处理实战
2018/10/26 Javascript
详解JS判断页面是在手机端还是在PC端打开的方法
2019/04/26 Javascript
Vue分页器实现原理详解
2019/06/28 Javascript
Node.js学习教程之Module模块
2019/09/03 Javascript
Vue开发环境跨域访问问题
2020/01/22 Javascript
python中的yield使用方法
2014/02/11 Python
Python脚本实现DNSPod DNS动态解析域名
2015/02/14 Python
使用url_helper简化Python中Django框架的url配置教程
2015/05/30 Python
python实现单线程多任务非阻塞TCP服务端
2017/06/13 Python
使用python语言,比较两个字符串是否相同的实例
2018/06/29 Python
如何使用Pytorch搭建模型
2020/10/26 Python
一款利用纯css3实现的超炫3D表单的实例教程
2014/12/01 HTML / CSS
websocket+sockjs+stompjs详解及实例代码
2018/11/30 HTML / CSS
详解HTML5中的manifest缓存使用
2015/09/09 HTML / CSS
女装和独特珠宝:Sundance Catalog
2018/09/19 全球购物
应届生的求职推荐信范文
2013/11/30 职场文书
汽车制造与装配专业自荐信范文
2014/01/02 职场文书
个人简历自我评价
2014/02/02 职场文书
《揠苗助长》教学反思
2016/02/20 职场文书
图解上海144收音机
2021/04/22 无线电