如上文所说,面对高维度、更多参数的情况时,通过画图来寻找最小代价函数值是不现实的,因此本文介绍一种可以将代价函数J最小化的算法——梯度下降(Gradient Descent)。梯度下降是很常用的算法,不仅被用在线性回归上,还被广泛应用于机器学习的众多领域。
一、直观理解梯度下降
以包含两个参数的如下代价函数J(θ0,θ1)为例,首先任选一个参数点作为起始点,然后我们需要一点一点的改变(微分)这两个参数的大小,并且每一次改变都要使代价函数值减小最多,直到到达一个无法再下降的最低点,这就是梯度下降。这就如同下山一样,假设下图是一片公园,你从公园的任意一点开始往下走,想尽快的下山,走每一步时都环顾四周选择能让你下降更多的方向走出一步,这样不断往下走,直到走到一个最低点。
很容易想到,最后获得的代价函数最低点只是局部的最小值,并不一定是全局的最小值,选择的初始点不同,最后获得的最低点可能就不一样。
二、梯度下降的数学原理
上述梯度下降中不断一点一点改变当前参数点(θ0, θ1)的数学上的表示为:
这是一个循环体,循环体中的内容为同时改变一次当前两个参数θ0和 θ1(再强调一下,这两个参数是关于单变量x的预测函数h(x)中的参数,我们就是要找到使得代价函数J(θ0, θ1)最小的θ0和 θ1以确定预测函数h(x))的值,改变方式为当前参数值减去[α x 当前偏导数值],α为学习速率(正数),它控制以多大的幅度来更新参数值,循环的结束条件为函数值收敛,即无限逼近某个常数,最后这个常数值点即为局部最小点。
我们先以最小化只含单个参数的函数J(θ1)为例来理解这其中的数学原理。
1. 用梯度下降来最小化只含单个参数的函数
对于J(θ1),梯度下降过程中改变参数值θ1的方式同样是减去α x 当前导数值,很容易想到局部最低点左边的点的导数为负数,右边的点的导数为正数,因此无论初始点选在局部最低点左边还是右边,每次减法都是一次向最低点的逼近,精髓之处在于,当接近最低点时,导数值会越来越小(局部最低点处的导数为0),于是梯度下降会自动采取越来越小的幅度来下降,不断逼近最低点,因此可以理解到这个式子就是不断向局部最低点逼近的过程,这就是梯度下降算法的数学原理。
需要注意的是,要选取一个合适的α值,如果α值过大,可能会导致参数点一次改变就使得函数值直接越过了最低点,并导致梯度下降过程在最低点两边不断震荡,不能正确的收敛。
2. 用梯度下降来最小化含多个参数的函数
上述原理思想也可推广至多个参数,无非就是从看一个参数的导数变化,变成看多个参数的偏导数变化
现在我们就用梯度下降来解决上一篇文章(单变量线性回归)房价预测的例子中代价函数最小化的问题(即用梯度下降来最小化含多个参数的函数),其中预测函数 h 和代价函数 J 如下:
代入h,则J的偏导数即为:
因此分别对θ0和θ1求偏导可得(再强调一下,这里的x(i)是指第i个样本的x值,是已知的常数):
再代入梯度下降算法,不断循环迭代,最后收敛得到的就是局部最低点。
需要注意的是在实际编写梯度下降算法代码时,要注意循环体中要同时改变θ0和θ1的值,不能先改变θ0,然后再用改变后的θ0带入去算θ1,故需先临时保存计算出的值。
三、关于梯度下降的漫谈
线性回归的代价函数通常不会像图1那样凹凸不平有很多个局部最低点,而是表现为一个凸函数(convex function),只有一个全局的最低点,如下图,因此使用梯度下降来计算其最低点时总能收敛到全局最优解。
上述房价预测中梯度下降的例子每一步下降都遍历了整个训练集的样本,这称为Batch梯度下降。除了Batch梯度下降还有那种下降过程中不全览整个数据集,只考虑部分子集的梯度下降算法。
除了梯度下降,高等线性代数中还有一种计算代价函数最小值的数值解法,不需要梯度下降这种迭代算法。在后面的课程中,我们也会谈到这个方法,它可以在不需要多步梯度下降的情况下,也能解出代价函数的最小值,这是另一种称为正规方程(normal equations)的方法。实际上在数据量较大的情况下,梯度下降法比正规方程要更适用一些。