机器学习(优化算法一)——梯度下降

对于机器学习,经常提及的就是批量梯度下降、随机梯度下降,以及两者结合的小批量梯度下降。在深度学习中,常用的还有梯度下降的一些变种,像Adam、AdaGrad……这里只说最基本的三种。

简要过程

像普通线性回归、Ridge回归,通过求导,也就是最小二乘法就可以求解,但Lasso不可以,Lasso通常采用的是坐标轴下降法。除了最小二乘法,还有另外一种方法,也是最常用的:梯度下降法。
比如有一个函数
y = f ( x ) = x ² y=f(x)=x² y=f(x)=x²
对应的图
机器学习(优化算法一)——梯度下降_第1张图片

我们要求的是
x ∗ = arg min ⁡ x ⁡ y x^∗=\argmin \limits_x⁡ y x=xargminy

这里简单说一下梯度下降基本的原理:
比如先随机找一点 x 0 = 2 x_0=2 x0=2,此时 y 0 = 4 y_0=4 y0=4。而目标点是 (0,0) 这个点;
现在找一点 x 1 x_1 x1 x 1 x_1 x1 只有在 x 0 x_0 x0 的左侧,即 x 1 < x 0 x_1x1<x0,才可能更接近目标点,比如找到的点是 x 1 = − 1.2 x_1=-1.2 x1=1.2,此时 y 1 = 1.44 y_1=1.44 y1=1.44;
接着再找 x 2 x_2 x2 x 2 x_2 x2 应位于 x 1 x_1 x1 的右侧,即 x 2 > x 1 x_2>x_1 x2>x1……
……
最终如上图,越来越接近目标点。也就我们基于递归的思想,每步都离目标更近一些。

对于 x 0 = 2 x_0=2 x0=2 y 0 ′ = 4 > 0 y_0^′=4>0 y0=4>0,我们期望找到 x 1 = x 0 − ∆ 1 x_1=x_0-∆_1 x1=x01
假如现在找到了 x 1 = − 1.2 x_1=-1.2 x1=1.2,此时 y 0 ′ = − 2.4 < 0 y_0^′=-2.4<0 y0=2.4<0,下一步则期望找到 x 2 = x 1 + ∆ 2 x_2=x_1+∆_2 x2=x1+2
我们不可能全部的∆ 都找出来。我们知道导数表示变化率,梯度表示的变化最快的情况,导数同时也是梯度在一维(这里说的是 x x x 的维度)空间的表现形式。我们当然是希望以最快的方式找到目标点,那么可不可以把梯度引入进来?

观察一下上面的内容,
对于 ∆ 1 ∆_1 1,可以令他等于 ∆ ∗ y 0 ′ ∆∗y_0^′ y0,即 x 1 = x 0 − ∆ ∗ y 0 ′ x_1=x_0 − ∆∗y_0^′ x1=x0y0
对于 ∆ 2 ∆_2 2,可以令他等于 ∆ ∗ y 1 ′ ∆∗y_1^′ y1,而 y 1 ′ y_1^′ y1 是负数,所以 x 2 = x 1 − ∆ 2 = x 1 − ∆ ∗ y 1 ′ x_2=x_1−∆_2=x_1−∆∗y_1^′ x2=x12=x1y1
……

综上,可得
x m + 1 = x m − ∆ ∗ y m ′ x_{m+1}=x_m−∆∗y_m^′ xm=xmym
即:
x k + 1 = x k − α f ′ ( x k ) x_{k+1}=x_k−α f^′ {(x_k)} xk=xkαf(xk)

通过上面的迭代一定能找到目标点。

上面说的是一维,如果是多维,比如二维呢?其实是一样的,举个例子:
机器学习(优化算法一)——梯度下降_第2张图片

公式推导

基于之前线性回归的目标函数
J ( θ ) = 1 2 ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J{(\theta)} = \frac{1}{2} \sum_{i=1}^m \left( h_\theta \left(x^{(i)} \right) -y^{(i)} \right)^2 J(θ)=21i=1m(hθ(x(i))y(i))2
初始化θ(随机初始化,可以初始为0),沿着负梯度方向迭代,更新后的θ使J(θ)更小(因为J(θ)是一个凸函数,和y=x²类似。如果不是凸函数呢?可能会找到局部最优,而非全局最优。这种情况可采用Adam算法,深度学习中有用到)
θ = θ − α ∙ ∂ J ( θ ) ∂ θ \theta = \theta - \alpha \bullet \frac{\partial J{(\theta)}}{\partial \theta} θ=θαθJ(θ)

注 α:学习率、步长,大于0,一般取0.001,0.01,0.1,从小到大调参
总的来说就是沿负梯度方向进行迭代更新


机器学习(优化算法一)——梯度下降_第3张图片

公式推导
J ( θ ) = 1 2 ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J{(\theta)} = \frac{1}{2} \sum_{i=1}^m \left( h_\theta \left(x^{(i)} \right) -y^{(i)} \right)^2 J(θ)=21i=1m(hθ(x(i))y(i))2
右式是累加的形式,可以以其中一项为例,即一个样本
∂ ∂ θ j J ( θ ) = ∂ ∂ θ j 1 2 ( h θ ( x ) − y ) 2 = 2 ⋅ 1 2 ( h θ ( x ) − y ) ⋅ ∂ ∂ θ j ( h θ ( x ) − y ) = ( h θ ( x ) − y ) ⋅ ∂ ∂ θ j ( ∑ i = 1 n θ i x i − y ) = ( h θ ( x ) − y ) x j \begin{aligned} \frac{\partial }{\partial \theta_j} J{(\theta)} &= \frac{\partial }{\partial \theta_j} \frac{1}{2} \left(h_\theta(x)-y \right) ^2 \\ &=2 \cdot \frac{1}{2} \left(h_\theta(x)-y \right) \cdot \frac{\partial }{\partial \theta_j} \left(h_\theta(x)-y \right) \\ &= \left(h_\theta(x)-y \right) \cdot \frac{\partial }{\partial \theta_j} \left( \sum_{i=1}^n \theta_i x_i -y \right) \\ &= \left(h_\theta(x)-y \right) x_j \end{aligned} θjJ(θ)=θj21(hθ(x)y)2=221(hθ(x)y)θj(hθ(x)y)=(hθ(x)y)θj(i=1nθixiy)=(hθ(x)y)xj

再来看一下
θ = θ − α ∙ ∂ J ( θ ) ∂ θ \theta = \theta - \alpha \bullet \frac{\partial J{(\theta)}}{\partial \theta} θ=θαθJ(θ)
这是一个向量的减法,具体的计算,是向量的每一维度进行相应的减操作,因此可以通过循环操作,对每一维度进行更新。

3种梯度下降

1)批量梯度下降算法(BGD)

∂ J ( θ ) ∂ θ j = ( h θ ( x ) − y ) x j \frac{\partial J{(\theta)}}{\partial \theta_j} = \left(h_\theta(x)-y \right) x_j θjJ(θ)=(hθ(x)y)xj
∂ J ( θ ) ∂ θ j = ∑ i = 1 m ∂ J ( θ ) ∂ θ j = ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \frac{\partial J{(\theta)}}{\partial \theta_j} = \sum_{i=1}^m \frac{\partial J{(\theta)}}{\partial \theta_j} = \sum_{i=1}^m \left(h_\theta(x^{(i)})-y^{(i)} \right) x_j^{(i)} θjJ(θ)=i=1mθjJ(θ)=i=1m(hθ(x(i))y(i))xj(i)

第一行表示一条数据的情况,如果对于m条数据,就是第二行的累加情况。

批量梯度下降,也就是对 θ j θ_j θj 进行更新时,一次对m条数据进行操作:m条数据导数累加的和,然后再做更新

θ j = θ j + α ∑ i = 1 m ( y ( i ) − h θ ( x ( i ) ) ) x j ( i ) \theta_j = \theta_j + \alpha \sum_{i=1}^m \left(y^{(i)} - h_\theta(x^{(i)}) \right) x_j^{(i)} θj=θj+αi=1m(y(i)hθ(x(i)))xj(i)

2)随机梯度下降算法(SGD)

既然能一次性更新所有的样本,那能不能一次只更新一个样本?这就是随机梯度下降:也就是有一条样本就更新一次 θ j θ_j θj
∂ J ( θ ) ∂ θ j = ( h θ ( x ) − y ) x j \frac{\partial J{(\theta)}}{\partial \theta_j} = \left(h_\theta(x)-y \right) x_j θjJ(θ)=(hθ(x)y)xj

机器学习(优化算法一)——梯度下降_第4张图片

总体是趋于最优值。但由于是一条样本一更新,当有异常样本时,可能会出现远离的情况。所以总体往往有波动。

比较

机器学习(优化算法一)——梯度下降_第5张图片
机器学习(优化算法一)——梯度下降_第6张图片

  • SGD速度比BGD快(迭代次数少)
  • SGD在某些情况下(全局存在多个相对最优解/J(θ)不是一个二次),SGD有可能跳出某些小的局部最优解,所以不会比BGD坏
  • BGD一定能够得到一个局部最优解(在线性回归模型中一定是得到一个全局最优解),SGD由于随机性的存在可能导致最终结果比BGD的差

注意:优先选择SGD

3)小批量梯度下降法(MBGD)

如果即需要保证算法的训练过程比较快,又需要保证最终参数训练的准确率,而这正是小批量梯度下降法(Mini-batch Gradient Descent,简称MBGD)的初衷。MBGD中不是每拿一个样本就更新一次梯度,而且拿b个样本(b一般为10)的平均梯度作为更新方向。
机器学习(优化算法一)——梯度下降_第7张图片

注意点

由于梯度下降法中负梯度方向作为变量的变化方向,所以有可能导致最终求解的值是局部最优解,所以在使用梯度下降的时候,一般需要进行一些调优策略。

学习率的选择:学习率过大,表示每次迭代更新的时候变化比较大,有可能会跳过最优解;学习率过小,表示每次迭代更新的时候变化比较小,就会导致迭代速度过慢,很长时间都不能结束;一般取0.001,0.01,0.1,从小到大调参
机器学习(优化算法一)——梯度下降_第8张图片
算法初始参数值的选择:初始值不同,最终获得的最小值也有可能不同,因为梯度下降法求解的是局部最优解,所以一般情况下,选择多次不同初始值运行算法,并最终返回损失函数最小情况下的结果值;sklearn无此功能

标准化:由于样本不同特征的取值范围不同,可能会导致在各个不同参数上迭代速度不同,为了减少特征取值的影响,可以将特征进行标准化操作。

BGD、SGD、MBGD的区别:

  • 当样本量为m的时候,每次迭代BGD算法中对于参数值更新一次,SGD算法中对于参数值更新m次,MBGD算法中对于参数值更新m/n次,相对来讲SGD算法的更新速度最快;

  • SGD算法中对于每个样本都需要更新参数值,当样本值不太正常的时候,就有可能会导致本次的参数更新会产生相反的影响,也就是说SGD算法的结果并不是完全收敛的,而是在收敛结果处波动的;

  • SGD算法是每个样本都更新一次参数值,所以SGD算法特别适合样本数据量大的情况以及在线机器学习(Online ML)。

补充

还经常听到牛顿法(Newton method)和拟牛顿法(quasi Newton method),其实也特别简单,这里只简单介绍一下。
上面说梯度下降法时,得到了式子:
x k + 1 = x k − α f ′ ( x k ) x_{k+1}=x_k−α f^′ {(x_k)} xk=xkαf(xk)

像牛顿法,其实就是在梯度下降法的基础上做了些变动(α不是超参,而是这一点二阶导的倒数)。
x k + 1 = x k − f ′ ( x k ) f ′ ′ ( x k ) x_{k+1}=x_k−\frac{f^′ {(x_k)}}{f^{''} {(x_k)}} xk=xkf(xk)f(xk)

二阶导就是一阶导的变化率,类似于物理学中的加速度与速度。在用梯度下降迭代优化的过程中,当变动越剧烈的时候,此时,二阶导的值就会越大,而取倒数后,则就会越小,从而能减缓剧烈程度;相反,当迭代优化时,变动比较缓慢,二阶导的倒数就会比较大,此时可以加快迭代。

一般认为牛顿法可以利用到曲线本身的信息,比梯度下降法更容易收敛(迭代更少次数),如下图是一个最小化一个目标方程的例子,红色曲线是利用牛顿法迭代求解,绿色曲线是利用梯度下降法求解。
机器学习(优化算法一)——梯度下降_第9张图片
在上面讨论的是低维情况,高维情况的牛顿迭代公式是:
X k + 1 = X k − ( H f ( X k ) ) − 1 ∇ f ( X k ) X_{k+1}=X_k - \left(Hf(X_k) \right) ^{-1} \nabla f(X_k) Xk+1=Xk(Hf(Xk))1f(Xk)
其中 H H H 就是hessian矩阵(海塞矩阵),他的定义为:
H ( f ) = [ ∂ 2 f ∂ x 1 2 ∂ 2 f ∂ x 1 ∂ x 2 ⋯ ∂ 2 f ∂ x 1 ∂ x n ∂ 2 f ∂ x 2 ∂ x 1 ∂ 2 f ∂ x 2 2 ⋯ ∂ 2 f ∂ x 2 ∂ x n ⋮ ⋮ ⋱ ⋮ ∂ 2 f ∂ x n ∂ x 1 ∂ 2 f ∂ x n ∂ x 2 ⋯ ∂ 2 f ∂ x n 2 ] H(f)= \begin{bmatrix} \frac {\partial^2f}{\partial x_1^2} & \frac {\partial^2f}{\partial x_1 \partial x_2} & \cdots & \frac {\partial^2f}{\partial x_1 \partial x_n} \\ \frac {\partial^2f}{\partial x_2 \partial x_1} & \frac {\partial^2f}{ \partial x_2^2} & \cdots & \frac {\partial^2f}{\partial x_2 \partial x_n} \\ \vdots & \vdots & \ddots & \vdots \\ \frac {\partial^2f}{\partial x_n \partial x_1} & \frac {\partial^2f}{\partial x_n \partial x_2} & \cdots & \frac {\partial^2f}{\partial x_n^2} \\ \end{bmatrix} H(f)=x122fx2x12fxnx12fx1x22fx222fxnx22fx1xn2fx2xn2fxn22f
高维情况依然可以用牛顿迭代求解,牛顿法虽然收敛速度快,但是需要计算海塞矩阵的逆矩阵 H − 1 H^{-1} H1,计算量会比较大,而且有时目标函数的海塞矩阵无法保持正定(也就是无法求得逆矩阵),从而使得牛顿法失效。为了克服这两个问题,人们提出了拟牛顿法。这个方法的基本思想是:不用二阶偏导数而构造出可以近似海塞矩阵(或海塞矩阵的逆)的正定对称阵。不同的构造方法就产生了不同的拟牛顿法。典型的有DFP算法、BFGS算法、L-BFGS算法等。这里就不再介绍了,感兴趣的可以自己去查相关资料。

你可能感兴趣的:(机器学习)