机器学习笔记:Gradient Descent

  最近掉进了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;
}

修改后的代码必须将学习速度改小,否则容易“跨过”最优值,由于学习速度改小,迭代次数也将增加。

参考链接:

http://blog.csdn.net/pennyliang/article/details/6998517

http://v.163.com/movie/2008/1/B/O/M6SGF6VB4_M6SGHJ9BO.html