梯度下降算法是什么,梯度下降算法是最常用也是最有效
1.概述梯度下降广泛应用于机器学习。无论是线性回归还是Logistic回归,其主要目的都是通过迭代找到目标函数的最小值或者收敛到最小值。
本文将从一个下坡场景开始,先提出梯度下降算法的基本思想,然后从数学上解释梯度下降算法的原理,解释为什么要用梯度,最后实现一个简单的梯度下降算法的例子!
2.梯度下降算法2.1场景假设梯度下降法的基本思想可以类比为一个下坡过程。
想象这样一个场景:一个人被困在山上,需要从山上下来(找到山的最低点,也就是山谷)。但此时山上雾很浓,导致能见度低;所以下山的路径无法确定。你必须利用身边的信息,一步步找到下山的路。这时候你可以用梯度下降算法来帮助自己下山。怎么做?先以他现在的位置为基准,找到这个位置最陡的地方,然后向下走一步,然后继续以现在的位置为基准,再找到最陡的地方,然后一直走,直到最后到达最低的地方;上山也是一样,只是这次变成了梯度上升算法。
2.2梯度下降梯度下降的基本过程与下坡场景非常相似。
首先,我们有一个可微函数。这个函数代表一座山。我们的目标是找到这个函数的最小值,也就是山的底部。按照前面的场景假设,下山最快的方法是找到当前位置最陡的方向,然后沿着这个方向下山,对应的就是函数,也就是找到给定点的梯度,然后向梯度的反方向移动,这样函数值下降最快!因为梯度的方向是函数变化最快的方向(后面会详细解释)。
所以我们反复使用这个方法,反复计算梯度,最后达到局部极小,类似于我们下降的过程。而找梯度决定了最陡方向,这是场景中测量方向的手段。那么为什么梯度的方向是最陡的呢?接下来,让我们从差异化开始:
2.2.1区分区分的意义可以从不同的角度来看。最常用的两种是:
1)函数图像中点的切线的斜率。
2)函数的变化率
差异化的几个例子:
1.当函数只有一个变量时,单个变量的微分
2.多变量微分,当函数有多个变量时,即分别对每个变量进行微分。
2.2.2梯度梯度实际上是多元微分的推广。
下面的例子:
我们可以看到,梯度分别区分每个变量,然后用逗号分隔。包括梯度,表明梯度实际上是一个向量。
在梯度微积分中是一个非常重要的概念,梯度的意义之前已经提到过。
在一元函数中,梯度实际上是函数的微分,代表函数在给定点的切线的斜率。
在多元函数中,梯度是一个向量,向量有方向。梯度的方向表示函数在给定点上升最快的方向。
这解释了为什么我们需要尽一切可能获得梯度!当我们需要到达山脚时,我们需要观察每一步最陡的地方,而坡度正好告诉我们这个方向。梯度的方向就是函数在给定点上升最快的方向,那么梯度的反方向就是函数在给定点下降最快的方向,这正是我们所需要的。所以只要沿着坡度一直走,就能到达当地最低点!
2.3数学解释
2.3.1 在梯度下降算法中称为学习率或步长,意思是我们可以通过来控制每一步的距离,实际上就是不要走得太快,错过最低点。同时,一定不要走得太慢,导致太阳落山,到不了山脚下。所以的选择在梯度下降法中往往是非常重要的!不能太大也不能太小。如果太小,可能会导致到达最低点的延迟。太大的话会导致错过最低点!
2.3.2渐变要乘以一个负号渐变前面有一个负号,意思是向渐变的反方向移动!我们前面提到过,梯度的方向实际上是该点函数上升最快的方向!而我们需要往下降最快的方向走,自然是负梯度的方向,所以这里需要加一个负号;那么如果时间上坡,也就是梯度上升算法,当然就不需要加负号了。
3.例子我们已经基本了解了梯度下降算法的计算过程,那么我们来看几个梯度下降算法的小例子,先从一元函数开始,再引入多元函数。
如图,经过四次运算,也就是四步,基本达到了函数的最低点,也就是山底。
3.2多变量函数的梯度下降我们假设有一个目标函数
现在用梯度下降法计算这个函数的最小值。通过观察可以发现,最小值其实是(0,0)点。但是接下来,我们会从梯度下降算法开始一步步计算这个最小值!
让我们假设我们最初的起点是:
初始学习率为:=0.1。
我们发现它几乎接近函数的最小点。
4.代码实现4.1场景分析接下来,我们用python实现一个简单的梯度下降算法。该方案是线性回归的一个简单示例:假设现在我们有一系列点,如下图所示:
我们将使用梯度下降法来拟合这条直线!
首先我们需要定义一个代价函数,这里我们选择均方误差代价函数(也叫平方误差代价函数)。
在这个公式中
1)m是数据集中数据点的个数,即样本数。
2)是一个常数,这样在求梯度的时候,2乘以二次方会抵消掉这里的1,自然没有冗余。
常数系数,方便后续计算,同时不会影响结果。
3)y是数据集中每个点的真实Y坐标值,是类标签。
4)h是我们的预测函数(假设函数)。根据每个输入X,根据计算预测Y值,即
根据代价函数,我们可以看到代价函数中有两个变量,所以是一个多变量梯度下降问题。求解代价函数的梯度,即两个变量分别微分。
定义了成本函数和梯度,以及预测的函数形式。我们可以开始写代码了。但在此之前需要说明的是,为了方便代码的编写,我们会将所有公式转换成矩阵的形式。用python计算矩阵非常方便,代码会变得非常简洁。
为了计算矩阵,我们观察预测函数的形式。
我们有两个变量。为了矩阵化这个公式,我们可以给每个点x增加一个维度,这个维度的值固定为1,这个维度会乘以 0。这便于我们统一矩阵计算。
然后我们将代价函数和梯度转化为矩阵向量乘法。
4.2代码首先,我们需要定义数据集和学习率
#!/usr/axdxf/env python 3 #-*-coding:utf-8-*-# @ Time:2019/1/21 21:06 # @ Author:Arrow and Bullet # @ FileName:gradient _ descent . py # @ software:py charm # @ blog:https://blog.csdn.net/qq_41800366from numpyimport * #数据集大小为20个数据点的坐标m=20# x和对应的矩阵X0=ones((m,1)) #生成一个m行1列的向量,即X0,Itreshape(m,1) #生成一个m行1列的向量,即x1。从1到mX=hstack((X0,X1)) #根据列堆栈形成一个数组,实际上就是Y坐标Y=NP。与样本数据# ([3,4,5 1,8,12,11,13,13,16,17,18,17,19,21])相对应的数组。reshape (m,1) #学习率alpha=0.01接下来我们以矩阵向量的形式定义代价函数和代价函数的梯度
#定义代价函数def cost _ function (theta,x,y): diff=dot (x,theta)-y # dot()数组需要像矩阵一样相乘,所以dot()return(1/(2 * m))* dot(Diff . transpose(),Diff)#定义代价函数对应的渐变函数def gradient _ function (theta,x,y):Diff=dot(x,theta)-y return (1/m) * dot (x.pose(),diff)最后就是算法的核心部分,梯度下降迭代计算
#定义代价函数def cost _ function (theta,x,y): diff=dot (x,theta)-y # dot()数组需要像矩阵一样相乘,所以dot()return(1/(2 * m))* dot(diff . transpose(),Diff)#定义代价函数对应的渐变函数def gradient _ function (theta,x,y):Diff=dot(x,theta)-y return (1/m) * dot (x.pose(),Diff)。当梯度小于1e-5时,说明进入了一个相对平滑的状态,类似于一个山谷的状态。
运行代码,计算结果如下:
Javaprint(optimal:,optimal)# result[[0.51583286][0.96992163]]print( cost function:,cost _ function (optimal,x,1.5080.000000000505
#根据数据绘制相应的图像def plot (x,Y,theta):导入matplotlib.py plot为plt ax=plt.plot (111) #这是我修改的ax.scatter(X,Y,s=30,c=red ,Marker= s )PLT . xlabel( X )PLT . ylabel( Y )X=orange的范围(0,21,0.2)# X Y=theta[0]theta[1]* X ax . plot(X,Y).
通过matplotlib画出图像
#!/usr/axdxf/env python 3 #-*-coding:utf-8-*-# @ Time:2019/1/21 21:06 # @ Author:Arrow and Bullet # @ FileName:gradient _ descent . py # @ software:py charm # @ blog:https://blog.csdn.net/qq_41800366from numpyimport * #数据集大小为20个数据点的坐标m=20# x和对应的矩阵X0=ones((m,1)) #生成一个m行1列的向量,即X0,Allreshape(m,1) #生成一个m行1列的向量,即x1,from 1 to mX=hstack((X0,X1)) #根据列栈形成一个数组,实际上是样本数据对应的Y坐标Y=array,4,5,5 8,12,11,13,13,16,17,18,17,19,21])。reshape (m,1) #学习率alpha=0.01#定义代价函数def cost _ function (theta,x,y): diff=dot (x Theta)-Y # dot()数组需要像矩阵一样相乘,所以dot () return (1/(2 * m)) * dot (diff。transpose(),diff) #定义渐变函数def gradient_function(theta,X,Y): diff=dot (x,theta)-y return (1/m) * dot (x.pose(),diff) #渐变下降迭代def gradient _ descent (x,Y,alpha): theta=array ([1,1])。reshape (2,1)gradient=gradient _ function(theta,X,Y)while not all(ABS(gradient)=1e-5):theta=theta-alpha * gradient gradient=gradient _ function(theta,X,Y)return theta optimal=gradient _ descent(X,Y,alpha)print(optimal:,optimal)print(cost function:,cost_function(optimal,X,Y)[0][0])#根据数据绘制相应的图像def plot (x,Y,theta):导入matplotlib.py plot作为PLT ax.最优)5。至此,基本介绍了梯度下降法的基本思想和算法流程,并用python实现了梯度下降算法拟合直线的一个简单案例!
最后,我们回到文章开头提出的情景假设:
这个下坡人实际上代表了反向传播算法,下坡路实际上代表了算法一直在寻找的参数。山上当前点的最陡方向实际上就是该点的代价函数的梯度方向,用来观察场景中最陡方向的工具就是微分。在我们的算法中,下一次观察之前的时间由学习速率定义。
可见情景假设和梯度下降算法很匹配!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。