目标函数 入门 | 目标函数的经典优化算法介绍
选自3dbabove
参与:干树,刘晓坤
本文利用流行的语言和图解介绍了随机梯度下降算法及其三个经典变种,并给出了完整的实现代码。
GitHub链接:https://github.com/ManuelGonzalezRivero/3dbabove
成本函数的几种优化方法
目标函数是衡量预测值和实际值之间相似性的指标。通常我们希望得到一个参数集,使得代价尽可能小,也就是说你的算法性能很好。一个函数的最小可能成本叫做最小值。有时一个成本函数可以有多个局部极小值。幸运的是,当参数空之间的维数很高时,阻碍目标函数充分优化的局部最小值并不经常出现,因为这意味着目标函数在训练过程的前期相对于每个参数是凹的。但这不正常。通常我们得到的是很多鞍点,而不是真正的最小值。
数据会说,θ是你试图找到的最小化J的参数,其中J称为目标函数。最后,我们记录学习率为α。通常情况下,你应该重复应用上面的等式,直到达到你需要的成本值。
这是什么意思?想想看,如果你坐在山顶的雪橇上,看着另一座山。滑下山,自然会往下移动,直到最后停在山脚。如果第一座山足够陡峭,你可能会开始滑向另一座山的一侧。从这个比喻中你可以想到:
学习率越高意味着摩擦力越小,所以雪橇会像冰一样滑下山坡。学习率低意味着摩擦力大,所以雪橇会像在地毯上一样难以滑下。怎么才能用上面的方程来模拟这种效果?
随机梯度下降法;
初始化参数(θ,学习率)
计算每个θ处的梯度
更新参数
重复步骤2和3,直到成本稳定
让我们用一个简单的例子来看看它是如何工作的!
这里我们看到一个目标函数及其导数(梯度):
我们可以使用以下代码来生成函数和梯度值/30的图形:
importnumpy asnp
定义最小函数(θ):
returnnp . cos(3 * NP . pi * theta)/theta
微分极小函数导数(θ):
const1 =3*np.pi
const 2 = const 1 *θ
返回-(const 1 * NP . sin(const 2)/theta)-NP . cos(const 2)/theta * * 2
θ= NP . arange(. 1,2.1,. 01)
JT heta = MiniFuncTion(θ)
DJθ=极小函数导数(θ)
plt.plot(theta,Jtheta,label =r'$J(theta)$ ')
plt.plot(theta,dJtheta/30,label =r'$dJ(theta)/30$ ')
plt.legend()
axes =plt.gca()
#axes.set_ylim([-10,10])
plt.ylabel(r'$J(theta),dJ(theta)/30$ ')
plt.xlabel(r'$theta$ ')
plt.title(r'$J(theta),dJ(theta)/30 $ vs $theta$ ')
plt.show()
γ和ν的值允许用户对dJ(θ)的先前值和当前值进行加权,以确定新的θ值。人们通常选择γ和ν的值来创建指数加权移动平均值,如下所示:
β参数的最佳选择为0.9。选择一个等于1-1/t的β值,可以让用户更愿意考虑νdw的最新t值。这个简单的改变就能让优化过程产生显著的效果!我们现在可以用更高的学习率,在最短的时间内收敛!
importnumpy asnp
importmatplotlib.mlab asmlab
importmatplotlib.pyplot asplt
importscipy.stats
import matplotlib . animation as imation
定义最小函数(参数):
#二元正态函数
x,Y =参数
sigma11,sigma12,mu11,mu12 =(3.0,. 5,0.0,0.0)
Z1 = mlab . binary _ normal(X,Y,sigma11,sigma12,mu11,mu12)
Z =Z1
返回-40*Z
定义最小函数导数(参数):
#二元正态函数的导数
x,Y =参数
sigma11,sigma12,mu11,mu12 =(3.0,. 5,0.0,0.0)
dZ1X =-scipy.stats.norm.pdf(X,mu11,sigma11)*(mu11 -X)/sigma11**2
dZ1Y =-scipy.stats.norm.pdf(Y,mu12,sigma12)*(mu12 -Y)/sigma12**2
返回(dZ1X,dZ1Y)
去优化(迭代、oF、dOF、参数、学习率、beta):
"""
计算给定目标函数及其导数的参数的最优值
参数:
- iteratoins -优化目标函数所需的迭代次数
- oF -目标函数
- dOF -目标函数的导数函数
- params -要优化的函数的参数
-学习率-学习率
-β-动量的加权移动平均参数
返回:
-运算内存-迭代每一步的优化参数列表
"""
oParams =[params]
vdw =(0.0,0.0)
#迭代循环
fori inrange(迭代次数):
#计算参数的导数
dParams =dOF(参数)
#计算每个梯度的动量vdw = vdw *β+(1.0+β)* dPAR
vDW = tuple([VdW * beta+(1.0-beta)* DPar FOrdPar,vDW inzip(dParams,vdw)])
#此行中的SGD遍历每个参数并应用参数=参数-学习率*参数
params = tuple([par-learning rate * DPar FOrdPar,par inzip(vdw,params)])
#添加新参数
oParams.append(params)
returnoParams
迭代次数=100
学习率=5.3
β= . 9
x,y =4.0,1.0
params =(x,y)
优化参数=优化(迭代,
minimaFunction,
最小函数导数,
params,
学习率,
beta)
请注意,这里加入ε是为了数值稳定,可以是10e-7。这是为什么?
importnumpy asnp
importmatplotlib.mlab asmlab
importmatplotlib.pyplot asplt
importscipy.stats
import matplotlib . animation as imation
定义最小函数(参数):
#二元正态函数
x,Y =参数
sigma11,sigma12,mu11,mu12 =(3.0,. 5,0.0,0.0)
Z1 = mlab . binary _ normal(X,Y,sigma11,sigma12,mu11,mu12)
Z =Z1
返回-40*Z
定义最小函数导数(参数):
#二元正态函数的导数
x,Y =参数
sigma11,sigma12,mu11,mu12 =(3.0,. 5,0.0,0.0)
dZ1X =-scipy.stats.norm.pdf(X,mu11,sigma11)*(mu11 -X)/sigma11**2
dZ1Y =-scipy.stats.norm.pdf(Y,mu12,sigma12)*(mu12 -Y)/sigma12**2
返回(dZ1X,dZ1Y)
去优化(迭代、oF、dOF、参数、学习率、beta):
"""
计算给定目标函数及其导数的参数的最优值
参数:
- iteratoins -优化目标函数所需的迭代次数
- oF -目标函数
- dOF -目标函数的导数函数
- params -要优化的函数的参数
-学习率-学习率
- beta -风险管理计划的加权移动平均参数
返回:
-运算内存-迭代每一步的优化参数列表
"""
oParams =[params]
sdw =(0.0,0.0)
eps =10**(-7)
#迭代循环
fori inrange(迭代次数):
#计算参数的导数
dParams =dOF(参数)
#计算每个梯度的动量sdw = sdw*beta+(1.0+beta)*dPar^2
sDW = tuple([SDw * beta+(1.0-beta)* DPar * * 2 FordPar,sDW inzip(dParams,sdw)])
#此行中的SGD遍历每个参数并应用参数=参数-学习率*参数
params = tuple([par-learning rate * DPar/((SDw * * . 5)+EPS)FOrsDW,par,dPar inzip(sdw,params,dParams)]
#添加新参数
oParams.append(params)
returnoParams
迭代=10
学习率=.3
β= . 9
x,y =5.0,1.0
params =(x,y)
优化参数=优化(迭代,
minimaFunction,
最小函数导数,
params,
学习率,
beta)
亚当算法
Adam算法将动量和RMSProp的概念结合到一个算法中,达到两全其美。公式如下:
importnumpy asnp
importmatplotlib.mlab asmlab
importmatplotlib.pyplot asplt
importscipy.stats
import matplotlib . animation as imation
定义最小函数(参数):
#二元正态函数
x,Y =参数
sigma11,sigma12,mu11,mu12 =(3.0,. 5,0.0,0.0)
Z1 = mlab . binary _ normal(X,Y,sigma11,sigma12,mu11,mu12)
Z =Z1
返回-40*Z
定义最小函数导数(参数):
#二元正态函数的导数
x,Y =参数
sigma11,sigma12,mu11,mu12 =(3.0,. 5,0.0,0.0)
dZ1X =-scipy.stats.norm.pdf(X,mu11,sigma11)*(mu11 -X)/sigma11**2
dZ1Y =-scipy.stats.norm.pdf(Y,mu12,sigma12)*(mu12 -Y)/sigma12**2
返回(dZ1X,dZ1Y)
去优化(迭代,oF,dOF,params,learningRate,beta1,beta2):
"""
计算给定目标函数及其导数的参数的最优值
参数:
- iteratoins -优化目标函数所需的迭代次数
- oF -目标函数
- dOF -目标函数的导数函数
- params -要优化的函数的参数
-学习率-学习率
-β1-亚当动量分量的加权移动平均参数
-β2-风险管理的加权移动平均参数
返回:
-运算内存-迭代每一步的优化参数列表
"""
oParams =[params]
vdw =(0.0,0.0)
sdw =(0.0,0.0)
vdwCorr =(0.0,0.0)
sdwCorr =(0.0,0.0)
eps =10**(-7)
#迭代循环
fori inrange(迭代次数):
#计算参数的导数
dParams =dOF(参数)
#计算每个梯度的动量vdw = vdw *β+(1.0+β)* dPAR
vDW = tuple([VdW * beta 1+(1.0-beta 1)* DPar FOrdPar,vDW inzip(dParams,vdw)])
#计算每个梯度的均方根值sdw = sdw*beta+(1.0+beta)*dPar^2
sDW = tuple([SDw * beta 2+(1.0-beta 2)* DPar * * 2.0 FOrdPar,sDW inzip(dParams,sdw)])
#计算sdw和vdw的重量增加
vdwCorr = tuple([vDW/(1.0-beta 1 * *(I+1.0))for vDW invdw])
sDW orr = tuple([SDw/(1.0-beta 2 * *(I+1.0))FOrsDW ins dw])
#此行中的SGD遍历每个参数并应用参数=参数-学习率*参数
params = tuple([par-learning rate * vdw orr/((sdw orr * * . 5)+EPS)for dwcorr,vdw orr,par in zip(vdw orr,sdw orr,params)]
#添加新参数
oParams.append(params)
returnoParams
迭代次数=100
学习率=.1
β1 = . 9
β2 = . 999
x,y =5.0,1.0
params =(x,y)
优化参数=优化(迭代,
minimaFunction,
最小函数导数,
params,
学习率,
beta1,
beta2)<。/div>。
Adam算法可能是目前深度学习中应用最广泛的优化算法,适用于很多应用。亚当计算了一个ν dw corr的值来加速指数加权移动平均的变化。它将通过增加它们的值来标准化它们,这与当前的迭代次数成反比。在使用Adam的时候有一些很好的初始值可以尝试。最好从0.9的β_1和0.999的β_2开始。
总结
优化目标函数的算法有很多种选择。在上面的例子中,我们发现各种方法的收敛速度越来越快:
–SGD:100次迭代
–SGD+动量:50次迭代
–rms道具:10次迭代
–亚当:5次迭代
原文链接:https://3dbabove.com/2017/11/14/optimizationalgorithms/
这篇文章是为机器的核心编写的。请联系该公众号进行授权。