用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中lambda()的用法
Nov 16 Python
Python os.rename() 重命名目录和文件的示例
Oct 25 Python
Python3实现爬虫爬取赶集网列表功能【基于request和BeautifulSoup模块】
Dec 05 Python
python小程序实现刷票功能详解
Jul 17 Python
Python数据处理篇之Sympy系列(五)---解方程
Oct 12 Python
python 实现dict转json并保存文件
Dec 05 Python
python 解决cv2绘制中文乱码问题
Dec 23 Python
完美解决pycharm 不显示代码提示问题
Jun 02 Python
python读取excel数据绘制简单曲线图的完整步骤记录
Oct 30 Python
python中Pexpect的工作流程实例讲解
Mar 02 Python
Python基于百度AI实现抓取表情包
Jun 27 Python
Python代码实现双链表
May 25 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
星际争霸, 教主第一视角, ZvT经典龙蛇演义
2020/03/02 星际争霸
2020年4月新番动漫目录 官方宣布4月播出的作品一览
2020/03/08 日漫
奉献出一个封装的curl函数 便于调用(抓数据专用)
2013/07/22 PHP
PHP处理大量表单字段的便捷方法
2015/02/07 PHP
yii2实现 &quot;上一篇,下一篇&quot; 功能的代码实例
2017/02/04 PHP
php实现表单提交上传文件功能
2018/05/28 PHP
用jquery ajax获取网站Alexa排名的代码
2009/12/12 Javascript
jQuery下通过$.browser来判断浏览器.
2011/04/05 Javascript
jquery实现商品拖动选择效果代码(自写)
2013/05/28 Javascript
js获取页面description的方法
2015/05/21 Javascript
JavaScript中的Math.SQRT1_2属性使用简介
2015/06/14 Javascript
JavaScript深度复制(deep clone)的实现方法
2016/02/19 Javascript
输入法的回车与消息发送快捷键回车的冲突解决方法
2016/08/09 Javascript
BootStrap Fileinput上传插件使用实例代码
2017/07/28 Javascript
微信小程序中显示倒计时代码实例
2019/05/09 Javascript
JavaScript实现网页tab栏效果制作
2020/11/20 Javascript
JS中箭头函数与this的写法和理解
2021/01/14 Javascript
[28:28]Ti4 冒泡赛第二天NEWBEE vs NaVi 2
2014/07/15 DOTA
[45:25]完美世界DOTA2联赛循环赛 PXG vs IO 第一场 11.06
2020/11/09 DOTA
Python实现的排列组合、破解密码算法示例
2019/04/12 Python
python基于递归解决背包问题详解
2019/07/03 Python
python爬虫项目设置一个中断重连的程序的实现
2019/07/26 Python
修改Pandas的行或列的名字(重命名)
2019/12/18 Python
基于python实现可视化生成二维码工具
2020/07/08 Python
一文解决django 2.2与mysql兼容性问题
2020/07/15 Python
python openssl模块安装及用法
2020/12/06 Python
html5新特性与用法大全
2018/09/13 HTML / CSS
HTML5标签使用方法详解
2015/11/27 HTML / CSS
Pretty Little Thing美国:时尚女性服饰
2018/08/27 全球购物
舞蹈比赛获奖感言
2014/02/04 职场文书
广告设计应届生求职信
2014/03/01 职场文书
信访维稳工作汇报
2014/10/27 职场文书
实习推荐信格式模板
2015/03/27 职场文书
学生检讨书怎么写
2015/05/07 职场文书
2016年119消防宣传日活动总结
2016/04/05 职场文书
警用民用对讲机找不同
2022/02/18 无线电