梯度下降(Gradient Descent),一句代码,一个式子
一直以來,總是覺得國外的PhD們的教育以及課程的安排很好很強大,雖然是說很累作業多工作量大,但是功率大了,效果好點兒,浪費的時間也少,年輕人哪有怕苦怕累的。比比身邊好多每天睡超過12小時的研究生們,不知道是誰更幸福一點兒。
我也經常拿我所在的大學的研究生博士跟自己所了解的美國那邊的phd比比,說實話感覺總是有點硬性的差距在里面。我所處在大學的研究生教育,就拿安排的課程來說,覺得真是有用的不多,雖然也有一些好課,但是鑒于教學質量的問題,往往又起不到好的效果,最重要的是,這里的學生真是太輕松安逸了,不會有有用的作業,也不會有作業讓你熬夜計算或者coding,也不會有作業讓你在圖書館過夜,圖書館,哎,也是在按時上下班。
國外大牛的課程設計的也不錯,拿美女教授Kristen Grauman舉個例子,你可以去看看她得研究生以及本科的課程,看著都羨慕啊,是吧。Andrew Ng的課也不用說了,還有很多很多自身修養不錯的老師的課設計的都不錯。及時你對這個方向開始不是很懂,那么這一門課下來,讀了這么多論文以及寫了這么多作業和coding,加上一門課所輻射的一個領域,相信應該會學到很多東西,況且老師教學又那么認真,及時你懶,那么也會逼著你去學到了。
課程設計真是一種藝術,也是一種優化。學到的不僅僅是理論,也是一種理解和實現理論的方法以及過程的體驗。
--------------------------------
我經常會有一種感覺,就是感覺在自己實現一些算法的時候總是覺得不順利或者甚至不想去實現,一方面開源的工具很多,另一方面懶吧。
其實每個初學算法的人都應該去親自體驗一下才好,我覺得這個過程當中最重要的就是建立起書面論文理論到具體coding實現的一個映射,理論-實現,這個映射相信是很多人的瓶頸,要努力克服這個。
就拿梯度下降(Gradient Descent)這個小算法來舉個例子吧,算法簡單,對吧?但是忽然讓你馬上實現一下,能夠5分鐘迅速搞定么?3分鐘??允許用matlab的話,方便點兒是吧。
------------------------------------------------
即使以前看過梯度下降算法,但是真的要去用去實現的時候,還真是得重新再看看。針對具體問題吧,先選擇個問題,回歸問題。再找點兒數據,索性就把libsvm包里的例子數據heart_scale.mat拿來吧,可以自己去下載。雖然是分類的,但是也可以看做回歸唄,有些原理也相似。數據中heart_scale_inst包括270個13維的樣本,label全部是+-1,這里看做回歸吧。
假設要學習這么一個函數:
h(x)=hθ(x)=θ0+θ1x1+θ2x2+?
那么損失函數可以定義成:
J(Θ)=12∥XΘ?Y∥2
其中X看以看成一行一行的樣本向量,那么Θ就是一列一列的了。別搞混了。這其實就是比較常用的square loss,for least squares regression or classification。那么我們的目標很簡單,就是求損失的最小值的時候的解:
Θ?=argminΘJ(Θ)
像這種優化問題有很多方法,那咱們先直接求導吧,對于求導過程,好多還是不理解,可以用這種方法:
首先定義損失變量:
ri=∑j=1nXijθj?yi
那么損失函數就可以表示成:
J=12∑i=1mr2i
一步一步的求導:
?J?θj=∑i=1mri?ri?θj(j=1,2,…,n)
再求:
?ri?θj=Xij
那么把分步驟合起來就是:
?J?θj=∑i=1m(∑k=1nXikθk?yi)Xij(j=1,2,…,n)
導數為0,那么有:
∑i=1m(∑k=1nXikθ^k?yi)Xij=0(j=1,2,…,n)
整理一下:
∑i=1m∑k=1nXijXikθ^k=∑i=1mXijyi(j=1,2,…,n)
用矩陣符號將上面的細節運算抽象一下:
?J(Θ)?Θ=XTXΘ?XTY=0
讓導數為0,那么求得的解為:
Θ=(XTX)?1XTY
但是我們知道求矩陣(XTX)的逆復雜度有點兒高,O(n3),如果n很大,那么也受不了。
可以用最小二乘或者梯度下降來求解,這里我們看看梯度下降的實現,梯度下降的思想不難,只要確定好梯度以及梯度的方向就ok,因為是梯度的反方向去下降,所以在對參數更新的時候要注意:
Θi=Θi?1?γ?J(Θ)=Θi?1?γ?J(Θ)?Θ
其中γ就是下降的速度了,這個很敏感的,一般是一個小的數值,可以從0.01開始嘗試,越大下降越快,收斂越快。當然下降的速率可以改成自適用的,就是根據梯度的強弱適當調整步伐,這樣效果還好一點兒。
上圖就是迭代目標函數值的情況,迭代終止的條件有很多種,這里取得:
∥∥Θi?Θi?1∥∥<ε
代碼也很簡單,如果用matlab的話,矩陣計算就容易很多:
clc; clear % load data heart_scale = load('heart_scale'); X = heart_scale.heart_scale_inst; Y = heart_scale.heart_scale_label;epsilon = 0.0003; gamma= 0.0001;w_old=zeros(size(X,2),1); k=1; figure(1); while 1 minJ_w(k) = 1/2 * (norm(X*w_old - Y))^2; w_new = w_old - gamma*(X'*X*w_old - X'*Y); fprintf('The %dth iteration, minJ_w = %f, \n',k,minJ_w(k));if norm(w_new-w_old) < epsilon W_best = w_new; break; end w_old = w_new; k=k+1; endplot(minJ_w);
運行的結果:
The 1th iteration, minJ_w = 135.000000,
The 2th iteration, minJ_w = 128.785026,
The 3th iteration, minJ_w = 123.210569,
The 4th iteration, minJ_w = 118.202908,
The 5th iteration, minJ_w = 113.697504,
The 6th iteration, minJ_w = 109.637791,
The 7th iteration, minJ_w = 105.974133,
The 8th iteration, minJ_w = 102.662919,
The 9th iteration, minJ_w = 99.665786,
The 10th iteration, minJ_w = 96.948948,
The 11th iteration, minJ_w = 94.482602,
The 12th iteration, minJ_w = 92.240436,
The 13th iteration, minJ_w = 90.199178,
The 14th iteration, minJ_w = 88.338227,
The 15th iteration, minJ_w = 86.639312,
....................
from:?http://www.zhizhihu.com/html/y2011/3632.html
總結
以上是生活随笔為你收集整理的梯度下降(Gradient Descent),一句代码,一个式子的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于编译器的一个问题
- 下一篇: 梯度、梯度下降,随机梯度下降