mini-batch 梯度下降

http://m.blog.csdn.net/article/details?id=51188876

一、梯度下降法

  在机器学习算法中,对于很多监督学习模型,需要对原始的模型构建损失函数,接下来便是通过优化算法对损失函数进行优化,以便寻找到最优的参数。在求解机器学习参数的优化算法中,使用较多的是基于梯度下降的优化算法(Gradient Descent, GD)。

  梯度下降法有很多优点,其中,在梯度下降法的求解过程中,只需求解损失函数的一阶导数,计算的代价比较小,这使得梯度下降法能在很多大规模数据集上得到应用。梯度下降法的含义是通过当前点的梯度方向寻找到新的迭代点。

  基本思想可以这样理解:我们从山上的某一点出发,找一个最陡的坡走一步(也就是找梯度方向),到达一个点之后,再找最陡的坡,再走一步,直到我们不断的这么走,走到最“低”点(最小花费函数收敛点)。

        这里写图片描述 
  如上图所示,得到了局部最优解。x,y表示的是theta0和theta1,z方向表示的是花费函数,很明显出发点不同,最后到达的收敛点可能不一样。当然如果是碗状的,那么收敛点就应该是一样的。

二、梯度下降法的变形形式

  在具体使用梯度下降法的过程中,主要有以下几种不同的变种,即:batch、mini-batch、SGD。其主要区别是不同的变形在训练数据的选择上

1、批量梯度下降法BGD 
  批梯度下降法(Batch Gradient Descent)针对的是整个数据集,
通过对所有的样本的计算来求解梯度的方向。 
  批量梯度下降法的损失函数为: 
       这里写图片描述 
  进一步得到批量梯度下降的迭代式为: 
    这里写图片描述 
  每迭代一步,都要用到训练集所有的数据,如果样本数目很大,那么可想而知这种方法的迭代速度! 
  优点:全局最优解;易于并行实现; 
  缺点:当样本数目很多时,训练过程会很慢。 
  从迭代的次数上来看,BGD迭代的次数相对较少。其迭代的收敛曲线示意图可以表示如下: 
       这里写图片描述 
        
2、小批量梯度下降法MBGD 
  在上述的批梯度的方式中每次迭代都要使用到所有的样本,对于数据量特别大的情况,如大规模的机器学习应用,每次迭代求解所有样本需要花费大量的计算成本。是否可以在每次的迭代过程中利用部分样本代替所有的样本呢?基于这样的思想,便出现了mini-batch的概念。 
  假设训练集中的样本的个数为1000,则每个mini-batch只是其一个子集,假设,每个mini-batch中含有10个样本,这样,整个训练数据集可以分为100个mini-batch。伪代码如下: 
     这里写图片描述

3、随机梯度下降法SGD

  随机梯度下降算法(stochastic gradient descent)可以看成是mini-batch gradient descent的一个特殊的情形,即在随机梯度下降法中每次仅根据一个样本对模型中的参数进行调整,等价于上述的b=1情况下的mini-batch gradient descent,即每个mini-batch中只有一个训练样本。 
  随机梯度下降法的优化过程为: 
这里写图片描述 
  随机梯度下降是通过每个样本来迭代更新一次,如果样本量很大的情况(例如几十万),那么可能只用其中几万条或者几千条的样本,就已经将theta迭代到最优解了,对比上面的批量梯度下降,迭代一次需要用到十几万训练样本,一次迭代不可能最优,如果迭代10次的话就需要遍历训练样本10次。但是,SGD伴随的一个问题是噪音较BGD要多,使得SGD并不是每次迭代都向着整体最优化方向。 
  优点:训练速度快; 
  缺点:准确度下降,并不是全局最优;不易于并行实现。 
  从迭代的次数上来看,SGD迭代的次数较多,在解空间的搜索过程看起来很盲目。其迭代的收敛曲线示意图可以表示如下: 
  这里写图片描述

三 通俗的理解梯度下降

  (1)批量梯度下降—最小化所有训练样本的损失函数(对全部训练数据求得误差后再对参数进行更新),使得最终求解的是全局的最优解,即求解的参数是使得风险函数最小。批梯度下降类似于在山的某一点环顾四周,计算出下降最快的方向(多维),然后踏出一步,这属于一次迭代。批梯度下降一次迭代会更新所有theta,每次更新都是向着最陡的方向前进。

  (2)随机梯度下降—最小化每条样本的损失函数,虽然不是每次迭代得到的损失函数都向着全局最优方向, 但是大的整体的方向是向全局最优解的,最终的结果往往是在全局最优解附近。随机也就是说我用样本中的一个例子来近似我所有的样本,来调整theta,其不会计算斜率最大的方向,而是每次只选择一个维度踏出一步;下降一次迭代只更新某个theta,报着并不严谨的走走看的态度前进。

四 随机梯度下降代码

load data; %导入X,Y,test_feature
epsilon = 0.0001; %收敛阈值
alpha = 0.001; %学习率
k = 1; %迭代次数
n = size(X,2); %特征数+1
m = size(X,1); %训练样本个数
theta = zeros(n,1);
theta_new = zeros(n,1);
converge = 0;
while(converge==0)    %未收敛
        for(i=1:m)        %反复使用m个训练样本,每个样本就更新一次参数
            J(k) = 1/2 * (norm(X*theta - Y))^2;
            for(j = 1:n)
                theta_new(j) = theta(j)-alpha*(X(i,:)*theta-Y(i,:))*X(i,j);
            end;
            if norm(theta_new-theta) < epsilon
                converge=1;
                theta = theta_new;
                break;
            else
                theta = theta_new;
                k = k + 1;
            end
        end;
end;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

相关文献: 
http://www.zhizhihu.com/html/y2011/3632.html

http://www.th7.cn/system/win/201511/142910.shtml




=======================================================
下面链接先看


http://www.cnblogs.com/python27/p/MachineLearningWeek10.html



梯度下降(BGD)、随机梯度下降(SGD)、Mini-batch Gradient Descent、带Mini-batch的SGD

标签: 神经网络梯度下降随机梯度下降
 3633人阅读 评论(1) 收藏 举报
 分类:

目录(?)[+]

一、回归函数及目标函数

以均方误差作为目标函数(损失函数),目的是使其值最小化,用于优化上式。

二、优化方式(Gradient Descent)

1、最速梯度下降法

也叫批量梯度下降法Batch Gradient Descent,BSD

a、对目标函数求导

b、沿导数相反方向移动theta

原因:

(1)对于目标函数,theta的移动量应当如下,其中a为步长,p为方向向量。


(2)对J(theta)做一阶泰勒级数展开:

(3)上式中,ak是步长,为正数,可知要使得目标函数变小,则应当<0,并且其绝对值应当越大越好,这样下降的速度更快。在泰勒级数中,g代表J(theta k)的梯度,所以为了使得为负并且绝对值最大,应当使theta的移动方向与梯度g相反。


2、随机梯度下降法(stochastic gradient descent,SGD)

SGD是最速梯度下降法的变种。

使用最速梯度下降法,将进行N次迭代,直到目标函数收敛,或者到达某个既定的收敛界限。每次迭代都将对m个样本进行计算,计算量大。

为了简便计算,SGD每次迭代仅对一个样本计算梯度,直到收敛。伪代码如下(以下仅为一个loop,实际上可以有多个这样的loop,直到收敛):


(1)由于SGD每次迭代只使用一个训练样本,因此这种方法也可用作online learning。

(2)每次只使用一个样本迭代,若遇上噪声则容易陷入局部最优解。

3、Mini-batch Gradient Descent

(1)这是介于BSD和SGD之间的一种优化算法。每次选取一定量的训练样本进行迭代。

(2)从公式上似乎可以得出以下分析:速度比BSD快,比SGD慢;精度比BSD低,比SGD高。

4、带Mini-batch的SGD

(1)选择n个训练样本(n<m,m为总训练集样本数)

(2)在这n个样本中进行n次迭代,每次使用1个样本

(3)对n次迭代得出的n个gradient进行加权平均再并求和,作为这一次mini-batch下降梯度

(4)不断在训练集中重复以上步骤,直到收敛。


=============================================


机器学习公开课笔记(10):大规模机器学习

批梯度下降 (Batch Gradient Descent)

以线性回归为例,用梯度下降算法进行参数更新的公式为

θj=θjα1mi=1m(hθ(x(i))y(i))x(i)jθj=θj−α1m∑i=1m(hθ(x(i))−y(i))xj(i)
可以看到每次参数更新一次,都需要将整个训练集扫描一遍,所以称为批梯度下降,这种更新方式对于参数集很大的集合(例如m=100,000,000)运行速度十分慢,为了加快算法运行速度,提出了随机梯度下降。

随机梯度下降 (Stochastic Gradient Descent)

每次仅用一个example来更新参数θθ,仍以线性回归为例,随机梯度下降算法为

1. 随机重排列整个训练集(shuffle)

2. 重复下列过程多次(数据集较大时可以重复1~10次)

    for i = 1, ..., m {
   θj=θjα(hθ(x(i))y(i))x(i)jθj=θj−α(hθ(x(i))−y(i))xj(i)
    }

小批梯度下降 (Mini-Batch Gradient Descent)

介于批梯度下降和随机梯度下降之间,批梯度处理利用全部m个example进行参数更新;随机梯度下降只用1个example进行参数更新;而Mini梯度下降使用b(1<b<m)个example进行参数更新。仍以线性回归为例,加入我们有m=1000个example,我们可以用每b=10个example进行参数更新,例如:

Repeat {
        for i = 1, 11, 21, ..., 991 {
                θj=θjα110k=ii+9(hθ(x(k))y(k))x(k)jθj=θj−α110∑k=ii+9(hθ(x(k))−y(k))xj(k)
        }
}

算法收敛性

批梯度处理能够保证算法收敛到最小值(如果选择的学习速率αα合适的话),可以plot代价函数J(θ)J(θ)随迭代次数的曲线,如果曲线是总是下降的,则能够收敛,反之需要调整学习速率。

随机梯度下降并不能保证算法收敛到最小值,最终结果可能是在最小值附近来回游走,为了观察其收敛特性,可以plot每100(1000)次迭代时100个example代价函数函数cost(θ,(x(i),y(i)))cost(θ,(x(i),y(i)))的平均值,如果是下降趋势,则可以收敛,否则可能需要调整增大或者减小平均的example数(将100改为1000或者10等),减小或者增大学习速率。

在线学习 (Online Learning)

之前的算法都是有一个固定的训练集来训练模型,当模型训练好后对未来的example进行分类、回归等。在线学习则不同,它对每个新来的example进行模型参数更新,因此不需要固定的训练集,参数更新的方式则是采用随机梯度下降。在线学习的优势是模型参数可以随用户的偏好自适应的进行调整,以logistic回归为例,在线学习方式如下:

Repeat forever {
        1. 获取当前example (x, y)
        2. 使用(x,y)进行参数更新:θj=θjα(hθ(x)y)xjθj=θj−α(hθ(x)−y)xj
}

MapReduce和数据并行化

这部分内容Andrew Ng讲得不多,可以认为仅仅讲了多个机器的求和问题,比如如何求解1+2+3+...+1000?Map过程:四个机器分别计算1+2+...+250,251+252+...+500, 501+502...+750,751+752+...+1000,然后Reduce过程:将四个机器求和的结果sum1,sum2,sum3,sum4汇总到一台机器上,计算sum1+sum2+sum3+sum4。




==============================================


梯度下降之随机梯度下降 -minibatch 与并行化方法

问题的引入:

考虑一个典型的有监督机器学习问题,给定m个训练样本S={x(i),y(i)},通过经验风险最小化来得到一组权值w,则现在对于整个训练集待优化目标函数为:

其中为单个训练样本(x(i),y(i))的损失函数,单个样本的损失表示如下:

引入L2正则,即在损失函数中引入,那么最终的损失为:

注意单个样本引入损失为(并不用除以m):

正则化的解释

这里的正则化项可以防止过拟合,注意是在整体的损失函数中引入正则项,一般的引入正则化的形式如下:

其中L(w)为整体损失,这里其实有:

这里的 C即可代表,比如以下两种不同的正则方式:

下面给一个二维的示例图:我们将模型空间限制在w的一个L1-ball 中。为了便于可视化,我们考虑两维的情况,在(w1, w2)平面上可以画出目标函数的等高线,而约束条件则成为平面上半径为C的一个 norm ball 。等高线与 norm ball 首次相交的地方就是最优解

 

可以看到,L1-ball 与L2-ball 的不同就在于L1在和每个坐标轴相交的地方都有“角”出现,而目标函数的测地线除非位置摆得非常好,大部分时候都会在角的地方相交。注意到在角的位置就会产生稀疏性,例如图中的相交点就有w1=0,而更高维的时候(想象一下三维的L1-ball 是什么样的?)除了角点以外,还有很多边的轮廓也是既有很大的概率成为第一次相交的地方,又会产生稀疏性,相比之下,L2-ball 就没有这样的性质,因为没有角,所以第一次相交的地方出现在具有稀疏性的位置的概率就变得非常小了。

因此,一句话总结就是:L1会趋向于产生少量的特征,而其他的特征都是0,而L2会选择更多的特征,这些特征都会接近于0。Lasso在特征选择时候非常有用,而Ridge就只是一种规则化而已。

Batch Gradient Descent

有了以上基本的优化公式,就可以用Gradient Descent 来对公式进行求解,假设w的维度为n,首先来看标准的Batch Gradient Descent算法:

repeat until convergency{

  for j=1;j<n ; j++:

    

}

 这里的批梯度下降算法是每次迭代都遍历所有样本,由所有样本共同决定最优的方向。

stochastic Gradient Descent

随机梯度下降就是每次从所有训练样例中抽取一个样本进行更新,这样每次都不用遍历所有数据集,迭代速度会很快,但是会增加很多迭代次数,因为每次选取的方向不一定是最优的方向.

repeat until convergency{

  random choice j from all m training example:

    

}

mini-batch Gradient Descent

这是介于以上两种方法的折中,每次随机选取大小为b的mini-batch(b<m), b通常取10,或者(2...100),这样既节省了计算整个批量的时间,同时用mini-batch计算的方向也会更加准确。

repeat until convergency{

  for j=1;j<n ; j+=b:

    

}

最后看并行化的SGD:

若最后的v达到收敛条件则结束执行,否则回到第一个for循环继续执行,该方法同样适用于minibatch gradient descent。




=============================================


随机梯度下降(Stochastic gradient descent)和 批量梯度下降(Batch gradient descent )的公式对比、实现对比

标签: 梯度下降最优化迭代
 87890人阅读 评论(28) 收藏 举报
 分类:
 

梯度下降(GD)是最小化风险函数、损失函数的一种常用方法,随机梯度下降和批量梯度下降是两种迭代求解思路,下面从公式和实现的角度对两者进行分析,如有哪个方面写的不对,希望网友纠正。


下面的h(x)是要拟合的函数,J(theta)损失函数,theta是参数,要迭代求解的值,theta求解出来了那最终要拟合的函数h(theta)就出来了。其中m是训练集的记录条数,j是参数的个数。



1、批量梯度下降的求解思路如下:

(1)将J(theta)对theta求偏导,得到每个theta对应的的梯度

   

(2)由于是要最小化风险函数,所以按每个参数theta的梯度负方向,来更新每个theta


(3)从上面公式可以注意到,它得到的是一个全局最优解,但是每迭代一步,都要用到训练集所有的数据,如果m很大,那么可想而知这种方法的迭代速度!!所以,这就引入了另外一种方法,随机梯度下降。


2、随机梯度下降的求解思路如下:

(1)上面的风险函数可以写成如下这种形式,损失函数对应的是训练集中每个样本的粒度,而上面批量梯度下降对应的是所有的训练样本:


(2)每个样本的损失函数,对theta求偏导得到对应梯度,来更新theta

(3)随机梯度下降是通过每个样本来迭代更新一次,如果样本量很大的情况(例如几十万),那么可能只用其中几万条或者几千条的样本,就已经将theta迭代到最优解了,对比上面的批量梯度下降,迭代一次需要用到十几万训练样本,一次迭代不可能最优,如果迭代10次的话就需要遍历训练样本10次。但是,SGD伴随的一个问题是噪音较BGD要多,使得SGD并不是每次迭代都向着整体最优化方向。


3、对于上面的linear regression问题,与批量梯度下降对比,随机梯度下降求解的会是最优解吗?

(1)批量梯度下降---最小化所有训练样本的损失函数,使得最终求解的是全局的最优解,即求解的参数是使得风险函数最小。

(2)随机梯度下降---最小化每条样本的损失函数,虽然不是每次迭代得到的损失函数都向着全局最优方向, 但是大的整体的方向是向全局最优解的,最终的结果往往是在全局最优解附近。


4、梯度下降用来求最优解,哪些问题可以求得全局最优?哪些问题可能局部最优解?

对于上面的linear regression问题,最优化问题对theta的分布是unimodal,即从图形上面看只有一个peak,所以梯度下降最终求得的是全局最优解。然而对于multimodal的问题,因为存在多个peak值,很有可能梯度下降的最终结果是局部最优。


5、随机梯度和批量梯度的实现差别

以前一篇博文中NMF实现为例,列出两者的实现差别(注:其实对应Python的代码要直观的多,以后要练习多写python!)

[java] view plain copy
  1. // 随机梯度下降,更新参数  
  2. public void updatePQ_stochastic(double alpha, double beta) {  
  3.     for (int i = 0; i < M; i++) {  
  4.         ArrayList<Feature> Ri = this.dataset.getDataAt(i).getAllFeature();  
  5.         for (Feature Rij : Ri) {  
  6.             // eij=Rij.weight-PQ for updating P and Q  
  7.             double PQ = 0;  
  8.             for (int k = 0; k < K; k++) {  
  9.                 PQ += P[i][k] * Q[k][Rij.dim];  
  10.             }  
  11.             double eij = Rij.weight - PQ;  
  12.   
  13.             // update Pik and Qkj  
  14.             for (int k = 0; k < K; k++) {  
  15.                 double oldPik = P[i][k];  
  16.                 P[i][k] += alpha  
  17.                         * (2 * eij * Q[k][Rij.dim] - beta * P[i][k]);  
  18.                 Q[k][Rij.dim] += alpha  
  19.                         * (2 * eij * oldPik - beta * Q[k][Rij.dim]);  
  20.             }  
  21.         }  
  22.     }  
  23. }  
  24.   
  25. // 批量梯度下降,更新参数  
  26. public void updatePQ_batch(double alpha, double beta) {  
  27.   
  28.     for (int i = 0; i < M; i++) {  
  29.         ArrayList<Feature> Ri = this.dataset.getDataAt(i).getAllFeature();  
  30.   
  31.         for (Feature Rij : Ri) {  
  32.             // Rij.error=Rij.weight-PQ for updating P and Q  
  33.             double PQ = 0;  
  34.             for (int k = 0; k < K; k++) {  
  35.                 PQ += P[i][k] * Q[k][Rij.dim];  
  36.             }  
  37.             Rij.error = Rij.weight - PQ;  
  38.         }  
  39.     }  
  40.   
  41.     for (int i = 0; i < M; i++) {  
  42.         ArrayList<Feature> Ri = this.dataset.getDataAt(i).getAllFeature();  
  43.         for (Feature Rij : Ri) {  
  44.             for (int k = 0; k < K; k++) {  
  45.                 // 对参数更新的累积项  
  46.                 double eq_sum = 0;  
  47.                 double ep_sum = 0;  
  48.   
  49.                 for (int ki = 0; ki < M; ki++) {// 固定k和j之后,对所有i项加和  
  50.                     ArrayList<Feature> tmp = this.dataset.getDataAt(i).getAllFeature();  
  51.                     for (Feature Rj : tmp) {  
  52.                         if (Rj.dim == Rij.dim)  
  53.                             ep_sum += P[ki][k] * Rj.error;  
  54.                     }  
  55.                 }  
  56.                 for (Feature Rj : Ri) {// 固定k和i之后,对多有j项加和  
  57.                     eq_sum += Rj.error * Q[k][Rj.dim];  
  58.                 }  
  59.   
  60.                 // 对参数更新  
  61.                 P[i][k] += alpha * (2 * eq_sum - beta * P[i][k]);  
  62.                 Q[k][Rij.dim] += alpha * (2 * ep_sum - beta * Q[k][Rij.dim]);  
  63.             }  
  64.         }  
  65.     }  

  1. }  
  2. ================================================================================================

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页