用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 mysqldb连接数据库
Mar 16 Python
Django发送html邮件的方法
May 26 Python
详解Python中的from..import绝对导入语句
Jun 21 Python
python实现八大排序算法(2)
Sep 14 Python
K-means聚类算法介绍与利用python实现的代码示例
Nov 13 Python
Tensorflow使用tfrecord输入数据格式
Jun 19 Python
解决python3 安装完Pycurl在import pycurl时报错的问题
Oct 15 Python
Python清空文件并替换内容的实例
Oct 22 Python
pandas重新生成索引的方法
Nov 06 Python
python 实现多维数组(array)排序
Feb 28 Python
Kmeans均值聚类算法原理以及Python如何实现
Sep 26 Python
python 合并多个excel中同名的sheet
Jan 22 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
apache php mysql开发环境安装教程
2016/07/28 PHP
PHP迭代与递归实现无限级分类
2017/08/28 PHP
JavaScript 学习 - 提高篇
2007/02/02 Javascript
读jQuery之十三 添加事件和删除事件的核心方法
2011/08/23 Javascript
js点击更换背景颜色或图片的实例代码
2013/06/25 Javascript
jquery实现图片翻页效果
2013/12/23 Javascript
javascript使用正则表达式检测IP地址
2014/12/03 Javascript
jquery队列函数用法实例
2014/12/16 Javascript
JS获取及设置TextArea或input文本框选择文本位置的方法
2015/03/24 Javascript
JavaScript数据结构与算法之集合(Set)
2016/01/29 Javascript
深入理解JavaScript中的并行处理
2016/09/22 Javascript
JS实现改变HTML上文字颜色和内容的方法
2016/12/30 Javascript
JS jQuery使用正则表达式去空字符的简单实现代码
2017/05/20 jQuery
JavaScript实现二维坐标点排序效果
2017/07/18 Javascript
微信小程序支付及退款流程详解
2017/11/30 Javascript
Vue-cli Eslint在vscode里代码自动格式化的方法
2018/02/23 Javascript
解决vue.js 数据渲染成功仍报错的问题
2018/08/25 Javascript
在Create React App中使用CSS Modules的方法示例
2019/01/15 Javascript
layui实现数据表格table分页功能(ajax异步)
2019/07/27 Javascript
Vue常用传值方式、父传子、子传父及非父子实例分析
2020/02/24 Javascript
VSCode 添加自定义注释的方法(附带红色警戒经典注释风格)
2020/08/27 Javascript
[01:45]2014DOTA2 TI预选赛预选赛 战前探营!
2014/05/21 DOTA
详解Python装饰器由浅入深
2016/12/09 Python
python用Pygal如何生成漂亮的SVG图像详解
2017/02/10 Python
numpy自动生成数组详解
2017/12/15 Python
Django ImageFiled上传照片并显示的方法
2019/07/28 Python
Python学习笔记之lambda表达式用法详解
2019/08/08 Python
Python判断字符串是否为空和null方法实例
2020/04/26 Python
英国最大的奢侈品零售网络商城:Flannels
2016/09/16 全球购物
幼儿教师自我鉴定
2013/11/02 职场文书
初三政治教学反思
2014/01/30 职场文书
作风建设年活动实施方案
2014/10/24 职场文书
2015少先队大队辅导员工作总结
2015/07/24 职场文书
一年之计:2019年下半年的计划
2019/05/07 职场文书
详解JVM系列之内存模型
2021/06/10 Javascript
Windows Server 2019 配置远程控制以及管理方法
2022/04/28 Servers