百度
360搜索
搜狗搜索

gradient descent,梯度下降算法有哪些详细介绍

本文目录一览: 梯度下降算法有哪些

梯度下降法的介绍如下:
定义
梯度下降法(Gradient descent,简称GD)是一阶最优化算法。要使用梯度下降法找到一个函数的局部极小值,必须向函数上当前点对应梯度(或者是近似梯度)的反方向的规定步长距离点进行迭代搜索。
如果相反地向梯度正方向迭代进行搜索,则会接近函数的局部极大值点,这个过程则被称为梯度上升法。
用途
梯度下降法是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降法和最小二乘法是最常采用的方法。在求解损失函数的最小值时,可以通过梯度下降法来迭代求解。
得到最小化的损失函数和模型参数值。反过来,如果我们需要求解损失函数的最大值,这时就需要用梯度上升法来迭代了。在机器学习中,基于基本的梯度下降法发展了两种常用梯度下降方法,分别为随机梯度下降法和批量梯度下降法。
原理
在当前位置求偏导,即梯度,正常的梯度方向类似于上山的方向,是使值函数增大的,下山最快需使最小,从负梯度求最小值,这就是梯度下降。梯度上升是直接求偏导,梯度下降则是梯度上升的负值。
由于不知道怎么下山,于是需要走一步算一步,继续求解当前位置的偏导数。这样一步步的走下去,当走到了最低点,此时我们能得到一个近似最优解。
在当前位置求偏导,即梯度,正常的梯度方向类似于上山的方向,是使值函数增大的,下山最快需使最小,从负梯度求最小值,这就是梯度下降。梯度上升是直接求偏导,梯度下降则是梯度上升的负值。
由于不知道怎么下山,于是需要走一步算一步,继续求解当前位置的偏导数。这样一步步的走下去,当走到了最低点,此时我们能得到一个近似最优解。

随机梯度下降法到底是什么?

梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。
在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一,另一种常用的方法是最小二乘法。在求解损失函数的最小值时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数和模型参数值。
反过来,如果需要求解损失函数的最大值,这时就需要用梯度上升法来迭代了。在机器学习中,基于基本的梯度下降法发展了两种梯度下降方法,分别为随机梯度下降法和批量梯度下降法。
缺点:
(1)靠近极小值时收敛速度减慢。
(2)直线搜索时可能会产生一些问题。
(3)可能会“之字形”地下降。

如何理解机器学习中的gradient descent

梯度下降:我来试着用通俗的语言解释下吧,希望可以帮到你。
对于一个选定的模型,学习的目的是找到合适的参数,合适的参数指的是让损失函数值最小,损失函数就是表示预测值与实际值差距总和的(不够严格的说)。也就是说,希望找到一组参数,使预测值和实际值差别最小。
如下图是有两个参数的情况,两个横坐标代表两个参数,纵坐标表示损失函数的值,所以目的就是找到最低点就可以了。假设初始位置(就是两个参数初始值确定的位置)在山顶,那么要一步一步到达谷底,就是梯度下降。至于每一步往哪个方向走能保证是在下坡,需要根据求导计算梯度方向,每一步走多远要根据学习速率计算。

stochastic gradient descent 和 gradient descent有什么区别

1、stochastic gradient descent随机梯度下降
2、gradient descent梯度下降
而stochastic随机
形容词
random随机, 任意, 乱, 随便, 轻淡, 胡乱的
stochastic随机
1)Stochastic and mathematical models;
随机和数学模型;
2)In this paper, a numerical method for structure stochastic response analysis is presented.
对结构随机响应分析的数值积分方法进行了深入的研究。
3)The optimization of fuzzy stochastic systems is studied in this paper.
本文研究了模糊随机系统的模糊随机优化问题。
4)In this paper, the probability distribution of this kind of stochastic benefit is studied.
本文对这类随机利润的概率分布进行了研究。
5)In this paper, the problem of stochastic optimal control with uncertain terminating time is discussed.
文章研究了终时不确定的随机最优控制问题。

gradient descent method 什么意思

按字面理解就是“梯度下降方法”;最优化算法里面有个最速下降算法应该就是这个。就是按照梯度下降的方向搜索最优解。
gradient descent method
是梯度下降法 的意思
gradient descent method
梯度下降法
例句
1 A Fast Learning Method of Fuzzy Systems Based on GA and Gradient Descent Method
一种基于GA和梯度下降法的快速模糊系统学习方法
2 LVQ2 algorithm is derived rigorously as a gradient descent method to minimize the classification error;
严格推导出LVQ2算法实质上是一种使分类错误减小的梯度下降法;
3 It uses genetic algorithm for optimizing intrinsic parameters and gradient descent method for optimizing extrinsic parameters.
该标定方法内部参数的优化使用遗传算法,外部参数的优化使用梯度下降法,它具有原理简单、不需要估计初始值、鲁棒性强、标定参数更准确的优点。

什么是最优化

最优化是应用数学的一个分支,主要指在一定条件限制下,选取某种研究方案使目标达到最优的一种方法。最优化问题在当今的军事、工程、管理等领域有着极其广泛的应用。
常见方法?:1. 梯度下降法(Gradient Descent) 梯度下降法是最早最简单,也是最为常用的最优化方法。
梯度下降法实现简单,当目标函数是凸函数时,梯度下降法的解是全局解。一般情况下,其解不保证是全局最优解,梯度下降法的速度也未必是最快的。
梯度下降法的优化思想是用当前位置负梯度方向作为搜索方向,因为该方向为当前位置的最快下降方向,所以也被称为是”最速下降法“。最速下降法越接近目标值,步长越小,前进越慢。
2. 牛顿法(Newton's Method)和拟牛顿法(Quasi-Newton Methods)(1)牛顿法: 牛顿法是一种在实数域和复数域上近似求解方程的方法。方法使用函数f(x)的泰勒级数的前面几项来寻找方程f(x) = 0的根。牛顿法最大的特点就在于它的收敛速度很快。
(2)拟牛顿法: 拟牛顿法是求解非线性优化问题最有效的方法之一,其本质思想是改善牛顿法每次需要求解复杂的Hessian矩阵的逆矩阵的缺陷,它使用正定矩阵来近似Hessian矩阵的逆,从而简化了运算的复杂度。拟牛顿法和最速下降法一样只要求每一步迭代时知道目标函数的梯度。
通过测量梯度的变化,构造一个目标函数的模型使之足以产生超线性收敛性。这类方法大大优于最速下降法,尤其对于困难的问题。另外,因为拟牛顿法不需要二阶导数的信息,所以有时比牛顿法更为有效。如今,优化软件中包含了大量的拟牛顿算法用来解决无约束,约束,和大规模的优化问题。
3. 共轭梯度法(Conjugate Gradient) 共轭梯度法是介于最速下降法与牛顿法之间的一个方法,它仅需利用一阶导数信息,但克服了最速下降法收敛慢的缺点,又避免了牛顿法需要存储和计算Hesse矩阵并求逆的缺点,共轭梯度法不仅是解决大型线性方程组最有用的方法之一,也是解大型非线性最优化最有效的算法之一。
在各种优化算法中,共轭梯度法是非常重要的一种。其优点是所需存储量小,具有步收敛性,稳定性高,而且不需要任何外来参数。
4. 启发式优化方法 启发式方法指人在解决问题时所采取的一种根据经验规则进行发现的方法。其特点是在解决问题时,利用过去的经验,选择已经行之有效的方法,而不是系统地、以确定的步骤去寻求答案。
启发式优化方法种类繁多,包括经典的模拟退火方法、遗传算法、蚁群算法以及粒子群算法等等。
5. 拉格朗日乘数法 作为一种优化算法,拉格朗日乘子法主要用于解决约束优化问题,它的基本思想就是通过引入拉格朗日乘子来将含有n个变量和k个约束条件的约束优化问题转化为含有(n+k)个变量的无约束优化问题。拉格朗日乘子背后的数学意义是其为约束方程梯度线性组合中每个向量的系数。
将一个含有n个变量和k个约束条件的约束优化问题转化为含有(n+k)个变量的无约束优化问题,拉格朗日乘数法从数学意义入手,通过引入拉格朗日乘子建立极值条件,对n个变量分别求偏导对应了n个方程,然后加上k个约束条件(对应k个拉格朗日乘子)一起构成包含了(n+k)变量的(n+k)个方程的方程组问题,这样就能根据求方程组的方法对其进行求解。

导数、偏导数、方向导数、梯度、梯度下降

机器学习中的大部分问题都是优化问题,而绝大部分优化问题都可以使用梯度下降法处理,那么搞懂什么是梯度、什么是梯度下降法就非常重要!这是基础中的基础,也是必须掌握的概念! 提到梯度,就必须从导数(derivative)、偏导数(partial derivative)和方向导数(directional derivative)讲起,弄清楚这些概念,才能够正确理解为什么在优化问题中使用梯度下降法来优化目标函数,并熟练掌握梯度下降法(Gradient Descent)。 文章小节安排如下: 1.导数 2.导数和偏导数 3.导数和方向导数 4.导数和梯度 5.梯度下降法
一张图读懂导数和微分:

偏导数的定义如下: 可以看到, 导数与偏导数本质是一致的,都是当自变量的变化趋于0时,函数值的变化量与自变量变化量比值的极限。直观来说,偏导数也是函数在某一点上沿坐标轴正方向的变化率。 区别在于: 导数,指的是一元函数中,函数 在某一处沿 轴正方向的变化率; 偏导数,指的是多元函数中,函数 在某一点处沿着某一坐标轴 正方向的变化率。
方向导数的定义如下: 在前面导数和偏导数的定义中,均是沿坐标轴正方向讨论函数的变化率。那么当我们讨论函数沿任意方向的变化率时,也就引出了方向导数的定义,即: 某一点在某一趋近方向上的导数值。 通俗的解释是: 我们不仅要知道函数在坐标轴正方向上的变化率(即偏导数),而且还要设法求得函数在其他特定方向上的变化率。而方向导数就是函数在其他特定方向上的变化率。
梯度的定义如下: 梯度的提出职位回答一个问题: 函数在变量空间的某一点处,沿着哪一方向有最大的变化率? 梯度定义如下: 函数在某一点的梯度是这样一个向量,它的方向与取得最大方向导数的方向一致,而它的模为方向导数的最大值。 这里需要注意三点: 1)梯度是一个向量,即有方向有大小; 2)梯度的方向是最大方向导数的方向; 3)梯度的模是最大方向导数的值。
提问:导数与偏导数与方向导数是向量么? 向量的定义是有方向(direction)和大小(magnitude)的量。 从前面的定义可以这样看出,偏导数和方向导数表达的是函数在某一点沿某一个方向的变化率,也是具有方向和大小的。因此从这个角度理解,我们可以把偏导数和方向导数看作是一个向量,向量的方向就是变化率的方向,向量的模就是变化率的大小。 那么沿着这样一种思路,就可以如下理解梯度: 梯度即函数在某一点最大的方向导数,函数沿梯度方向函数有最大的变化率。
既然在在变量空间的某一点处,函数沿梯度方向局域最大的变化率,那么在优化目标函数的时候,自然是 沿着负梯度方向去减少函数值 ,以此来达到我们的优化目标。 如何沿着负梯度方向减少函数值呢?既然梯度是偏导数的集合,如下: 同时梯度和偏导数都是向量,那么参考向量运算法则,我们在每个变量轴上减少对应变量值即可,梯度下降法可以描述如下: 以上就是提嘟嘟下降法的由来,大部分的机器学习任务,都可以利用 来进行优化。
总结

神经网络算法-梯度下降GradientDescent

神经网络文章索引
上一篇神经网络结构中,我们介绍了神经元的结构,激活函数以及每个神经元激活值的算法,涉及到权重、偏置值等。
上一篇结尾提到,对于28*28的黑白手写图像识别,我们需要13002个权重和偏置数值,才能让我们的神经网络最后输出正确结果。
所谓的机器学习,就是寻找这13002个数值的过程。首先这里有两点需要注意:
在负无穷到正无穷之间,如何获得一万多个数字最佳的匹配值?这比在全世界挑选1万人让TA们一起相爱还要难。
我们的做法是用计算机强大运算速度,暴力解决问题。
好了,现在,暴力不是问题,要想出奇迹的关键就在于如何找到如何 优化的规律 。
要想做优化,首先要明确目标,找到当前神经网络和期望结果之间的差距。
从下图可以看到,随机设定的神经网络最终输出的是混乱的一层(被黄色线框标出),距离最右边我们期望只点亮神经元3的情况差距很大。
我们把混乱输出层的每个神经元与期望层每个对应神经元激活值相减,然后平方,再累加在一起,这就是方差cost代价,如下图,计算得到cost是3.37。
我们用这个cost来表示当前神经网络13002个设定值和期望设定值之间的差距,当然,这个cost等于0是差距最小,也就是最接近期望设定值。——当然这只是针对数字3的1张图片来说,我们需要的是针对0~9共10个数字的数万张图片,cost都能是最小。
从下图,我们来看一下神经网络的功能。它能利用13002个设定值经过3层神经元激活值的计算,把784个像素亮度变为10个数字(我们期望这10个数字中只有一个是1,其他都是0)。
这13002个权重和偏置数字,加上激活值的算法,就是神经网络的“想法”。
我们再来看看代价函数的情况,如下图,它是利用很多很多的训练图片(已经明确了对应的数字),把13002个数字变为1个cost代价数。
写成函数形式
我们假设最简单的情况,只有1个权重和1个偏置:
x和y是任意可能的数值,我们希望知道当x和y是什么数值的时候z最小。
每一组[x,y]都对应唯一的z,我们可以假想,有无数个[x,y,z]这样的位置点,在三维空间坐标中,它们就会组成一个面(曲面或平面),如下图。
从几何意义上看,我们就是要找到凹陷最低的那个位置点的x,y的值,因为那里z也就是cost代价最低。
假设上面的xyz绘制的cost曲面是个山地,你是一个旅行者,需要行走找到最低点的位置,你会怎么办?
没错,只要一直往下走,那么就能走到所在区域的最低点。——当然,如果山后面还有更深的山谷,那么你可能找到的只是局部最低点,而并非世界最低点。
实际上,对于复杂的超多维度来说,找到世界最低点几乎是不可能任务。我们唯一能做的就是多找几个局部最低点,然后选择其中最低的那个。
同样,如果我们落脚在[x',y'],那么可以尝试对比[x'+0.1,y'],[x'-0.1,y'],[x',y'-0.1],[x',y'+0.1],如果[x'+0.1,y']是最低的,那么我们就走到这里,然后继续尝试对比四周点的高度。这就是梯度下降的算法。
如下图,我们沿着虚线一步一步下山找到最低点。
首先快速的从下图了解几个基本概念。 下图的弧线表示的是某个函数y=f(x),比如抛物线方程y=x 2 。 曲线上任取两个点a,b,它们对应x和x+dx。(d是指德尔塔大写Δ,小写δ) ab两点对应的y的差是dy。 现在直线ab看上去是曲线的割线(有ab两个交点)。 假设b点沿着曲线,越来越靠近a点,那么dx极限趋近于0,这时候dy也会越来越小趋近于0,但是!我们会意识到dy/dx永远不会是0,而最终它仍然是角∠cab的对边比邻边,也就是正切三角函数值。 实际上,这也正是曲线的切线的定义。 可以想象,我们取的a点越是靠右,那么这个切线越是竖直。 如果我们把这个切线看做表示某个一次方程,如y=mx+n这种形式,那么a点越靠右,直线越竖直,m值也就越大。 我们把m值叫做直线的斜率。

导数derivative ,一元函数y=f(x)(即因变量y只受到一个自变量x影响的函数)中任意取x,如果x增加极小趋近于0的Δx(或者写为dx),那么y相应的被增加Δy(或者写作dy),那么导数就是dy/dx,而又有dy=f(x+dx)-f(x),所以:

从函数的曲线图上可以看到,某点的导数就是dx趋近于0时候∠cab的正切,导数反映了切线的陡峭程度,也就是y随着x变化的快慢程度。
微分differential ,简单说就是Δx和Δy,或者记作dx和dy。x称之为自变量,y称之为因变量,那么x趋近于最小的时候的值,就是x的微分(趋近0又不是0的那个神秘值),同样y的微分也是这个意思,总之是想得到又摸不到的神奇值。
斜率slope ,一元一次函数(直线方程)y=mx+n的系数m值。在这里就是a点的导数值f'(x)。
切线tangent ,某个点a的切线,就是经过a点的,以A点斜率为系数的方程y=f'(x)x+n所表示的直线。
自变量dependent variable和因变量 independent variable ,x自己的变化,引发y被动变化。
好了,我们来看 多变量微分Multivariable differential 。
上面都是一个y收到一个x的影响y=f(x),多变量就是不止受到一个自变量的影响,我们以最简单的z=f(x,y)为例,z=x 2 +y 2 。

绿轴x的变化和红轴y的变化,都会对应蓝轴z的变化。 x从负无穷到正无穷无限种可能,y也是无限种可能,x和y复合到一起就在水平方向覆盖了全部地面,z值有高有低,就像现实世界中的海拔一样,把xy平面凸起或凹陷。(图中粉色没有画出全部曲面)
我们可以想象,这时候不能讨论A点的切线了,而应该考虑它的 切平面tangent plane (下图绿色平面)。
方向导数directional derivative ,就是曲面上过A点的任意曲线的切线(下图紫色线)组成的平面,就是切平面。
这么多紫色的方向中,哪一个方向最陡峭?对于这个z=x 2 +y 2 函数来说,明显是最接近竖直朝上的那个箭头和最接近竖直朝下的那个箭头。 和曲线一样道理,越陡峭意味着z对x、y的变化越敏感,或者说dx、dy的变化会引发更多的dz。 梯度gradient ,我们规定,能够引发因变量最快变化的那个切线正方向,就叫做曲面方程上这个点的梯度。注意梯度是个xyz表示的三维方向,例如[0,0,1]表示z轴竖直向上,[0.1,0.1,1]就往xy的正方向偏一点点。
对于只有xy两个变量的三维曲面来说,我们还可以只是考虑x+0.1,x-0.1,y+0.1,y-0.1这样的试探方法找到最低点,只要2*2=4次就可以了,周全一点也就8次。
但是对于我们手写数字识别中13002个自变量来说,那就要2 13002 次,这是不可行的。
借用多元微分,我们可以找到13002个自变量某一随机点对应的切平面(实际早已不是什么平面了,我们姑且这么说),也可以计算出其中变化最快的方向,就是梯度,数学家已经证明,不管多少个维度,沿着梯度往前走一步,都能获得最快变化后新的一个点,这个点是一个n维向量,对于我们的案例来说就是13003个新数字组成的数组[0.322,0.123,0.55,0.222,...0.233]共13003个数字。
唯一要说明的一点不同就是,为了找最低点,我们不是往上走,而是往相反的负方向,朝下走。
步长step size ,就是我们每次沿着 负梯度 往下走多远,在机器学习算法里面它叫做 学习率learning rate ,同样道理,步子迈小了走得太慢,找到最低点耗时间太久,步子太大了容易跳过最低点(注意,1万多维的复杂情况不是我们上面三维漏斗曲面那么简单可以描述的)。所以我们经常设置0.00001这样小的数字,好在很多机器学习程序都会适当的自动调整它(比如Tensorflow中的梯度下降优化GradientDescentOptimizer),实际上不会让它太慢。
同时,我们从上图中看到,计算出的负梯度是由很多数字组成的数组,每个数字代表一个维度(就像xy那样),所以我们只要在原来的位置点坐标(比如[x,y])上分别把这个梯度(比如[0.1,-0.3])加上去就能得到新的点([x+0.1,y-0.3])。
内容小结
如果您发现文章错误,请不吝留言指正; 如果您觉得有用,请点喜欢; 如果您觉得很有用,感谢转发~
END

阅读更多 >>>  extern的作用,extern c作用

用matlab实现梯度下降算法(gradient descent)。

function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)
%GRADIENTDESCENT Performs gradient descent to learn theta
% theta = GRADIENTDESENT(X, y, theta, alpha, num_iters) updates theta by
% taking num_iters gradient steps with learning rate alpha
% Initialize some useful values
m = length(y); % number of training examples
J_history = zeros(num_iters, 1);
for iter = 1:num_iters,
% ====================== YOUR CODE HERE ======================
% Instructions: Perform a single gradient step on the parameter vector
% theta.
%
% Hint: While debugging, it can be useful to print out the values
% of the cost function (computeCost) and gradient here.

p=theta(1)-alpha*(1/m)*(sum((X*theta-y).*X(:,1)));
q=theta(2)-alpha*(1/m)*(sum((X*theta-y).*X(:,2)));
theta(1)=p;
theta(2)=q;
% ============================================================
% Save the cost J in every iteration
J_history(iter) = computeCost(X, y, theta);
end
end

梯度下降法的原理是什么?

梯度下降是非常常用的优化算法。作为机器学习的基础知识,这是一个必须要掌握的算法。借助本文,让我们来一起详细了解一下这个算法。
前言
本文的代码可以到我的Github上获取:
https://github.com/paulQuei/gradient_descent
本文的算法示例通过Python语言实现,在实现中使用到了numpy和matplotlib。如果你不熟悉这两个工具,请自行在网上搜索教程。
关于优化
大多数学习算法都涉及某种形式的优化。优化指的是改变x以最小化或者最大化某个函数的任务。
我们通常以最小化指代大多数最优化问题。最大化可经由最小化来实现。
我们把要最小化或最大化的函数成为目标函数(objective function)或准则(criterion)。
我们通常使用一个上标*表示最小化或最大化函数的x值,记做这样:
[x^* = arg; min; f(x)]
优化本身是一个非常大的话题。如果有兴趣,可以通过《数值优化》和《运筹学》的书籍进行学习。
模型与假设函数
所有的模型都是错误的,但其中有些是有用的。– George Edward Pelham Box
模型是我们对要分析的数据的一种假设,它是为解决某个具体问题从数据中学习到的,因此它是机器学习最核心的概念。
针对一个问题,通常有大量的模型可以选择。
本文不会深入讨论这方面的内容,关于各种模型请参阅机器学习的相关书籍。本文仅以最简单的线性模型为基础来讨论梯度下降算法。
这里我们先介绍一下在监督学习(supervised learning)中常见的三个符号:
m,描述训练样本的数量
x,描述输入变量或特征
y,描述输出变量或者叫目标值
请注意,一个样本可能有很多的特征,因此x和y通常是一个向量。不过在刚开始学习的时候,为了便于理解,你可以暂时理解为这就是一个具体的数值。训练集会包含很多的样本,我们用 表示其中第i个样本。
x是数据样本的特征,y是其目标值。例如,在预测房价的模型中,x是房子的各种信息,例如:面积,楼层,位置等等,y是房子的价格。在图像识别的任务中,x是图形的所有像素点数据,y是图像中包含的目标对象。
我们是希望寻找一个函数,将x映射到y,这个函数要足够的好,以至于能够预测对应的y。由于历史原因,这个函数叫做假设函数(hypothesis function)。
学习的过程如下图所示。即:首先根据已有的数据(称之为训练集)训练我们的算法模型,然后根据模型的假设函数来进行新数据的预测。
线性模型(linear model)正如其名称那样:是希望通过一个直线的形式来描述模式。线性模型的假设函数如下所示:
[h_{\theta}(x) = \theta_{0} + \theta_{1} * x]
这个公式对于大家来说应该都是非常简单的。如果把它绘制出来,其实就是一条直线。
下图是一个具体的例子,即: 的图形:
在实际的机器学习工程中,你会拥有大量的数据。这些数据会来自于某个数据源。它们存储在csv文件中,或者以其他的形式打包。
但是本文作为演示使用,我们通过一些简单的代码自动生成了需要的数据。为了便于计算,演示的数据量也很小。
import numpy as np
max_x = 10data_size = 10theta_0 = 5theta_1 = 2
def get_data:x = np.linspace(1, max_x, data_size)noise = np.random.normal(0, 0.2, len(x))y = theta_0 + theta_1 * x + noisereturn x, y
这段代码很简单,我们生成了x范围是 [1, 10] 整数的10条数据。对应的y是以线性模型的形式计算得到,其函数是:。现实中的数据常常受到各种因素的干扰,所以对于y我们故意加上了一些高斯噪声。因此最终的y值为比原先会有轻微的偏离。
最后我们的数据如下所示:
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]y = [6.66, 9.11, 11.08, 12.67, 15.12, 16.76, 18.75, 21.35, 22.77, 24.56]
我们可以把这10条数据绘制出来这样就有一个直观的了解了,如下图所示:
虽然演示用的数据是我们通过公式计算得到的。但在实际的工程中,模型的参数是需要我们通过数据学习到的。所以下文我们假设我们不知道这里线性模式的两个参数是什么,而是通过算法的形式求得。
最后再跟已知的参数进行对比以验证我们的算法是否正确。
有了上面的数据,我们可以尝试画一条直线来描述我们的模型。
例如,像下面这样画一条水平的直线:
很显然,这条水平线离数据太远了,非常的不匹配。
那我们可以再画一条斜线。
我们初次画的斜线可能也不贴切,它可能像下面这样:
最后我们通过不断尝试,找到了最终最合适的那条,如下所示:
梯度下降算法的计算过程,就和这种本能式的试探是类似的,它就是不停的迭代,一步步的接近最终的结果。
代价函数
上面我们尝试了几次通过一条直线来拟合(fitting)已有的数据。
二维平面上的一条直线可以通过两个参数唯一的确定,两个参数的确定也即模型的确定。那如何描述模型与数据的拟合程度呢?答案就是代价函数。
代价函数(cost function)描述了学习到的模型与实际结果的偏差程度。以上面的三幅图为例,最后一幅图中的红线相比第一条水平的绿线,其偏离程度(代价)应该是更小的。
很显然,我们希望我们的假设函数与数据尽可能的贴近,也就是说:希望代价函数的结果尽可能的小。这就涉及到结果的优化,而梯度下降就是寻找最小值的方法之一。
代价函数也叫损失函数。对于每一个样本,假设函数会依据计算出一个估算值,我们常常用来表示。即 。
很自然的,我们会想到,通过下面这个公式来描述我们的模型与实际值的偏差程度:
[(h_\theta(x^i) - y^i)^2 = (\widehat{y}^{i} - y^i)^2 = (\theta_{0} + \theta_{1} * x^{i} - y^{i})^2]
请注意, 是实际数据的值, 是我们的模型的估算值。前者对应了上图中的离散点的y坐标,后者对应了离散点在直线上投影点的y坐标。
每一条数据都会存在一个偏差值,而代价函数就是对所有样本的偏差求平均值,其计算公式如下所示:
[L(\theta) = \frac {1}{m} \sum_{i=1}^{m}(h_\theta(x^i) - y^i)^2 = \frac {1}{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i})^2]
当损失函数的结果越小,则意味着通过我们的假设函数估算出的结果与真实值越接近。这也就是为什么我们要最小化损失函数的原因。
不同的模型可能会用不同的损失函数。例如,logistic回归的假设函数是这样的:。其代价函数是这样的:借助上面这个公式,我们可以写一个函数来实现代价函数:
def cost_function(x, y, t0, t1):cost_sum = 0for i in range(len(x)):cost_item = np.power(t0 + t1 * x[i] - y[i], 2)cost_sum += cost_itemreturn cost_sum / len(x)
这个函数的代码应该不用多做解释,它就是根据上面的完成计算。
我们可以尝试选取不同的 和 组合来计算代价函数的值,然后将结果绘制出来:
import numpy as npimport matplotlib.pyplot as plt
from matplotlib import cmfrom mpl_toolkits.mplot3d import Axes3D
theta_0 = 5theta_1 = 2
def draw_cost(x, y):fig = plt.figure(figsize=(10, 8))ax = fig.gca(projection='3d')scatter_count = 100radius = 1t0_range = np.linspace(theta_0 - radius, theta_0 + radius, scatter_count)t1_range = np.linspace(theta_1 - radius, theta_1 + radius, scatter_count)cost = np.zeros((len(t0_range), len(t1_range)))for a in range(len(t0_range)):for b in range(len(t1_range)):cost[a][b] = cost_function(x, y, t0_range[a], t1_range[b])t0, t1 = np.meshgrid(t0_range, t1_range)
ax.set_xlabel('theta_0')ax.set_ylabel('theta_1')ax.plot_surface(t0, t1, cost, cmap=cm.hsv)
在这段代码中,我们对 和 各自指定了一个范围进行100次的采样,然后以不同的 组合对来计算代价函数的值。
如果我们将所有点的代价函数值绘制出来,其结果如下图所示:
从这个图形中我们可以看出,当 越接近 [5, 2]时其结果(偏差)越小。相反,离得越远,结果越大。
直观解释
从上面这幅图中我们可以看出,代价函数在不同的位置结果大小不同。
从三维的角度来看,这就和地面的高低起伏一样。最高的地方就好像是山顶。
而我们的目标就是:从任意一点作为起点,能够快速寻找到一条路径并以此到达图形最低点(代价值最小)的位置。
而梯度下降的算法过程就和我们从山顶想要快速下山的做法是一样的。
在生活中,我们很自然会想到沿着最陡峭的路往下行是下山速度最快的。如下面这幅图所示:
针对这幅图,细心的读者可能很快就会有很多的疑问,例如:
对于一个函数,怎么确定下行的方向?
每一步该往前走多远?
有没有可能停留在半山腰的平台上?
这些问题也就是本文接下来要讨论的内容。
算法描述
梯度下降算法最开始的一点就是需要确定下降的方向,即:梯度。
我们常常用 来表示梯度。
对于一个二维空间的曲线来说,梯度就是其切线的方向。如下图所示:
而对于更高维空间的函数来说,梯度由所有变量的偏导数决定。
其表达式如下所示:
[\nabla f({\theta}) = ( \frac{\partial f({\theta})}{\partial \theta_1} , \frac{\partial f({\theta})}{\partial \theta_2} , ... , \frac{\partial f({\theta})}{\partial \theta_n} )]
在机器学习中,我们主要是用梯度下降算法来最小化代价函数,记做:
[\theta ^* = arg min L(\theta)]
其中,L是代价函数,是参数。
梯度下降算法的主体逻辑很简单,就是沿着梯度的方向一直下降,直到参数收敛为止。
记做:
[\theta ^{k + 1}_i = \theta^{k}_i - \lambda \nabla f(\theta^{k})]
这里的下标i表示第i个参数。 上标k指的是第k步的计算结果,而非k次方。在能够理解的基础上,下文的公式中将省略上标k。这里有几点需要说明:
收敛是指函数的变化率很小。具体选择多少合适需要根据具体的项目来确定。在演示项目中我们可以选择0.01或者0.001这样的值。不同的值将影响算法的迭代次数,因为在梯度下降的最后,我们会越来越接近平坦的地方,这个时候函数的变化率也越来越小。如果选择一个很小的值,将可能导致算法迭代次数暴增。
公式中的 称作步长,也称作学习率(learning rate)。它决定了每一步往前走多远,关于这个值我们会在下文中详细讲解。你可以暂时人为它是一个类似0.01或0.001的固定值。
在具体的项目,我们不会让算法无休止的运行下去,所以通常会设置一个迭代次数的最大上限。
线性回归的梯度下降
有了上面的知识,我们可以回到线性模型代价函数的梯度下降算法实现了。
首先,根据代价函数我们可以得到梯度向量如下:
[\nabla f({\theta}) = (\frac{\partial L(\theta)}{ \partial\theta_{0}}, \frac{ \partial L(\theta)}{ \partial\theta_{1}}) = (\frac {2}{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i}) , \frac {2}{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i}) x^{i})]
接着,将每个偏导数带入迭代的公式中,得到:
[\theta_{0} := \theta_{0} - \lambda \frac{\partial L(\theta_{0})}{ \partial\theta_{0}} = \theta_{0} - \frac {2 \lambda }{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i}) \ \theta_{1} := \theta_{1} - \lambda \frac{\partial L(\theta_{1})}{ \partial\theta_{1}} = \theta_{1} - \frac {2 \lambda }{m} \sum_{i=1}^{m}(\theta_{0} + \theta_{1} * x^{i} - y^{i}) x^{i}]
由此就可以通过代码实现我们的梯度下降算法了,算法逻辑并不复杂:
learning_rate = 0.01
def gradient_descent(x, y):t0 = 10t1 = 10delta = 0.001for times in range(1000):sum1 = 0sum2 = 0for i in range(len(x)):sum1 += (t0 + t1 * x[i] - y[i])sum2 += (t0 + t1 * x[i] - y[i]) * x[i]t0_ = t0 - 2 * learning_rate * sum1 / len(x)t1_ = t1 - 2 * learning_rate * sum2 / len(x)print('Times: {}, gradient: [{}, {}]'.format(times, t0_, t1_))if (abs(t0 - t0_) < delta and abs(t1 - t1_) < delta):print('Gradient descent finish')return t0_, t1_t0 = t0_t1 = t1_print('Gradient descent too many times')return t0, t1
这段代码说明如下:
我们随机选择了 都为10作为起点
设置最多迭代1000次
收敛的范围设为0.001
学习步长设为0.01
如果我们将算法迭代过程中求得的线性模式绘制出来,可以得到下面这幅动态图:
最后算法得到的结果如下:
Times: 657, gradient: [5.138008697, 1.952931052920264]Times: 658, gradient: [5.138000733, 1.9530753071808193]Times: 659, gradient: [5.138004868, 1.9532138003]Times: 660, gradient: [5.138009619, 1.9533620008416623]Gradient descent finish
从输出中可以看出,算法迭代了660次就收敛了。这时的结果[5.138009619, 1.9533620008416623],这已经比较接近目标值 [5, 2]了。如果需要更高的精度,可以将delta的值调的更小,当然,此时会需要更多的迭代次数。
高维扩展
虽然我们举的例子是二维的,但是对于更高维的情况也是类似的。同样是根据迭代的公式进行运算即可:
[\theta_{i} = \theta_{i} - \lambda \frac {\partial L(\theta)}{\partial \theta_i} = \theta_{i} - \frac{2\lambda}{m} \sum_{i=1}^{m}(h_\theta(x^{k})-y^k)x_i^k]
这里的下标i表示第i个参数,上标k表示第k个数据。
梯度下降家族BGD
在上面的内容中我们看到,算法的每一次迭代都需要把所有样本进行遍历处理。这种做法称为之Batch Gradient Descent,简称BGD。作为演示示例只有10条数据,这是没有问题的。
但在实际的项目中,数据集的数量可能是几百万几千万条,这时候每一步迭代的计算量就会非常的大了。
于是就有了下面两个变种。
SGD
Stochastic Gradient Descent,简称SGD,这种算法是每次从样本集中仅仅选择一个样本来进行计算。很显然,这样做算法在每一步的计算量一下就少了很多。
其算法公式如下:
[\theta_{i} = \theta_{i} - \lambda \frac {\partial L(\theta)}{\partial \theta_i} = \theta_{i} - \lambda(h_\theta(x^k)-y^k)x_i^k]
当然,减少算法计算量也是有代价的,那就是:算法结果会强依赖于随机取到的数据情况,这可能会导致算法的最终结果不太令人满意。
MBGD
以上两种做法其实是两个极端,一个是每次用到了所有数据,另一个是每次只用一个数据。
我们自然就会想到两者取其中的方法:每次选择一小部分数据进行迭代。这样既避免了数据集过大导致每次迭代计算量过大的问题,也避免了单个数据对算法的影响。
这种算法称之为Mini-batch Gradient Descent,简称MBGD。
其算法公式如下:
[\theta_{i} = \theta_{i} - \lambda \frac {\partial L(\theta)}{\partial \theta_i} = \theta_{i} - \frac{2\lambda}{m} \sum_{i=a}^{a + b}(h_\theta(x^k)-y^k)x_i^k]
当然,我们可以认为SGD是Mini-batch为1的特例。
针对上面提到的算法变种,该如何选择呢?
下面是Andrew Ng给出的建议:
如果样本数量较小(例如小于等于2000),选择BGD即可。
如果样本数量很大,选择 来进行MBGD,例如:64,128,256,512。
下表是 Optimization for Deep Learning 中对三种算法的对比
方法准确性更新速度内存占用在线学习BGD好慢高否SGD好(with annealing)快低是MBGD好中等中等是算法优化
式7是算法的基本形式,在这个基础上有很多人进行了更多的研究。接下来我们介绍几种梯度下降算法的优化方法。
Momentum
Momentum是动量的意思。这个算法的思想就是借助了动力学的模型:每次算法的迭代会使用到上一次的速度作为依据。
算法的公式如下:
[v^t = \gamma v^{t - 1} + \lambda \nabla f(\theta) \ \theta = \theta - v_t]
对比式7可以看出,这个算法的主要区别就是引入了,并且,每个时刻的受前一个时刻的影响。
从形式上看,动量算法引入了变量 v 充当速度角色——它代表参数在参数空间移动的方向和速率。速度被设为负梯度的指数衰减平均。名称动量来自物理类比,根据牛顿运动定律,负梯度是移动参数空间中粒子的力。动量在物理学上定义为质量乘以速度。在动量学习算法中,我们假设是单位质量,因此速度向量 v 也可以看作是粒子的动量。
对于可以取值0,而是一个常量,设为0.9是一个比较好的选择。
下图是momentum算法的效果对比:
对原来的算法稍加修改就可以增加动量效果:
def gradient_descent_with_momentum(x, y):t0 = 10t1 = 10delta = 0.001v0 = 0v1 = 0gamma = 0.9for times in range(1000):sum1 = 0sum2 = 0for i in range(len(x)):sum1 += (t0 + t1 * x[i] - y[i])sum2 += (t0 + t1 * x[i] - y[i]) * x[i]v0 = gamma * v0 + 2 * learning_rate * sum1 / len(x)v1 = gamma * v1 + 2 * learning_rate * sum2 / len(x)t0_ = t0 - v0t1_ = t1 - v1print('Times: {}, gradient: [{}, {}]'.format(times, t0_, t1_))if (abs(t0 - t0_) < delta and abs(t1 - t1_) < delta):print('Gradient descent finish')return t0_, t1_t0 = t0_t1 = t1_print('Gradient descent too many times')return t0, t1
以下是该算法的输出:
Times: 125, gradient: [4.955453758569991, 2.000005017897775]Times: 126, gradient: [4.955309381126545, 1.9956928964532015]Times: 127, gradient: [4.9542964317327005, 1.9855674828684156]Times: 128, gradient: [4.9536358220657, 1.9781138005]Times: 129, gradient: [4.95412496254411, 1.9788858350530971]Gradient descent finish
从结果可以看出,改进的算法只用了129次迭代就收敛了。速度比原来660次快了很多。
同样的,我们可以把算法计算的过程做成动态图:
对比原始的算法过程可以看出,改进算法最大的区别是:在寻找目标值时会在最终结果上下跳动,但是越往后跳动的幅度越小,这也就是动量所产生的效果。
Learning Rate 优化
至此,你可能还是好奇该如何设定学习率的值。
事实上,这个值的选取需要一定的经验或者反复尝试才能确定。
《深度学习》一书中是这样描述的:“与其说是科学,这更像是一门艺术,我们应该谨慎地参考关于这个问题的大部分指导。”。关键在于,这个值的选取不能过大也不能过小。
如果这个值过小,会导致每一次迭代的步长很小,其结果就是算法需要迭代非常多的次数。
那么,如果这个值过大会怎么样呢?其结果就是:算法可能在结果的周围来回震荡,却落不到目标的点上。下面这幅图描述了这个现象:
事实上,学习率的取值未必一定要是一个常数,关于这个值的设定有很多的研究。
下面是比较常见的一些改进算法。
AdaGrad
AdaGrad是Adaptive Gradient的简写,该算法会为每个参数设定不同的学习率。它使用历史梯度的平方和作为基础来进行计算。
其算法公式如下:
[\theta_i = \theta_i - \frac{\lambda}{\sqrt{G_t + \epsilon}} \nabla f(\theta)]
对比式7,这里的改动就在于分号下面的根号。
根号中有两个符号,第二个符号比较好理解,它就是为了避免除0而人为引入的一个很小的常数,例如可以设为:0.001。
第一个符号的表达式展开如下:
[G_t = \sum_{i = 1}^{t} \nabla f(\theta){i}\nabla f(\theta){i}^{T}]
这个值其实是历史中每次梯度的平方的累加和。
AdaGrad算法能够在训练中自动的对learning rate进行调整,对于出现频率较低参数采用较大的学习率;相反,对于出现频率较高的参数采用较小的学习率。因此,Adagrad非常适合处理稀疏数据。
但该算法的缺点是它可能导致学习率非常小以至于算法收敛非常的慢。
关于这个算法的直观解释可以看李宏毅教授的视频课程:ML Lecture 3-1: Gradient Descent。
RMSProp
RMS是Root Mean Square的简写。RMSProp是AI教父Geoff Hinton提出的一种自适应学习率方法。AdaGrad会累加之前所有的梯度平方,而RMSProp仅仅是计算对应的平均值,因此可缓解Adagrad算法学习率下降较快的问题。
该算法的公式如下:
[E[\nabla f(\theta_{i})^2]^{t} = \gamma E[\nabla f(\theta_{i})^2]^{t - 1} + (1-\gamma)(\nabla f(\theta_{i})^{t})^{2} \ \theta_i = \theta_i - \frac{\lambda}{\sqrt{E[g^2]^{t+1} + \epsilon}} \nabla f(\theta_{i})]
类似的,是为了避免除0而引入。 是衰退参数,通常设为0.9。
这里的 是t时刻梯度平方的平均值。
Adam
Adam是Adaptive Moment Estimation的简写。它利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。
Adam的优点主要在于经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。
该算法公式如下:
[m^{t} = \beta_{1} m^{t-1} + (1-\beta_{1}) \nabla f(\theta) \ v^{t} = \beta_{2} v^{t-1} + (1-\beta_{2}) \nabla f(\theta)^2 \ \widehat{m}^{t} = \frac{m^{t}}{1 - \beta^{t}_1} \ \widehat{v}^{t} = \frac{v^{t}}{1 - \beta^{t}_2} \ \theta = \theta - \frac{\lambda}{\sqrt{\widehat{v}^{t}} + \epsilon}\widehat{m}^{t}]
,分别是对梯度的一阶矩估计和二阶矩估计。, 是对,的校正,这样可以近似为对期望的无偏估计。
Adam算法的提出者建议 默认值为0.9,默认值为0.999,默认值为 。
在实际应用中 ,Adam较为常用,它可以比较快地得到一个预估结果。
优化小结
这里我们列举了几种优化算法。它们很难说哪种最好,不同的算法适合于不同的场景。在实际的工程中,可能需要逐个尝试一下才能确定选择哪一个,这个过程也是目前现阶段AI项目要经历的工序之一。
实际上,该方面的研究远不止于此,如果有兴趣,可以继续阅读 《Sebastian Ruder: An overview of gradient descent optimization algorithms》 这篇论文或者 Optimization for Deep Learning 这个Slides进行更多的研究。
由于篇幅所限,这里不再继续展开了。
算法限制
梯度下降算法存在一定的限制。首先,它要求函数必须是可微分的,对于不可微的函数,无法使用这种方法。
除此之外,在某些情况下,使用梯度下降算法在接近极值点的时候可能收敛速度很慢,或者产生Z字形的震荡。这一点需要通过调整学习率来回避。
另外,梯度下降还会遇到下面两类问题。
局部最小值
局部最小值(Local Minima)指的是,我们找到的最小值仅仅是一个区域内的最小值,而并非全局的。由于算法的起点是随意取的,以下面这个图形为例,我们很容易落到局部最小值的点里面。
这就是好像你从上顶往下走,你第一次走到的平台未必是山脚,它有可能只是半山腰的一个平台的而已。
算法的起点决定了算法收敛的速度以及是否会落到局部最小值上。
坏消息是,目前似乎没有特别好的方法来确定选取那个点作为起点是比较好的,这就有一点看运气的成分了。多次尝试不同的随机点或许是一个比较好的方法,这也就是为什么做算法的优化这项工作是特别消耗时间的了。
但好消息是:
对于凸函数或者凹函数来说,不存在局部极值的问题。其局部极值一定是全局极值。
最近的一些研究表明,某些局部极值并没有想象中的那么糟糕,它们已经非常的接近全局极值所带来的结果了。
鞍点
除了Local Minima,在梯度下降的过程中,还有可能遇到另外一种情况,即:鞍点(Saddle Point)。鞍点指的是我们找到点某个点确实是梯度为0,但它却不是函数的极值,它的周围既有比它小的值,也有比它大的值。这就好像马鞍一样。
如下图所示:
多类随机函数表现出以下性质:在低维空间中,局部极值很普遍。但在高维空间中,局部极值比较少见,而鞍点则很常见。
不过对于鞍点,可以通过数学方法Hessian矩阵来确定。关于这点,这里就不再展开了,有兴趣的读者可以以这里提供的几个链接继续探索。
参考资料与推荐读物
Wikipeida: Gradient descent
Sebastian Ruder: An overview of gradient descent optimization algorithms
吴恩达:机器学习
吴恩达:深度学习
Peter Flach:机器学习
李宏毅 - ML Lecture 3-1: Gradient Descent
PDF: 李宏毅 - Gradient Descent
Intro to optimization in deep learning: Gradient Descent
Intro to optimization in deep learning: Momentum, RMSProp and Adam
Stochastic Gradient Descent – Mini-batch and more
刘建平Pinard - 梯度下降(Gradient Descent)小结
多元函数的偏导数、方向导数、梯度以及微分之间的关系思考
[Machine Learning] 梯度下降法的三种形式BGD、SGD以及MBGD
作者:阿Paul https://paul.pub/gradient-descent/

阅读更多 >>>  微观经济学考试重点

网站数据信息

"gradient descent,梯度下降算法有哪些"浏览人数已经达到20次,如你需要查询该站的相关权重信息,可以点击进入"Chinaz数据" 查询。更多网站价值评估因素如:gradient descent,梯度下降算法有哪些的访问速度、搜索引擎收录以及索引量、用户体验等。 要评估一个站的价值,最主要还是需要根据您自身的需求,如网站IP、PV、跳出率等!