凌云时刻 · 技术
导读:这篇笔记主要介绍梯度下降法,梯度下降不是机器学习专属的算法,它是一种基于搜索的最优化方法,也就是通过不断的搜索然后找到损失函数的最小值。像上篇笔记中使用正规方程解实现多元线性回归,基于这个模型我们可以推导出的数学解,但是很多模型是推导不出数学解的,所以就需要梯度下降法来搜索出最优解。
作者 | 计缘
来源 |凌云时刻(微信号:linuxpk)
梯度下降法概念
我们来看看在二维坐标里的一个曲线方程:
纵坐标表示损失函数L的值,横坐标表示系数。每一个
的值都会对应一个损失函数L的值,我们希望损失函数收敛,既找到一个的值,使损失函数L的值最小。
在曲线上定义一点A,对应一个值,一个损失函数L的值,要判断点A是否是损失函数L的最小值,既求该点的导数,在第一篇笔记中我解释过,点A的导数就是直线M的斜率,直线M是点A的切线,所以导数描述了一个函数在某一点附近的变化率,并且导数大于零时,函数在区间内单调递增,导数小于零时函数在区间内单调递减。所以表示损失函数L增大的变化率,表示损失函数L减小的变化率。
再在曲线上定义一点B,在点A的下方,B点的值就是A点的值加上让损失函数L递减的变化率,称为步长,既B点在变化率的基础下移动了多少距离,在机器学习中这个值也称为学习率。
同理还可以再求得点C,然后看是否是损失函数的L的最小值。所以梯度下降法就是基于损失函数在某一点的变化率,以及寻找下一个点的步长,不停的找到下一个点,然后判断该点处的损失函数值是否为最小值的过程。就称为梯度。
在第一篇笔记中将极值的时候提到过,当曲线或者曲面很复杂时,会有多个驻点,既局部极值,所以如果运行一次梯度下降法寻找损失函数极值的话很有可能找到的只是局部极小值点。所以在实际运用中我们需要多次运行算法,随机化初始点,然后进行比较找到真正的全局极小值点,所以初始点的位置是梯度下降法的一个超参数。
不过在线性回归的场景中,我们的损失函数是有唯一极小值的,所以暂时不需要多次执行算法搜寻全局极值。
梯度下降的步长
步长在梯度下降法中非常重要,这里着重说一下。
在机器学习中称为学习率(Learning rate)。
的取值影响获得最优解的速度。想象一下如果过小,那么寻找的点就会变得很多,收敛速度下降。如果过大可能会不断错过最优解,同样影响收敛速度。
取值不合适时甚至得不到最优解。比如值过大会造成损失函数值越来越大。
也是梯度下降法的一个超参数。可能会有搜索最佳的过程。
实现梯度下降法
我们在Jupyter Notebook中来看看如何实现梯度下降法:
下面我们来定义变化率和损失函数:
然后来看看实现梯度下降的过程:
得到的值为2.5,损失函数的极小值为-1,代入方程可验证我们的求解是正确的。
Theta的变化
我们将每次的值记下来,然后描绘出来,看看是如何变化的:
从上面的示例代码中看到,一共经历了45次的查找得到了让函数达到最小值的。并且看到一开始因为曲线比较陡,所以梯度比较大,两个点之间的间隔比较大,到曲线底部的时候因为曲线开始平缓,梯度逐渐变小,每个点之间的间隔就越来越小。
我们将步长调大一些,看看的查找轨迹是怎样的:
从图中可以看到,第一次查找的时候就越过了极值点,找到了曲线另一侧的点,不过好在损失函数的值还是递减的状态所以最终还是找到了极值点。
我们将步长再调大点,看会发生什么情况:
从图中看到每次找到的会使损失函数越来越大,根本无法找到极小值。所以步长的确定非常重要,不过一般情况下,我们将步长设为0.01是比较保险的做法,但是如果想使算法在各方面达到最优,那么还是需要先对步长这个超参数进行严谨的确定。
求导概念复习
在看如何使用梯度下降解决线性回归问题前,我们先来复习一下求导的知识。
代数函数的求导
一般求导定则
线性定则
乘法定则
除法定则
倒数定则
复合函数求导法则
线性回归中使用梯度下降法
上一节通过一维场景解释了梯度下降法,这一节在高维的场景中看看如何使用梯度下降法解决线性回归的问题。
在线性回归的问题中注意一下三个方面:
首先损失函数是明确的,前面用正规方程解实现的时候已经推导过。
其次系数不是一维的了,而是多维的,即是一个向量。
最后损失函数不是对一维系数求全导,而是对求导数,记为,即梯度。
在上一篇笔记中我们推导过的函数:
所以代入损失函数后就得:
在讲正规方程解时我们推导过,上面的函数可以转换为:
我们的目标就是让上面的函数尽可能的小,根据之前讲过的概念,我们知道损失函数的梯度就是对向量中的每个求导,并且在上篇笔记中我们知道向量是一个列向量,根据复合函数求导定则,所以损失函数L的梯度为:
将2提到外面,然后将后面的负号移进前面的括号里得:
可以发现上面公式中每个元素都经过了m求和,这样带来的问题就是梯度受样本数据数量的影响极大,不过在线性回归的评测标准一节中讲到的均方误差MSE就是为了解决这个问题的,所以我们将损失函数直接转变为MSE:
那么对MSE求梯度的结果自然也是损失函数求梯度后乘以1/m:
实现线性回归中的梯度下降法
我们先在Jupyter Notebook中来实现,然后再在PyCharm中进行封装:
可以看到我们得到的结果,解决为4,斜率为3,和我们拟定的线性方程是一致的。
下面我们在PyCharm中封装梯度下降法。在LinearRegression
类中再增加一个fit_gd
方法,和fit_normal
方法区分开,表明是用梯度下降法进行训练:
END
往期精彩文章回顾
机器学习笔记(九):多元线性回归
机器学习笔记(八):线性回归算法的评测标准
机器学习笔记(七):线性回归
机器学习笔记(六):数据归一化
机器学习笔记(五):超参数
机器学习笔记(四):kNN算法
机器学习笔记(三):NumPy、Matplotlib、kNN算法
机器学习笔记(二):矩阵、环境搭建、NumPy
机器学习笔记(一):机器的学习定义、导数和最小二乘
Kafka从上手到实践 - 实践真知:搭建Kafka相关的UI工具
长按扫描二维码关注凌云时刻
每日收获前沿技术与科技洞见