用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中的map()函数和reduce()函数的用法
Apr 27 Python
Django中模型Model添加JSON类型字段的方法
Jun 17 Python
用python写的一个wordpress的采集程序
Feb 27 Python
Tensorflow简单验证码识别应用
May 25 Python
python的常用模块之collections模块详解
Dec 06 Python
Python3.5面向对象编程图文与实例详解
Apr 24 Python
python打包exe开机自动启动的实例(windows)
Jun 28 Python
python os模块常用的29种方法使用详解
Jun 02 Python
keras 读取多标签图像数据方式
Jun 12 Python
如何让python的运行速度得到提升
Jul 08 Python
Python列表嵌套常见坑点及解决方案
Sep 30 Python
Python3中小括号()、中括号[]、花括号{}的区别详解
Nov 15 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
drupal 代码实现URL重写
2011/05/04 PHP
PHP把空格、换行符、中文逗号等替换成英文逗号的正则表达式
2014/05/04 PHP
PHP使用Mysqli类库实现完美分页效果的方法
2016/04/07 PHP
PHP网页缓存技术优点及代码实例
2020/07/29 PHP
用js实现下载远程文件并保存在本地的脚本
2008/05/06 Javascript
JQuery从头学起第一讲
2010/07/04 Javascript
validator验证控件使用代码
2010/11/23 Javascript
打造基于jQuery的高性能TreeView(asp.net)
2011/02/23 Javascript
jquery中map函数与each函数的区别实例介绍
2014/06/23 Javascript
jquery uploadify 在FF下无效的解决办法
2014/09/26 Javascript
JavaScript检测鼠标移动方向的方法
2015/05/22 Javascript
AngularJS基础 ng-mouseenter 指令示例代码
2016/08/02 Javascript
jQuery子元素过滤选择器用法示例
2016/09/09 Javascript
BootStrap table使用方法分析
2016/11/08 Javascript
react.js使用webpack搭配环境的入门教程
2017/08/14 Javascript
AngularJS模糊查询功能实现代码(过滤内容下拉菜单排序过滤敏感字符验证判断后添加表格信息)
2017/10/24 Javascript
js实现数组内数据的上移和下移的实例
2017/11/14 Javascript
Vue中this.$router.push参数获取方法
2018/02/27 Javascript
详解ES6 Fetch API HTTP请求实用指南
2018/11/14 Javascript
LayUI switch 开关监听 获取属性值、更改状态的方法
2019/09/21 Javascript
python实现字符串和日期相互转换的方法
2015/05/13 Python
Python实现多线程抓取妹子图
2015/08/08 Python
Python实现对象转换为xml的方法示例
2017/06/08 Python
Python使用wget实现下载网络文件功能示例
2018/05/31 Python
Python基于pyCUDA实现GPU加速并行计算功能入门教程
2018/06/19 Python
详解Python解决抓取内容乱码问题(decode和encode解码)
2019/03/29 Python
Python opencv实现人眼/人脸识别以及实时打码处理
2019/04/29 Python
利用python如何在前程无忧高效投递简历
2019/05/07 Python
Python中list的交、并、差集获取方法示例
2019/08/01 Python
python批量处理文件或文件夹
2020/07/28 Python
会计职业生涯规划书
2014/01/13 职场文书
幼儿园课题实施方案
2014/05/14 职场文书
委托书怎么写
2014/07/31 职场文书
高一课前三分钟演讲稿
2014/09/13 职场文书
Python list去重且保持原顺序不变的方法
2021/04/03 Python
mysql部分操作
2021/04/05 MySQL