用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获取GY-85九轴模块信息示例
Dec 05 Python
在Django框架中设置语言偏好的教程
Jul 27 Python
Python实现的微信支付方式总结【三种方式】
Apr 13 Python
python装饰器常见使用方法分析
Jun 26 Python
django框架使用方法详解
Jul 18 Python
django的分页器Paginator 从django中导入类
Jul 25 Python
详解程序意外中断自动重启shell脚本(以Python为例)
Jul 26 Python
python利用百度云接口实现车牌识别的示例
Feb 21 Python
Python私有属性私有方法应用实例解析
Sep 15 Python
pandas 数据类型转换的实现
Dec 29 Python
2021年值得向Python开发者推荐的VS Code扩展插件
Jan 25 Python
10个顶级Python实用库推荐
Mar 04 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
PHP实时显示输出
2008/10/02 PHP
PHP按指定键值对二维数组进行排序的方法
2015/12/22 PHP
php的4种常用运行方式详解
2016/12/22 PHP
PHP获取数组中单列值的方法
2017/06/10 PHP
PHP数组内存利用率低和弱类型详细解读
2017/08/10 PHP
laravel中短信发送验证码的实现方法
2018/04/25 PHP
javascript 支持ie和firefox杰奇翻页函数
2008/07/22 Javascript
js面向对象设计用{}好还是function(){}好(构造函数)
2011/10/23 Javascript
浅析js中取绝对值的2种方法
2013/07/09 Javascript
在Ubuntu系统上安装Ghost博客平台的教程
2015/06/17 Javascript
JS实现黑色大气的二级导航菜单效果
2015/09/18 Javascript
详解JavaScript的AngularJS框架中的作用域与数据绑定
2016/03/04 Javascript
JavaScript设计模式之单体模式全面解析
2016/09/09 Javascript
JS排序之冒泡排序详解
2017/04/08 Javascript
JavaScript中双向数据绑定详解
2017/05/03 Javascript
深入浅出webpack教程系列_安装与基本打包用法和命令参数详解
2017/09/10 Javascript
详解PHP后期静态绑定分析与应用
2018/03/21 Javascript
Javasript设计模式之链式调用详解
2018/04/26 Javascript
详解vue更改头像功能实现
2019/04/28 Javascript
elementUI select组件使用及注意事项详解
2019/05/29 Javascript
NodeJS有难度的面试题(能答对几个)
2019/10/09 NodeJs
JS如何生成动态列表
2020/09/22 Javascript
[01:45]2014DOTA2 TI预选赛预选赛 大神专访第二弹!
2014/05/20 DOTA
Python实现获取邮箱内容并解析的方法示例
2018/06/16 Python
python实现textrank关键词提取
2018/06/22 Python
python微信公众号之关注公众号自动回复
2018/10/25 Python
PIL对上传到Django的图片进行处理并保存的实例
2019/08/07 Python
Python列表去重复项的N种方法(实例代码)
2020/05/12 Python
html5 跨文档消息传输示例探讨
2013/04/01 HTML / CSS
美国女孩洋娃娃店:American Girl
2017/10/24 全球购物
好的自荐信的要求
2013/10/30 职场文书
小学美术兴趣小组活动总结
2014/07/07 职场文书
2014年创卫工作总结
2014/11/24 职场文书
2014年学生管理工作总结
2014/12/20 职场文书
2015年全国科普日活动总结
2015/03/23 职场文书
女方家长婚礼致辞
2015/07/27 职场文书