《机器学习》 梯度下降


《机器学习》 梯度下降
2712人阅读 评论(0) 收藏 举报

参照《机器学习》这本书的第4.4.3节。

一.解决目标及情景假设:

当给定一些数据,输入x向量已知,输出y也已知,设计一个线性函数y=h(x)去拟合这些数据。

既然是线性函数,在此不妨设为h(x)=w0*x0+w1*x1。

此时我们遇到的问题就是如何确定w0和w1这两个参数,即w=(w0,w1)这个向量。

既然是拟合,则拟合效果可以用误差函数:E(w)=∑ [ h(x)- y ] ^2 / 2 来衡量。

其中w是权重二维向量,x是输入二维向量,x和y都是训练集的数据,即已知。

至于后面除于2只是为了之后的推导过程中对E求导时候可以消除系数,暂时可以不管。


因为我们解决的目标是找出一个向量w=(w0,w1)使得E(w)值最小,即误差最小。

其实这个问题本质上也是搜索最优解的问题,如果用暴力搜索的话,随机取每个可能的值去让机器每天每夜地跑,显然这是不可能的。
所以此时有一种搜索策略:梯度下降。


二. 梯度下降方法:

梯度其实就是高数求导方法,对E这个公式针对每个维数(w0,w1)求偏导后的向量▽E(w)=(∂E/∂w0,∂E/∂w1

梯度为最陡峭上升的方向,对应的梯度下降的训练法则为:

w=w-η▽E(w)

这里的η代表学习速率,决定梯度下降搜索中的步长 。

上式的w是向量,即可用将该式写成分量形式为:wi=wi-η*∂E/∂wi

现在关键就使计算∂E/∂wi:

推导过程很简单,书上写的很详细,这里只记录结论:

∂E/∂wi=∑(h(x)-y)*(xi)

这里的∑是对样本空间,即训练集进行一次遍历,耗费时间较大,可以使用梯度下降的随机近似:

随机梯度下降策略来改进时间。


三.随机梯度下降的随机近似:

既然是随机近似,则顾名思义,肯定是用近似方法来改善梯度下降时候的时间复杂度问题。

正如上所说,在∂E/∂wi=∑(h(x)-y)*(xi)
的时候∑耗费了大量的时间,特别是在训练集庞大的时候。

所以肯定有人会猜想,如果把求和去掉如何,即变为∂E/∂wi=(h(x)-y)*(xi)。

幸运的是,猜想成立了。

只是要注意一下标准的梯度下降和随机梯度下降的区别:

1.标准下降时在权值更新前汇总所有样例得到的标准梯度,随机下降则是通过考察每次训练实例来更新。

2.对于步长 η的取值,标准梯度下降的η比随机梯度下降的大。

因为标准梯度下降的是使用准确的梯度,理直气壮地走,随机梯度下降使用的是近似的梯度,就得小心翼翼地走,怕一不小心误入歧途南辕北辙了。

3.当E(w)有多个局部极小值时,随机梯度反而更可能避免进入局部极小值中。



四.代码及实例:

直接照着别人博客代码敲的一遍:http://blog.csdn.net/pennyliang/article/details/6998517

  1. /* 
  2.  * 随机梯度下降实验: 
  3.  * 训练集输入为矩阵: 
  4.  * 1,4 
  5.  * 2,5 
  6.  * 5,1 
  7.  * 4,2 
  8.  * 输出结果为: 
  9.  * 19 
  10.  * 26 
  11.  * 19 
  12.  * 20 
  13.  * 需要参数为theta: 
  14.  * ? 
  15.  * ? 
  16.  * 
  17.  * 目标函数:y=theta0*x0+theta1*x1; 
  18.  * 
  19.  * 
  20.  * */  
  21. #include<stdio.h>  
  22. int main()  
  23. {  
  24.     double matrix[4][2]={{1,4},{2,5},{5,1},{4,2}};  
  25.     double result[4]={19,26,19,20};  
  26.     double theta[2]={0,0};//初始为零向量  
  27.     double loss=10.0;  
  28.     for(int i=0;i<100&&loss>0.001;i++)  
  29.     {  
  30.         double error_sum=0;  
  31.         int j=i%4;  
  32.         {  
  33.             double h=0;  
  34.             for(int k=0;k<2;k++)  
  35.             {  
  36.                 h+=matrix[j][k]*theta[k];  
  37.             }  
  38.             error_sum=result[j]-h;  
  39.              for(int k=0;k<2;k++)  
  40.              {  
  41.                  theta[k]+=0.01*(error_sum)*matrix[j][k];//这里是关键  
  42.              }  
  43.          }  
  44.          printf("%lf,%lf\n",theta[0],theta[1]);  
  45.          double loss=0;  
  46.          for(int j=0;j<4;j++)  
  47.          {  
  48.              double sum=0;  
  49.              for(int k=0;k<2;k++)  
  50.              {  
  51.                  sum+=matrix[j][k]*theta[k];  
  52.              }  
  53.              loss+=(sum-result[j])*(sum-result[j]);  
  54.          }  
  55.          printf("%lf\n",loss);  
  56.      }  
  57.   
  58.   
  59.      return 0;  
  60.  }  
/*
 * 随机梯度下降实验:
 * 训练集输入为矩阵:
 * 1,4
 * 2,5
 * 5,1
 * 4,2
 * 输出结果为:
 * 19
 * 26
 * 19
 * 20
 * 需要参数为theta:
 * ?
 * ?
 *
 * 目标函数:y=theta0*x0+theta1*x1;
 *
 *
 * */
#include<stdio.h>
int main()
{
    double matrix[4][2]={{1,4},{2,5},{5,1},{4,2}};
    double result[4]={19,26,19,20};
    double theta[2]={0,0};//初始为零向量
    double loss=10.0;
    for(int i=0;i<100&&loss>0.001;i++)
    {
        double error_sum=0;
        int j=i%4;
        {
            double h=0;
            for(int k=0;k<2;k++)
            {
                h+=matrix[j][k]*theta[k];
            }
            error_sum=result[j]-h;
             for(int k=0;k<2;k++)
             {
                 theta[k]+=0.01*(error_sum)*matrix[j][k];//这里是关键
             }
         }
         printf("%lf,%lf\n",theta[0],theta[1]);
         double loss=0;
         for(int j=0;j<4;j++)
         {
             double sum=0;
             for(int k=0;k<2;k++)
             {
                 sum+=matrix[j][k]*theta[k];
             }
             loss+=(sum-result[j])*(sum-result[j]);
         }
         printf("%lf\n",loss);
     }


     return 0;
 }

结果可以得出c0=3,c1=4。


http://blog.csdn.net/wuyanyi/article/details/8003946
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值