基于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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。