用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 相关文章推荐
python3生成随机数实例
Oct 20 Python
Python实现提取谷歌音乐搜索结果的方法
Jul 10 Python
教你用python3根据关键词爬取百度百科的内容
Aug 18 Python
Python提取网页中超链接的方法
Sep 18 Python
解决pyttsx3无法封装的问题
Dec 24 Python
python tools实现视频的每一帧提取并保存
Mar 20 Python
python求最大值最小值方法总结
Jun 25 Python
python函数不定长参数使用方法解析
Dec 14 Python
计算pytorch标准化(Normalize)所需要数据集的均值和方差实例
Jan 15 Python
python中列表的含义及用法
May 26 Python
python实现web邮箱扫描的示例(附源码)
Mar 30 Python
从np.random.normal()到正态分布的拟合操作
Jun 02 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/11/20 PHP
如何使用php绘制在图片上的正余弦曲线
2013/06/08 PHP
培养自己的php编码规范
2015/09/28 PHP
jquery插件制作 图片走廊 gallery
2012/08/17 Javascript
js取整数、取余数的方法
2014/05/11 Javascript
JavaScript拆分字符串时产生空字符的解决方案
2014/09/26 Javascript
关于编写性能高效的javascript事件的技术
2014/11/28 Javascript
JS实现一个按钮的方法
2015/02/05 Javascript
JavaScript动态提示输入框输入字数的方法
2015/07/27 Javascript
Jquery和angularjs获取check框选中的值的方法汇总
2016/01/17 Javascript
JS、jQuery中select的用法详解
2016/04/21 Javascript
详解基于angular-cli配置代理解决跨域请求问题
2017/07/05 Javascript
微信小程序授权获取用户详细信息openid的实例详解
2017/09/20 Javascript
vue.js分页中单击页码更换页面内容的方法(配合spring springmvc)
2018/02/10 Javascript
vue2.0使用v-for循环制作多级嵌套菜单栏
2018/06/25 Javascript
Vue+Koa2+mongoose写一个像素绘板的实现方法
2019/09/10 Javascript
JavaScript使用localStorage存储数据
2019/09/25 Javascript
js代码实现轮播图
2020/05/04 Javascript
[49:54]Ti4 循环赛第三日 LGD vs Titan
2014/07/12 DOTA
Python ljust rjust center输出
2008/09/06 Python
Ubuntu16.04/树莓派Python3+opencv配置教程(分享)
2018/04/02 Python
python中的句柄操作的方法示例
2019/06/20 Python
python搜索包的路径的实现方法
2019/07/19 Python
Python实现AI自动抠图实例解析
2020/03/05 Python
python Selenium 库的使用技巧
2020/10/16 Python
使用python对excel表格处理的一些小功能
2021/01/25 Python
Python+Appium实现自动化清理微信僵尸好友的方法
2021/02/04 Python
利用Node实现HTML5离线存储的方法
2020/10/16 HTML / CSS
西尔斯百货官网:Sears
2016/09/06 全球购物
Lookfantastic葡萄牙官方网站:欧洲第一大化妆品零售商
2018/03/17 全球购物
adidas澳大利亚官方网站:adidas Australia
2018/04/15 全球购物
三年级数学教学反思
2014/01/31 职场文书
客服部班长工作责任制
2014/02/25 职场文书
2014年教育工作总结
2014/11/26 职场文书
介绍信如何写
2015/01/31 职场文书
Python中Matplotlib的点、线形状、颜色以及绘制散点图
2022/04/07 Python