基于Python fminunc 的替代方法
最近闲着没事,想把coursera上斯坦福ML课程里面的练习,用Python来实现一下,一是加深ML的基础,二是熟悉一下numpy,matplotlib,scipy这些库。
在EX2中,优化theta使用了matlab里面的fminunc函数,不知道Python里面如何实现。搜索之后,发现stackflow上有人提到用scipy库里面的minimize函数来替代。我尝试直接调用我的costfunction和grad,程序报错,提示(3,)和(100,1)dim维度不等,gradientvector不对之类的,试了N多次后,终于发现问题何在。。
首先来看看使用np.info(minimize)查看函数的介绍,传入的参数有:
fun:callable Theobjectivefunctiontobeminimized. ``fun(x,*args)->float`` wherexisan1-Darraywithshape(n,)and`args` isatupleofthefixedparametersneededtocompletely specifythefunction. x0:ndarray,shape(n,) Initialguess.Arrayofrealelementsofsize(n,), where'n'isthenumberofindependentvariables. args:tuple,optional Extraargumentspassedtotheobjectivefunctionandits derivatives(`fun`,`jac`and`hess`functions). method:strorcallable,optional Typeofsolver.Shouldbeoneof -'Nelder-Mead':ref:`(seehere)` -'Powell':ref:`(seehere) ` -'CG':ref:`(seehere) ` -'BFGS':ref:`(seehere) ` -'Newton-CG':ref:`(seehere) ` -'L-BFGS-B':ref:`(seehere) ` -'TNC':ref:`(seehere) ` -'COBYLA':ref:`(seehere) ` -'SLSQP':ref:`(seehere) ` -'trust-constr':ref:`(seehere) ` -'dogleg':ref:`(seehere) ` -'trust-ncg':ref:`(seehere) ` -'trust-exact':ref:`(seehere) ` -'trust-krylov':ref:`(seehere) ` -custom-acallableobject(addedinversion0.14.0), seebelowfordescription. Ifnotgiven,chosentobeoneof``BFGS``,``L-BFGS-B``,``SLSQP``, dependingiftheproblemhasconstraintsorbounds. jac:{callable,'2-point','3-point','cs',bool},optional Methodforcomputingthegradientvector.OnlyforCG,BFGS, Newton-CG,L-BFGS-B,TNC,SLSQP,dogleg,trust-ncg,trust-krylov, trust-exactandtrust-constr.Ifitisacallable,itshouldbea functionthatreturnsthegradientvector: ``jac(x,*args)->array_like,shape(n,)`` wherexisanarraywithshape(n,)and`args`isatuplewith thefixedparameters.Alternatively,thekeywords {'2-point','3-point','cs'}selectafinite differenceschemefornumericalestimationofthegradient.Options '3-point'and'cs'areavailableonlyto'trust-constr'. If`jac`isaBooleanandisTrue,`fun`isassumedtoreturnthe gradientalongwiththeobjectivefunction.IfFalse,thegradient willbeestimatedusing'2-point'finitedifferenceestimation.
需要注意的是fun关键词参数里面的函数,需要把优化的theta放在第一个位置,X,y,放到后面。并且,theta在传入的时候一定要是一个一维shape(n,)的数组,不然会出错。
然后jac是梯度,这里的有两个地方要注意,第一个是传入的theta依然要是一个一维shape(n,),第二个是返回的梯度也要是一个一维shape(n,)的数组。
总之,关键在于传入的theta一定要是一个1Dshape(n,)的,不然就不行。我之前为了方便已经把theta塑造成了一个(n,1)的列向量,导致使用minimize时会报错。所以,学会用help看说明可谓是相当重要啊~
importnumpyasnp
importpandasaspd
importscipy.optimizeasop
defLoadData(filename):
data=pd.read_csv(filename,header=None)
data=np.array(data)
returndata
defReshapeData(data):
m=np.size(data,0)
X=data[:,0:2]
Y=data[:,2]
Y=Y.reshape((m,1))
returnX,Y
defInitData(X):
m,n=X.shape
initial_theta=np.zeros(n+1)
VecOnes=np.ones((m,1))
X=np.column_stack((VecOnes,X))
returnX,initial_theta
defsigmoid(x):
z=1/(1+np.exp(-x))
returnz
defcostFunction(theta,X,Y):
m=X.shape[0]
J=(-np.dot(Y.T,np.log(sigmoid(X.dot(theta))))-\
np.dot((1-Y).T,np.log(1-sigmoid(X.dot(theta)))))/m
returnJ
defgradient(theta,X,Y):
m,n=X.shape
theta=theta.reshape((n,1))
grad=np.dot(X.T,sigmoid(X.dot(theta))-Y)/m
returngrad.flatten()
if__name__=='__main__':
data=LoadData('ex2data1csv.csv')
X,Y=ReshapeData(data)
X,initial_theta=InitData(X)
result=op.minimize(fun=costFunction,x0=initial_theta,args=(X,Y),method='TNC',jac=gradient)
print(result)
最后结果如下,符合MATLAB里面用fminunc优化的结果(fminunc:cost:0.203,theta:-25.161,0.206,0.201)
fun:array([0.2034977]) jac:array([8.95038682e-09,8.16149951e-08,4.74505693e-07]) message:'Localminimumreached(|pg|~=0)' nfev:36 nit:17 status:0 success:True x:array([-25.16131858,0.20623159,0.20147149])
此外,由于知道cost在0.203左右,所以我用最笨的梯度下降试了一下,由于后面实在是太慢了,所以设置whileJ>0.21,循环了大概13W次。。可见,使用集成好的优化算法是多么重要。。。还有,在以前的理解中,如果一个学习速率不合适,J会一直发散,但是昨天的实验发现,有的速率开始会发散,后面还是会收敛。
以上这篇基于Pythonfminunc的替代方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。