机器学习中为什么需要梯度下降_机器学习理论(四)线性回归中的梯度下降法...

机器学习中为什么需要梯度下降_机器学习理论(四)线性回归中的梯度下降法..._第1张图片

(小小:机器学习的经典算法与应用)

(小小:机器学习理论(一)KNN-k近邻算法)

(小小:机器学习理论(二)简单线性回归)

(小小:机器学习理论(三)多元线性回归)

(小小:机器学习理论(四)线性回归中的梯度下降法)

(小小:机器学习理论(五)主成分分析法)

(小小:机器学习理论(六)多项式回归)

(小小:机器学习理论(七)模型泛化)

(小小:机器学习理论(八)逻辑回归)

(小小:机器学习理论(九)分类算法的评价)

(小小:机器学习理论(十)支持向量机)

(小小:机器学习理论(十一)决策树)

(小小:机器学习理论(十二)集成学习)

(小小:机器学习理论(十三)Kmeans聚类)


一、什么是梯度下降?

二、简单线性回归中使用梯度下降法

三、多元线性回归算法中使用梯度下降法

四、梯度下降算法的向量化

五、梯度下降法

六、关于梯度的调试


前言

梯度下降法,是一种基于搜索的最优化方法,最用是最小化一个损失函数。梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。在求解机器学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一,另一种常用的方法是最小二乘法。在求解损失函数的最小值时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数和模型参数值。

一、什么是梯度下降?

​ 机器学习算法都需要最大化或最小化一个函数,这个函数被称为"目标函数",其中我们一般把最小化的一类函数,称为"损失函数"。它能根据预测结果,衡量出模型预测能力的好坏。在求损失函数最小化的过程中使用梯度下降法。

机器学习中为什么需要梯度下降_机器学习理论(四)线性回归中的梯度下降法..._第2张图片

在直线方程中,导数代表斜率,在曲线方程中,导数代表切线的斜率。导数代表着参数、

单位变化时,损失函数J相应的的变化。通过上面图中的点可以发现,该点的导数为负值,所以随着参数
的增加,损失函数J减小,因此导数从某种意义上还可以代表方向,对应着损失函数J增大的方向。

​ 综上,如果最小化一个函数,我们就需要得到导数再取个负数,并且再乘以一个系数,这个系数通常叫做步长或者叫学习率(Learning rate, Lr)。

的取值影响获得求最优解的速度,取值不合适的话甚至得不到最优解,它是梯度下降的一个超参数。
太小,减慢收敛速度效率,
太大,甚至会导致不收敛。

机器学习中为什么需要梯度下降_机器学习理论(四)线性回归中的梯度下降法..._第3张图片

​ 对于梯度下降算法而言,最不友好的就是并不是所有的函数都有唯一的极值点。很大概率就是局部最优解,并不是真正的全局最优解。这还只是针对二维平面来说,如果对于高维空间更加相对复杂的环境,就更不好说了。

​ 解决方案:多次运行,随机化初始点。初始点也是梯度下降算法的一个超参数。初始化的方法也有很多。

二、简单线性回归中使用梯度下降法

​ 在线性回归算法中目标函数

线性回归算法具有唯一的最优解。下面就来实现一下:

​ 首先,在Jupyter Notebook先生成一组数据。

import 

输出结果:

2.499891109642585
-0.99999998814289

​ 从输出结果来看,theta=2.499891109642585,计算机的浮点数计算精度来说,所以达不到2.5。所以才设置epsilon=1e-8,也是因为这个原因。接下来,看一下梯度下降的过程:

theta 

机器学习中为什么需要梯度下降_机器学习理论(四)线性回归中的梯度下降法..._第4张图片

​ 从上面的图中看出,刚开始下降很快,是因为刚开始的梯度大,所以下降比较快。再看看走了多少步?

len

输出结果:45

​ 下面,把梯度下降封装成一个函数:

def 

测试:

eta 

机器学习中为什么需要梯度下降_机器学习理论(四)线性回归中的梯度下降法..._第5张图片

​ 这是

=0.01的情况,一共有3682个点,有兴趣还可以试试0.001,那这是减小学习率的过程,如果增大学习率试试,eta=0.8,
eta 

机器学习中为什么需要梯度下降_机器学习理论(四)线性回归中的梯度下降法..._第6张图片

​ 可以看出虽然第一步跳到的右边,但是总体还是在朝着减小的地方移动,最终也能寻找到最优解。这说明我们不一定非要沿着一边一点一点的减少,只要在一个合理的范围内就可以。但是如果把

设置为1.1就会报错。但是如果我们修改一下
这个函数,就不会报错,但是会陷入一个死循环,因此我们还要加一个循环次数限制,强行让程序停止。
def 

机器学习中为什么需要梯度下降_机器学习理论(四)线性回归中的梯度下降法..._第7张图片
eta 

输出结果:nan。这是因为在python中无穷大-无穷大=NaN

三、多元线性回归算法中使用梯度下降法

目标:使

尽可能的小

目标:使

尽可能小

由于目标函数的梯度随着特征向量的增加会越来越大,这是不合理的,因此我们给它加个系数

目标:使

尽可能的小

如果想把2消掉,有时取

首先,先随机生成一组数据:

import 

输出结果:array([4.02145786, 3.00706277])

这跟生成数据时候的截距为4,系数为3。所以这样的预测结果也在预料之中。

接下来将这个函数封装到我之前写的多元线性回归的类中。之前的多元线性回归中我们使用的是正规方程解fit_normal,现在我们将梯度下降方法加入这个类中fit_gd。

import 

四、梯度下降算法的向量化

其中,

维度mx(n+1),
维度(n+1)x1,所以
维度mx1

维度1xm,
维度1x(n+1)

但是,往往我们希望得到的导数或者叫梯度的向量是一个列向量,因此我们还需要进行相应的转换。

上式就是我们通过向量化之后得到的梯度的表达式,所以,我们需要将求梯度的函数进行改造一下:之前一直都是使用随机生成的数据,接下来使用波士顿房价进行多元线性回归,并且使用梯度下降法的向量化,

def 

报错:RuntimeWarning: overflow encountered in reduce return ufunc.reduce(obj, axis, dtype, out, **passkwargs),数据溢出。之前我们就说过如果求导得到的梯度需要乘以一个系数,不然会数据溢出,那么在这里为什么又overflow呢?这是因为在我们的数据中肯定有偏向两端的极值存在,比如1000个数据中900个是1000,另外100个是1,就算我们除以1000仍然会可能会导致数据溢出。这也就是之前为什么会谈到数据归一化的问题。

if 

因此,在使用梯度下降法前,最好进行数据归一化。

那使用梯度下降法向量化有什么优势呢?

import 

通过比较,梯度下降法向量化明显快很多。

五、梯度下降法

1、批量梯度下降法

​ 批量梯度下降法,(Batch Gradient Descent),通过下面这个公式可以看出,如果想要求出梯度,每一项都要对所有的样本进行一次计算。这种计算方式一定能精确地求出最优梯度。但如果样本量m比较大的时候,计算梯度那是相当耗时的。因此,基于这个问题就有了随机梯度下降。

2、随机梯度下降

​ 随机梯度下降,(Stochastic Gradient Descent),根据批量梯度下降算法,能不能每次只对一个样本进行求梯度,这样也就不用除以m了。基于这样的想法就出现了随机选择样本求梯度的方法,并且使其向量化,使用下面这个式子作为搜索的方向。这个式子已经不是目标函数的梯度方向了。

​ 既然不确定这个搜索方向是不是梯度方向,那么学习率eta这个参数就更加重要了,如果一直取个不变的学习率,很有可能到达最优解之后还会跳出去。因此,在实际的使用过程中,在随机梯度下降法中需要让学习率逐渐递减。

机器学习中为什么需要梯度下降_机器学习理论(四)线性回归中的梯度下降法..._第8张图片

​ 这种思想其实在基于搜索领域的一种叫做模拟退火的思想。优势在于能够跳出局部最优解,拥有更快的计算速度,机器学习领域很多地方都会用到随机的特点,比如随机森林等。

def 

接下来,具体地测试一下:

%%

输出结果:Wall time: 17.6 ms

theta

输出结果:Wall time: array([4.12778345, 3.16315746])

​ 通过测试代码,可以看出只需要使用1/3的数据量求得的搜索方向也能找到最优解。当然在高维数据中,就不能这么写意地只是用1/3的样本。接下来将随机梯度下降封装一下,并做一些改进:

1.n_iters表示需要随机地将样本过几遍。

2.每次我们都将样本进行随机乱序。

def 

使用真实数据集验证随机梯度下降,

if 

输出结果:当n_iters=5时,0.765475206668553

​ 当n_iters=10时,0.8021056414726753

因此,我们可以调整n_iters使得准确率越来越高。

3、mini-batch Gradient Descent

​ 小批量梯度下降法,mini-batch Gradient Descent,就是将批量梯度下降和随机梯度下降的两种结合,在深度学习的图像领域,会经常使用这种方法,因为相对一张图片来说假如是100*100=10000,因此如果直接使用批量梯度下降显然是不太现实的,所以结合随机梯度下降的思想,每次从样本中随机抽取一个mini-batch进行梯度求解,从而寻找搜索方向,进而找到最优解。

4、scikit-learn中封装实现sgd

在sklearn中还对sgd的实现进行了优化,具体的优化过程可以去github上看源码。

import 

六、关于梯度的调试

​ 有时候遇到复杂的求导函数,很有可能求解梯度并不容易,在这种情况下,推导出公式以后,通过编程实现,但真正运行的时候,程序并不报错,但求得的梯度是错误的。那如何发现这种问题的原因所在呢?

机器学习中为什么需要梯度下降_机器学习理论(四)线性回归中的梯度下降法..._第9张图片

​ 上面这种图的一种思想就是通过在这个点的左边和右边各找一个临近点,连成的直线的斜率近似地作为改点的斜率,也就是我们所说的导数,其实这也就是导数的定义中的思想。并且将其扩展到高维空间也是一样的。

后面每一项都这么求导,最终合在一起作为梯度下降的方向。

很显然,这种导数的求法从数学的意义上解释是很简单的,但是这样做带来的问题就是时间复杂度将会增加很多,因为需要在一个点进行2次求导,因此这种方法一般只做为调试的一种手段。

def 

输出结果:

array([6.4206869 , 2.08303468, 2.56076208, 3.15680035, 4.41844686,
       5.2150793 , 5.80241598, 6.80736408, 7.5672971 , 8.47769298,
       9.31966978])
theta = gradient_descent(dJ_math, X_b, y, init_theta, eta)
theta

输出结果:

array([6.4206869 , 2.08303468, 2.56076208, 3.15680035, 4.41844686,
       5.2150793 , 5.80241598, 6.80736408, 7.5672971 , 8.47769298,
       9.31966978])

我是尾巴

本次推荐:图片在线压缩工具

据说好多人早上看时间不是为了起床,而是看还能睡多久。我也一样!

继续加油~

你可能感兴趣的:(机器学习中为什么需要梯度下降,线性分组码的最小汉明距为6,线性回归梯度下降法python)