大家好,我是努力学习AI算法的超级驼鹿,今天要跟大家分享的是梯度下降法。
---------------------------------------------------------------------------------------------------------------------------------
梯度下降法不是一种具体的做回归任务或者分类任务的算法,而是一个用来帮助我们求解其他算法的最优解的通用方法。很多机器学习的方法都用到了梯度下降求解最优值,甚至深度学习也是用它求解的。
无论是回归问题还是分类问题,其实本质都是期望尽快的求出方程的系数,然后才能进行拟合、进一步求解。我们之前的线性回归推导使用的是求导,令导数为0的方法求解的最优值。
然而并不是所有目标函数或者损失函数都是凸函数(像线性回归的损失函数就是标准的凸函数,所以可以用求导的方法求解),大部分函数都是曲里拐弯的,导数为零的点有很多,无法进一步求出最优值。
这时候就可以引出梯度下降的概念,可以帮助我们一步步地找到最优解!
---------------------------------------------------------------------------------------------------------------------------------
梯度是什么呢?梯度其实就是导数,尤其在多元函数中,函数值下降最快的方向就是梯度的方向,也就是说,沿梯度方向,函数值下降最快。梯度下降就是这样一种一点点逼近最优解的方法
那么梯度下降其实就好比是人下山的过程,山底就是我们的最优值,而我们一直沿着梯度的方向行走,就能在最快的时间到达山底。
还是有点抽象?那我们来看看梯度下降在简单的一元二次函数中具体是如何进行的:
第一步:随机取一个初始点开始“下山”(你随机刷新在了山上的某个地方)
第二步:求该点的梯度,也就是找到山路最陡峭的方向(你要确定一会要下山的方向)
第三步:根据更新公式更新参数,也就是“下山”(迈开步子,大胆下山)
第四步:判断走完之后是否在精确度可以容忍的范围内,如果在,就停止,不然则重复第二步(看看是不是已经下完山了,然后再决定是否继续迈步)
其中,随机刷新的地方叫做Random initial value,每走下降一次就相当于我们走了一步,把这一步叫做Learning step。
精确度可以容忍的范围(tolerance)通常是根据工程需要自行定义的(比如常用的3原则和6原则),因为模型算出的最小值只要堪用就好,很多时候真正的最小值是没用办法很精确地求出的,就连计算发射火箭的那些参数,也都只是精确到小数点后多位,而不是真正的精确值。
---------------------------------------------------------------------------------------------------------------------------------
相信各位小伙伴看到这里已经可以大概理解梯度下降的过程了,接下来还是老样子,我们用数学的方法表示一下,显得我们更专业一点~
随机取初始点和求梯度没有什么好说的,让我们先来看看第三步未曾谋面的更新公式吧(由二阶泰勒公式推导):
其中就是我们方程的系数,也是我们要求解的最优值中的自变量。式子中^(n+1)并不是说的n+1次方,而是第n+1次迭代后的可以用第n次迭代后的来计算。是我们一会要讨论的学习率,它表示着我们下山脚步的长短。而gradient就是梯度、导数的英文了。
所以这个式子就是告诉我们,当我们在进行梯度下降的时候,后一次的“落脚点”就等于前一次的“落脚点”减去下山的幅度(学习率与该点梯度的乘积)!
这里我们再来解释一下这个减号,由于梯度是有方向的,就好比二次函数可以从左边下山也可以从右边下山:当你从左边下山时,梯度是负数,所以更新公式就会把往大调整;当你从右边下山时,则恰好相反。无论怎样,减去负梯度都精确地表示“下山”,朝山底前进!
事实上,这个公式只是一个参数的更新公式,更一般地,我们要处理的方程会有多个系数(或者w,它们都等价的表示方程的系数),所以多维的更新公式应该是这样的一组公式:
每进行一次梯队下降,就要计算所有的上述这些公式。由于我们生活在三维世界里的局限性,我在下面展示了一个二元函数梯度下降的示意图,供大家参考理解:
---------------------------------------------------------------------------------------------------------------------------------
现在,我们已经知晓了梯度下降的原理:包括梯度、更新公式,那我们最后还有一个很重要的概念需要说道说道:学习率。
如前文所述,学习率与梯度的乘积相当于是我们下山的步长,其实梯度本身是一个有方向的向量,在这里大家可以理解为:梯度只提供一个方向,而学习率则提供了具体下降的幅度。这是因为梯度认为是一个单位向量,模长为1,任何数乘以1都不会改变,所以学习率才是真正下降的步子的长度。
那学习率怎么设置呢?这其实是一门很考究的学问。
还是拿一元二次函数举例子,让我们看看没设置好学习率会有什么后果:
左一图把学习率设置的很低很小,就像蜗牛一样缓慢的向前蠕动。它的罪状有二:一个是我们之前说过,在多元函数中每次梯度下降其实都是计算一大组公式,所以迭代次数越多,所花费的时间代价就会越大;另一个罪状就是,它有可能困在局部最优解的温床里,让我们看看下图:
它展示的就是具有局部最优解的一元函数,当我们的学习率很小的时候,在相当的时间内,它都不会从局部最优解的泥沼中爬出来,所以一般过小的学习率会找到局部最优解而不是全局最优解(当然有些局部最优解也是堪用的),对于更高维的函数则体现的更为明显,比如二元函数中的鞍点就是个很好的例子,步长长一点就可以很轻松的迈过鞍点,而小步长则会花费大量的时间,甚至可以认为是迈不过去的。
(鞍点示意图)
中间图和右边图学习率则很大,俗话说步子大了就容易扯到蛋,像中间图展示的效果,最终的结果还可以震荡收敛与最优值,而右一图的结果可就难堪大用了,它发生了梯度爆炸,永远也到不了最优值的地方。
所以在实际的工程问题中,学习率的设置至关重要,需要我们一点点的去尝试、优化,才有可能找到堪用的模型参数。
---------------------------------------------------------------------------------------------------------------------------------好了,以上就是所有关于梯度下降的基本知识了,相信各位小伙伴一定有所收获!如果小伙伴们还想继续了解更多梯度下降或者AI算法的知识,请关注超级驼鹿的博客,我会持续和大家分享AI算法的详细推导和知识!