梯度下降--监督学习

建议参考《统计学习方法》这本书

参考视频:http://v.163.com/special/opencourse/machinelearning.html

一.介绍

      梯度下降法(gradient descent)是求解无约束最优化问题的一种常用方法,有实现简单的优点。梯度下降法是迭代算法,每一步需要求解目标函数的梯度向量。

 

   二.应用场景

     1.给定许多组数据(xi, yi),x(向量)为输入,yi为输出。设计一个线性函数y=h(x)去拟合这些数据。

     2.感知机:感知机(perceptron)为二类分类的线性分类模型。 输入为实例的特征向量,输出为实例的类别, 取+1 和 -1 二值。

 

     下面分别对这两种应用场景进行分析。

     1.对于第一种场景:

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

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

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

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

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

        因此该问题变成了求E(w)最小值的无约束最优化问题

三.梯度下降方法

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

       1. 对于第一种场景

          对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)有多个局部极小值时,随机梯度反而更可能避免进入局部极小值中。


 四.代码及实例:

  1. 对于第一种场景

 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  * 需要参数为 w:
14  * ?
15  * ?
16  *
17  * 目标函数:y=w0*x0+w1*x1;
18  *
19  * */
20 #include<stdio.h>
21 #include <stdlib.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 w[2]={0,0};//初始为零向量
27     double loss=10.0;
28     const double n = 0.01;        //步长 
29     for(int i=0;i<100&&loss>0.001;i++)
30     {
31         double error_sum=0;
32         int j=i%4;
33         { 
34             double h=0;
35             for(int k=0;k<2;k++)
36             {
37                 h+=matrix[j][k]*w[k];
38             }
39             error_sum = h - result[j];
40             for(int k=0;k<2;k++)
41             {
42                 w[k]-= n * (error_sum) * matrix[j][k];//这里是关键
43             }
44          }
45         printf("%lf,%lf\n",w[0],w[1]);
46         double loss=0;
47         for(int j=0;j<4;j++)
48         {
49             double sum=0;
50             for(int k=0;k<2;k++)
51             {
52                 sum += matrix[j][k] * w[k];
53         }
54         loss += (sum - result[j]) * (sum-result[j]);
55      }
56         printf("%lf\n",loss);
57     }
58 
59     system("pause");
60     return 0;
61 }
复制代码

 结果可以得出  w0=3,w1=4。

参考地址:

http://blog.csdn.net/lotus___/article/details/20546119

http://blog.csdn.net/xiazdong/article/details/7950084

http://www.zhizhihu.com/html/y2011/3632.html


在matlab实现:

梯度下降法函数function [k ender]=steepest(f,x,e),需要三个参数f、x和e,其中f为目标函数,x为初始点,e为终止误差。输出也为两个参数,k表示迭代的次数,ender表示找到的最低点。

steepest.m:

function [k ender]=steepest(f,x,e)
%梯度下降法,f为目标函数(两变量x1和x2),x为初始点,如[3;4]
syms x1 x2 m; %m为学习率
d=-[diff(f,x1);diff(f,x2)];  %分别求x1和x2的偏导数,即下降的方向
flag=1;  %循环标志
k=0; %迭代次数
while(flag)
  d_temp=subs(d,x1,x(1));	  %将起始点代入,求得当次下降x1梯度值
  d_temp=subs(d_temp,x2,x(2)); %将起始点代入,求得当次下降x2梯度值
  nor=norm(d_temp); %范  if(nor>=e)
    x_temp=x+m*d_temp;			%改变初始点x的值
    f_temp=subs(f,x1,x_temp(1));  %将改变后的x1和x2代入目标函数
    f_temp=subs(f_temp,x2,x_temp(2));
    h=diff(f_temp,m);  %对m求导,找出最佳学习率
    m_temp=solve(h);   %求方程,得到当次m
    x=x+m_temp*d_temp; %更新起始点x
    k=k+1;
  else
    flag=0;
  end
end
ender=double(x);  %终点
end
调用示例1:

syms x1 x2;
f=(x1-2)^2+2*(x2-1)^2;
x=[1;3];
e=10^(-20);
[k ender]=steepest(f,x,e)

结果:

k =

  58


ender =

   -1.0000
  1.5000
syms x1 x2;
f=3/2*x1^2+1/2*x2^2-x1*x2-2*x1;
x=[0;0];
e=10^(-2);
[k ender]=steepest(f,x,e)
k =

  9


ender =

    0.9959
    0.9877

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值