用Python+Sympy實現一個簡單的梯度下降法

用Python+Sympy實現一個簡單的梯度下降法

來自專欄 機器學習實踐

from sympy import *import numpy as npepsilon=1e-6#精度x=Symbol("x")y=Symbol("y")z=Symbol("z")k=Symbol(k)#步長z=x**4-8*x*y+2*y**2-3#目標函數w0=np.array([-17.3,-20.5])#初始點i=0#迭代次數while (True): gx=diff(z,x).subs([(x,w0[0]),(y,w0[1])])#對x求偏導 gy=diff(z,y).subs([(x,w0[0]),(y,w0[1])])#對y求偏導 p=-np.array([gx,gy])#負梯度方向 if((np.sum(np.square(p)))**0.5<epsilon):#負梯度的模長達到精度要求時退出 break; #用求導的方式,得到步長k w1=p*k+w0 f=z.subs([(x,w1[0]),(y,w1[1])])#用w1替換原目標函數z中的x,y。得到關於步長k的一元函數f(k),即求f(k)的最小值 a=solve(diff(f,k),k)#對f(k)求導,並使其等於0,求出k w1=p*a[0]+w0 #用固定步長k=0.03。比用求導得到的步長收斂慢很多,而且很容易發生振蕩,無法收斂。不推薦。 #w1=p*0.03+w0 print w1[0].evalf(),w1[1].evalf(),z.subs([(x,w1[0]),(y,w1[1])]).evalf()#觀察迭代 if((np.sum(np.square(w1-w0)))**0.5<epsilon):#經過迭代後無明顯變化時退出 break w0=w1#繼續迭代 i=i+1 print i,"次迭代完成"print round(w1[0].evalf()),round(w1[1].evalf()),round(z.subs([(x,w1[0]),(y,w1[1])]).evalf())

目標函數的三維圖像:

迭代過程:

菜雞水平,僅供參考~
推薦閱讀:

初試微軟Azure Machine Learning:建立簡易CAD/CNY匯率預測模型
自動調參、ROC——2017.03.13
《機器智能的未來》系列三:Brendan Frey--當深度學習遇上基因生物學 | 將門推薦
【5】如何理解CNN中的池化?

TAG:機器學習 | Python |