XDRush

梯度下降法及其理解

1 背景说明

在求解机器学习和深度学习算法的模型参数,即无约束优化问题时,梯度下降(Gradient Descent)是最常采用的方法之一,其他的常用的方法是最小二乘法、牛顿法和拟牛顿法。这里就对梯度下降法做一个完整的总结。

2 梯度的概念

2.1 什么是梯度

在微积分里面,对多元函数的参数求$\Phi$偏导数,把求得的各个参数的偏导数以向量的形式写出来,就是梯度。比如函数$f(x,y)$, 分别对$(x,y)$求偏导数,求得的梯度向量就是$(∂f/∂x, ∂f/∂y)^T$,简称$gradf(x,y)$或者$▽f(x,y)$。对于在点$(x_0,y_0)$的具体梯度向量就是$(∂f/∂x_0,∂f/∂y_0)^T$或者$▽f(x_0,y_0)$,如果是3个参数的向量梯度,就是$(∂f/∂x, ∂f/∂y,∂f/∂z)^T$,以此类推。

那么这个梯度向量求出来有什么意义呢?他在意义从几何意义上讲,就是函数变化增加最快的地方。具体来说,对于函数$f(x,y)$,在点$(x_0,y_0)$,沿着梯度向量的方向就是$(∂f/∂x_0,∂f/∂y_0)^T$的方向是$f(x,y)$增加最快的地方。或者说,沿着梯度向量的方向,更加容易找到函数的最大值。反过来说,沿着梯度向量相反的方向,也就是$-(∂f/∂x_0,∂f/∂y_0)^T$的方向,梯度减少最快,也就是更加容易找到函数的最小值。

2.2 梯度上升和梯度下降

在机器学习算法中,在最小化损失函数时,可以通过梯度下降法来一步步的迭代求解,得到最小化的损失函数和模型参数值。反过来,如果我们需要求解损失函数的最大值,这时就需要用梯度上升法来迭代了。

梯度下降法和梯度上升法是可以互相转化的。比如我们需要求解损失函数$f(θ)$的最小值,这时我们需要用梯度下降法来迭代求解。但是实际上,我们可以反过来求解损失函数 $-f(θ)$的最大值,这时梯度上升法就派上用场了。

3 梯度下降法详细原理

3.1 梯度下降法直观理解

首先来看看梯度下降的一个直观的解释。比如我们在一座大山上的某处位置,由于我们不知道怎么下山,于是决定走一步算一步,也就是在每走到一个位置的时候,求解当前位置的梯度,沿着梯度的负方向,也就是当前最陡峭的位置向下走一步,然后继续求解当前位置梯度,向这一步所在位置沿着最陡峭最易下山的位置走一步。这样一步步的走下去,一直走到觉得我们已经到了山脚。当然这样走下去,有可能我们不能走到山脚,而是到了某一个局部的山峰低处。
梯度下降法示意图

从上面的解释可以看出,梯度下降不一定能够找到全局的最优解,有可能是一个局部最优解。当然,如果损失函数是凸函数,梯度下降法得到的解就一定是全局最优解。

3.2 梯度下降法相关概念

在详细了解梯度下降的算法之前,我们先看看相关的一些概念。

  • 步长(Learning rate):步长决定了在梯度下降迭代的过程中,每一步沿梯度负方向前进的长度。用上面下山的例子,步长就是在当前这一步所在位置沿着最陡峭最易下山的位置走的那一步的长度。
  • 特征(feature):指的是样本中输入部分,比如样本$(x_0,y_0)$,$(x_1,y_1)$,即样本特征为$x$,样本输出为$y$。
  • 假设函数(hypothesis function):在监督学习中,为了拟合输入样本,而使用的假设函数,记为$h\theta(x)$。比如对于样本$(x_i,y_i)$,$(i=1,2,…n)$,可以采用拟合函数如下: $h\theta(x) = \theta_0 + \theta_1*x$。
  • 损失函数(loss function):为了评估模型拟合的好坏,通常用损失函数来度量拟合的程度。损失函数极小化,意味着拟合程度最好,对应的模型参数即为最优参数。在线性回归中,损失函数通常为样本输出和假设函数的差取平方。比如对于样本$(xi,y_i)(i=1,2,…,m)$,采用线性回归,损失函数为:
    $J(θ_0,θ_1)=\sum
    {i=1}^{m}(hθ(x_i)−y_i)^2$
    其中$x_i$表示样本特征$x$的第$i$个元素,$y_i$表示样本输出$y$的第$i$个元素,$h
    θ(x_i)$为假设函数。

3.3 梯度下降法代数描述

(1)先决条件:确定优化模型的假设函数和损失函数
比如对于线性回归,假设函数表示为$hθ(x_1,x_2,…,x_n)=θ_0+θ_1x_1+…+θ_nx_n$, 其中$θ_i(i = 0,1,2…,n)$为模型参数,$x_i(i = 0,1,2…,n)$为每个样本的$n$维特征值。这个表示可以简化,我们增加一个特征$x_0=1$,这样$hθ(x1,x_2,…,x_n)=θ_0x_0+θ_1x_1+…+θ_nx_n=\sum{i=0}^nθ_ix_i$。

同样是线性回归,对应于上面的假设函数,损失函数为:
$J(θ0,θ_1,…,θ_n)=\frac{1}{2m}\sum{i=0}^{m}(h_θ(x_0,x_1,…,x_n)−y_i)^2$

(2)参数初始化
主要是初始化$θ_0,θ_1,…,θ_n$,算法终止距离$\epsilon$以及步长$\alpha$。在没有任何先验知识的时候,我喜欢将所有的$θ$初始化为0, 将步长初始化为1。在调优的时候再优化。

(3)算法过程
第一步:确定当前位置的损失函数的梯度,对于$θ_i$,其梯度表达式如下:
$\frac{\partial}{\partial{θ_i}}J(θ_0,θ_1,…,θ_n)$

第二步:用步长乘以损失函数的梯度,得到当前位置下降的距离,即$\alpha\frac{\partial}{\partial{θ_i}}J(θ_0,θ_1,…,θ_n)$,对应于前面登山例子中的某一步。

第三步:确定是否所有的$θ_i$,梯度下降的距离都小于$\epsilon$,如果小于$\epsilon$则算法终止,当前所有的$θ_i(i=0,1,…,n)$即为最终模型的结果。否则进入下一步。

第四步:更新所有的$θ$,对于$θ_i$,其更新表达式如下。更新完毕后继续转入第一步。
$θ_i=θ_i-\alpha\frac{\partial}{\partial{θ_i}}J(θ_0,θ_1,…,θ_n)$

下面用线性回归的例子来具体描述梯度下降。假设我们的样本是$(x1^{(0)},x_2^{(0)},…,x_n^{(0)},y_0),(x_1^{(1)},x_2^{(1)},…,x_n^{(1)},y_1),…,(x_1^{(m)},x_2^{(m)},…,x_n^{(m)},y_m)$,
损失函数为:
$J(θ_0,θ_1,…,θ_n)=\frac{1}{2m}\sum
{i=0}^{m}(h_θ(x_0^{(i)},x_1^{(i)},…,x_n^{(i)})-y_i)^2$

则在上述算法第一步中对$θi$求偏导的计算公式为:
$\frac{\partial}{\partial{θ_i}}J(θ_0,θ_1,…,θ_n)=\frac{1}{m}\sum
{j=0}^{m}(h_θ(x_0^{(j)},x_1^{(j)},…,x_n^{(j)})-y_j)x_i^{(j)}$
由于样本中没有$x_0$,为简化描述令上式中所有的$x_0^{(j)}$都为1。

则在上述算法第四步中对$θi$的更新表达式如下:
$θ_i=θ_i-\alpha\frac{1}{m}\sum
{j=0}^{m}(h_θ(x_0^{(j)},x_1^{(j)},…,x_n^{(j)})-y_j)x_i^{(j)}$

从这个例子可以看出当前点的梯度方向是由所有的样本共同决定的,同时也可以看出,当训练样本很大时,梯度下降算法可能会难以使用,梯度下降每次迭代的计算开销随着样本量线性增长,后文针对这个问题提出了其他的一些梯度更新方法。由于步长也为常数,他们的乘积也为常数,所以这里$\alpha\frac{1}{m}$可以用一个常数表示。

3.4 梯度下降法的算法调优

在使用梯度下降时,需要进行调优。哪些地方需要调优呢?

  • 算法的步长选择:在前面的算法描述中,我提到取步长为1,但是实际上取值取决于数据样本,可以多取一些值,从大到小,分别运行算法,看看迭代效果,如果损失函数在变小,说明取值有效。步长太大,会导致迭代过快,甚至有可能错过最优解。步长太小,迭代速度太慢,很长时间算法都不能结束。所以算法的步长需要多次运行后才能得到一个较为优的值。
  • 算法参数的初始值选择:初始值不同,获得的最小值也有可能不同,因此梯度下降求得的只是局部最小值;当然如果损失函数是凸函数则一定是最优解。由于有局部最优解的风险,需要多次用不同初始值运行算法,关键损失函数的最小值,选择损失函数最小化的初值。
  • 归一化:由于样本不同特征的取值范围不一样,可能导致迭代很慢,为了减少特征取值的影响,可以对特征数据归一化,也就是对于每个特征$x$,求出它的期望$E[x]$、标准差$std(x)$,然后转化为:$\frac{x-E[x]}{std(x)}$,这样特征的新期望为0,新方差为1,迭代次数可以大大加快。

以上就是梯度下降算法的详细过程,下面将讲解几种梯度下降法的变种,他们的主要区别就是对样本的处理方法不一样。

4 几种常见的梯度下降法(BGD,SGD,MBGD)

4.1 批量梯度下降法(Batch Gradient Descent)

批量梯度下降法,是梯度下降法最常用的形式,具体做法也就是在更新参数时使用所有的样本来进行更新,这个方法对应于前面第三章中的线性回归的梯度下降算法:$θi=θ_i-\alpha\frac{1}{m}\sum{j=0}^{m}(h_θ(x_0^{(j)},x_1^{(j)},…,x_n^{(j)})-y_j)x_i^{(j)}$

从上面公式可以注意到,它得到的是一个全局最优解,但是每迭代一步,都要用到训练集所有的数据,如果样本数目$m$很大,那么可想而知这种方法的迭代速度将会很慢!所以,这就引入了另外一种方法,随机梯度下降。
BGD优点:全局最优解;易于并行实现;从迭代的次数上来看,BGD迭代的次数相对较少;
BGD缺点:当样本数目很多时,训练过程会很慢。

4.2 随机梯度下降法(Stochastic Gradient Descent)

随机梯度下降法,其实和批量梯度下降法原理类似,区别在与求梯度时没有用所有的$m$个样本的数据,而是仅仅随机均匀地选取一个样本$j$来求梯度。对应的更新公式是:$θi=θ_i-\alpha(hθ(x_0^{(j)},x_1^{(j)},…,x_n^{(j)})-y_j)x_i^{(j)}$

随机梯度下降法为什么能够替代梯度下降法呢?这是因为随机梯度是对梯度的无偏估计。每个样本$j$产生的loss为:
$Jj(θ_0,θ_1,…,θ_n)=\frac{1}{2}(hθ(x0^{(j)},x_1^{(j)},…,x_n^{(j)})-y_j)^2$
所有样本的loss为:
$J(θ_0,θ_1,…,θ_n)=\frac{1}{2m}\sum
{i=0}^{m}(h_θ(x_0^{(i)},x_1^{(i)},…,x_n^{(i)})-y_i)^2$

因为是随机均匀的对样本进行采样,因此随机梯度是对梯度的无偏估计。

随机梯度下降法,和4.1的批量梯度下降法是两个极端,一个采用所有数据来梯度下降,一个用一个样本来梯度下降。自然各自的优缺点都非常突出:
(1)对于训练速度来说,随机梯度下降法由于每次仅仅采用一个样本来迭代,训练速度很快,而批量梯度下降法在样本量很大的时候,训练速度不能让人满意。
(2)对于准确度来说,随机梯度下降法用于仅仅用一个样本决定梯度方向,导致解很有可能不是最优。
(3)对于收敛速度来说,由于随机梯度下降法一次迭代一个样本,导致迭代方向变化很大,不能很快的收敛到局部最优解。

那么,有没有一个中庸的办法能够结合两种方法的优点呢?有!这就是4.3的小批量梯度下降法。

4.3 小批量梯度下降法(Mini-batch Gradient Descent)

小批量梯度下降法是批量梯度下降法和随机梯度下降法的折衷,也就是对于$m$个样本,我们随机均匀的采用$n$个样本来迭代,$1<n<m$。一般可以取$n=10$,当然根据样本的数据,可以调整这个$n$的值。对应的更新公式是:

实际上,小批量的梯度同样也是梯度的无偏估计。当批量大小等于样本数时,该算法就是梯度下降,当批量大小为1时,该算法就是随机梯度下降。

和学习率一样,批量大小也是一个超参数。当批量较小时,虽然每次迭代的计算开销较小,但计算机并行处理批量中各个样本的能力往往只得到较少利用。因此,当训练数据集的样本较少时,我们可以使用梯度下降;当样本较多时,我们可以使用小批量梯度下降并根据计算资源选择合适的批量大小。