常见优化算法实现

这里实现的主要算法有:

一维搜索方法:

黄金分割法

二次差值法

多维搜索算法

最速下降法

partan加速的最速下降法

共轭梯度法

牛顿法

拟牛顿法

使用函数表示一个用于优化的目标,包括其梯度函数和hessian矩阵函数

import numpy as np
import math
#用于测试的一个多元函数的例子
def f(x):
return (x[0]-1)**2+5*(x[1]-5)**2+(x[2]-1)**2+5*(x[3]-5)**2 #f(x)函数的gradient向量计算函数
def g(x):
return np.array([2*(x[0]-1),10*(x[1]-5),2*(x[2]-1),10*(x[3]-5)]) #f(x)函数的hessian矩阵的逆矩阵计算函数
def hi(x=None):
h=[1/2,1/10,1/2,1/10]
return np.diag(h)

拟牛顿法

def quasi_newton(f=f,x0=np.zeros(4),gradient=g,acc=0.001):
k=0
x=x0
xp=None
hpk=None
gpk=None while True:
gk=gradient(x)
#print(gk)
if np.sum(gk**2)<=acc:
#print("迭代 %d 次"%(k+1))
return x,np.round(f(x),5)
if k==0:
hik=np.eye(x0.shape[0])
else:
dx=x-xp
dg=gk-gpk temp = (dx-np.dot(hpk,dg)).reshape((-1,1))
hik=hpk + np.dot(temp,temp.transpose())/(np.dot(temp.transpose(),dg.reshape((-1,1))))
#print(hik) pk=-1*np.dot(hik,gk)
alpha,y=quadraticInterploation(lambda alpha:(f(alpha*pk+x)),0,10,0.001)
#更新变量
x=alpha*pk+x
hpk=hik
xp=x
gpk=gk
k+=1

共轭方向法

def conjugate_direction(f=f,x0=np.zeros(4),gradient=g,acc=0.001):
k=0
x=x0
#设置初值
gpk=x0
ppk=x0 while True:
gk=gradient(x)
#print(gk)
if np.sum(gk**2)<=acc:
#print("迭代 %d 次"%(k+1))
return x,np.round(f(x),5)
if k==0:
pk=-1*gk
else:
betak=np.sum(gk*gk)/np.sum(gpk*gpk)
pk=-1*gk+betak*ppk
#lambda表达式可以使用上层函数中的变量,这样对于不同的上下文,就是不同的函数
alpha,y=quadraticInterploation(lambda alpha:(f(alpha*pk+x)),0,10,0.001)
x=alpha*pk+x
ppk=pk
gpk=gk
k+=1

最速下降法

#最速下降法
def steepestDescent(f=f,x0=np.zeros(4),gradient=g,acc=0.001):
k=0
x=x0
while True:
gk=gradient(x)
pk=-1*gk
if np.sum(gk**2)<=acc:
#print("迭代 %d 次"%(k+1))
return x,f(x)
#lambda表达式可以使用上层函数中的变量,这样对于不同的上下文,就是不同的函数
alpha,y=quadraticInterploation(lambda alpha:(f(alpha*pk+x)),0,10,0.001)
x=alpha*pk+x
k+=1

牛顿法

def newton(f=f,x0=np.zeros(4),gradient=g,hessian=hi,acc=0.001):
k=0
x=x0
while True:
gk=gradient(x)
hik=hessian(x)
pk=-1*np.dot(gk,hik)
if np.sum(gk**2)<=acc:
#print("迭代 %d 次"%(k+1))
return x,f(x)
#lambda表达式可以使用上层函数中的变量,这样对于不同的上下文,就是不同的函数
alpha,y=quadraticInterploation(lambda alpha:(f(alpha*pk+x)),0,10,0.001)
x=alpha*pk+x
k+=1

使用partan加速的最速下降法

def partan(f=f,x0=np.zeros(4),gradient=g,acc=0.001,N=3):
k=0
x=x0
xp1=x0
xp2=x0
while True:
if k>=N and k%3==0:
pk=x-xp2
else:
gk=gradient(x)
pk=-1*gk
if np.sum(pk**2)<=acc:
#print("迭代 %d 次"%(k+1))
return x,f(x)
#lambda表达式可以使用上层函数中的变量,这样对于不同的上下文,就是不同的函数
alpha,y=quadraticInterploation(lambda alpha:(f(alpha*pk+x)),0,10,0.001)
xp2=xp1
xp1=x
x=alpha*pk+x
k+=1

一维搜索的黄金分割方法

def goldenSegmantation(f,a,b,acc):
x1=a+0.382*(b-a)
x2=b-(x1-a)
R=f(x1);G=f(x2)
#因为浮点数的舍入误差,可能导致a,b的大小逆转
while abs(b-a)>acc and a<=x1<x2<=b:
#print(abs(b-a))
if R>G:
a=x1
x1=x2
R=G
x2=b-(x1-a)
G=f(x2)
else:
b=x2
x2=x1
G=R
x1=a+(b-x2)
R=f(x1)
return (a+b)/2.0,f(((a+b)/2.0))

一维搜索的二次差值方法

def quadraticInterploation(f,a,b,acc):
assert(a<b)
x1=a;x2=(a+b)/2;x3=b
f1=f(x1);f2=f(x2);f3=f(x3)
while True:
c1=(f3-f1)/(x3-x1);c2=((f2-f1)/(x2-x1)-c1)/(x2-x3)
xp=0.5*(x1+x3-c1/c2)
fp=f(xp)
if abs(xp-x2)<acc or not a<=x1<x2<x3<=b:
if fp<f2:
return xp,fp
else:
return x2,f2
if x2<xp:
if f2<fp:
x3=xp;f3=fp
else:
x1=x2;f1=f2
x2=xp;f2=fp
else:
if f2<fp:
x1=xp;f1=fp
else:
x3=x2;f3=f2
x2=xp;f2=fp

测试一维搜索方法

%timeit(goldenSegmantation(lambda x:(x**4-5),-1,1,0.0001))
%timeit(quadraticInterploation(lambda x:(x**4-5),-1,1,0.00001))
%timeit(goldenSegmantation(lambda x:(x**2-5*x+6),-10,10,0.00000005))
%timeit(quadraticInterploation(lambda x:(x**2-5*x+6),-10,10,0.000001))
%timeit(goldenSegmantation(math.sin,-1*math.pi,0,0.000001))
%timeit(quadraticInterploation(math.sin,-1*math.pi,0,0.0000001))
11.3 µs ± 58.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
3.09 µs ± 18.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
12.5 µs ± 47.9 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
5.44 µs ± 27.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
7.97 µs ± 33.1 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
2.05 µs ± 19.5 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

结果分析

对于不同的目标函数,二次插值的速度均大于黄金分割方法

测试高维搜索方法

%timeit steepestDescent()
%timeit partan()
%timeit conjugate_direction()
%timeit newton()
%timeit quasi_newton()
236 µs ± 2.39 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
297 µs ± 2.39 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
197 µs ± 1.49 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
125 µs ± 276 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
224 µs ± 1.28 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

结果分析

从结果看出来,partan加速方法相比最速下降方法并没有什么优势,主要原因是目标函数太简单,迭代次数太少

拟牛顿法相比最速下降法也没有什么优势,我想也是基于同样的原因

常见优化算法统一框架下的实现:最速下降法,partan加速的最速下降法,共轭梯度法,牛顿法,拟牛顿法,黄金分割法,二次插值法的更多相关文章

  1. 最优化算法——常见优化算法分类及总结

    之前做特征选择,实现过基于群智能算法进行最优化的搜索,看过一些群智能优化算法的论文,在此做一下总结. 在生活或者工作中存在各种各样的最优化问题,比如每个企业和个人都要考虑的一个问题"在一定成 ...

  2. 优化深度神经网络(二)优化算法 SGD Momentum RMSprop Adam

    Coursera吴恩达<优化深度神经网络>课程笔记(2)-- 优化算法 深度机器学习中的batch的大小 深度机器学习中的batch的大小对学习效果有何影响? 1. Mini-batch ...

  3. zz:一个框架看懂优化算法之异同 SGD/AdaGrad/Adam

    首先定义:待优化参数:  ,目标函数: ,初始学习率 . 而后,开始进行迭代优化.在每个epoch  : 计算目标函数关于当前参数的梯度:  根据历史梯度计算一阶动量和二阶动量:, 计算当前时刻的下降 ...

  4. 一个框架看懂优化算法之异同 SGD/AdaGrad/Adam

    Adam那么棒,为什么还对SGD念念不忘 (1) —— 一个框架看懂优化算法 机器学习界有一群炼丹师,他们每天的日常是: 拿来药材(数据),架起八卦炉(模型),点着六味真火(优化算法),就摇着蒲扇等着 ...

  5. Adam那么棒,为什么还对SGD念念不忘 (1) —— 一个框架看懂优化算法

    机器学习界有一群炼丹师,他们每天的日常是: 拿来药材(数据),架起八卦炉(模型),点着六味真火(优化算法),就摇着蒲扇等着丹药出炉了. 不过,当过厨子的都知道,同样的食材,同样的菜谱,但火候不一样了, ...

  6. 解析基于keras深度学习框架下yolov3的算法

    一.前言 由于前一段时间以及实现了基于keras深度学习框架下yolov3的算法,本来想趁着余热将自己的心得体会进行总结,但由于前几天有点事就没有完成计划,现在趁午休时间整理一下. 二.Keras框架 ...

  7. [Algorithm] 群体智能优化算法之粒子群优化算法

    同进化算法(见博客<[Evolutionary Algorithm] 进化算法简介>,进化算法是受生物进化机制启发而产生的一系列算法)和人工神经网络算法(Neural Networks,简 ...

  8. 深度学习必备:随机梯度下降(SGD)优化算法及可视化

    补充在前:实际上在我使用LSTM为流量基线建模时候,发现有效的激活函数是elu.relu.linear.prelu.leaky_relu.softplus,对应的梯度算法是adam.mom.rmspr ...

  9. 【优化算法】遗传算法GA求解混合流水车间调度问题(附C++代码)

    00 前言 各位读者大家好,好久没有介绍算法的推文了,感觉愧对了读者们热爱学习的心灵.于是,今天我们带来了一个神奇的优化算法--遗传算法! 它的优点包括但不限于: 遗传算法对所求解的优化问题没有太多的 ...

随机推荐

  1. win10 uwp 上传Nuget 让别人用我们的库

    Nuget 我们的开发经常使用别人的dll,那么我们需要每次都从网上下载,然后复制到我们的项目, 而不知道我们的dll是否安全? 当我们的库更新的时候,我们又需要从网上搜索,这样不好,于是我们就用Nu ...

  2. 浅谈javascript继承体系

    最近做web项目,接触了jquery等框架,虽然使用方便,但是还是想学习下Javascript,今天分享下最近对js原型继承的理解,不足之处欢迎指正. 一.构造器的原型属性与原型对象 刚接触js时通常 ...

  3. Java8之旅(七) - 函数式备忘录模式优化递归

    前言 在上一篇开始Java8之旅(六) -- 使用lambda实现Java的尾递归中,我们利用了函数的懒加载机制实现了栈帧的复用,成功的实现了Java版本的尾递归,然而尾递归的使用有一个重要的条件就是 ...

  4. 基于HTML5及WebGl下生成的json格式的工控SCADA风机叶轮旋转

    突然有个想法,如果能把一些用到不同的知识点放到同一个界面上,并且放到一个盒子里,这样我如果要看什么东西就可以很直接显示出来,而且这个盒子一定要能打开.我用HT实现了我的想法,代码一百多行,这么少的代码 ...

  5. java压缩包上传,解压,预览(利用editor.md和Jstree实现)和下载

    java压缩包上传,解压,预览(利用editor.md和Jstree实现)和下载 实现功能:zip文件上传,后台自动解压,Jstree树目录(遍历文件),editor.md预览 采用Spring+Sp ...

  6. IIC协议建模——读写EEPROM

    案例采用明德扬设计思想完成.IIC协议是非常常用的接口协议,在电子类岗位招聘要求中经常出现它的身影.关于IIC协议这里只做简要介绍,详细信息请自行百度或查阅相关Datasheet,网上资料非常多.该篇 ...

  7. Yii2之属性

    一直以来,在我的理解中,类的成员变量和属性就是同一个东西,直到看了<深入理解Yii2.0>才明白,类的成员变量和属性其实不是同一个概念,成员变量是就类的结构构成而言的概念,而属性是就类的功 ...

  8. PHP的取整函数

    PHP的取整函数有四个,分别是ceil.floor.round和intval,下面对它们进行一一介绍: 1. ceil(x):向上舍入为最接近的整数. 返回不小于 x 的下一个整数,x 如果有小数部分 ...

  9. LeetCode 59. Spiral Matrix II (螺旋矩阵之二)

    Given an integer n, generate a square matrix filled with elements from 1 to n2 in spiral order. For ...

  10. C11 constant expressions 常量表达式

    一图流总结hhh