最近掉進了Machine Learning的坑里,暑期聽完了龍星計划的機器學習課程,走馬觀花看了一些書。最近找了Stanford的Machine Learning的公開課(http://v.163.com/special/opencourse/machinelearning.html),想系統地學習一遍,而且pennyliang博士在他的博客里(http://blog.csdn.net/pennyliang)公開了他學習這個課時候寫的一些代碼,對我這樣的入門級菜鳥很有幫助,在此對梁博士表示誠摯感謝。
今天看完了CS229,又下了Pennyliang寫的Batch Gradient Descent算法,發現它的實現跟Batch Gradient Descent算法不太一樣。傳統Batch Gradient Descent算法要求得到所有的樣本點后,根據所有樣本點計算出表示函數h,並更新theta,而后者的代碼則是來一個樣本就更新theta,這其實是Stochastic Gradient Descent算法。我對pennyliang的代碼進行了簡單的修改,實現了Batch Gradient Descent算法。
#include "stdio.h" int main(void) { float matrix[4][2]={{1,4},{2,5},{5,1},{4,2}}; float result[4]={19,26,19,20}; float theta[2]={2,5}; //initialized theta {2,5}, we use the algorithm to get {3,4} to fit the model float learning_rate = 0.001;//leaning_rate cann't be too big float loss = 1000.0; //set a loss big enough float error_sum[2]={0,0}; for(int i = 0;i<1000&&loss>0.0001;++i) { for(int j = 0;j<4;++j) { float h=0; for(int k=0;k<2;++k) { h += matrix[j][k]*theta[k]; } for(int k=0;k<2;++k) { error_sum[k] += (result[j]-h)*matrix[j][k]; } if(j==3) { for(int k=0;k<2;++k) { theta[k] += learning_rate*(error_sum[k]); } } } printf("*************************************\n"); printf("theta now: %f,%f\n",theta[0],theta[1]); printf("i: %d\n",i); loss = 0.0; for(int j = 0;j<4;++j) { float sum=0.0; for(int k = 0;k<2;++k) { sum += matrix[j][k]*theta[k]; } loss += (sum-result[j])*(sum-result[j]); } printf("loss ?now: %f\n",loss); } return 0; }
修改后的代碼必須將學習速度改小,否則容易“跨過”最優值,由於學習速度改小,迭代次數也將增加。
參考鏈接: