梯度下降算法是一种用于求解函数最小值的数值计算方法。求解函数的极值一般有两种方法,第一种是解析法, 即函数的极值可以用公式直接计算出来。如对于1元2次方程,我们可以直接求出这个函数的最大值或者最小值。 但对于更高次的方程或者非线性函数, 大多无法求出解析解,此时需要使用数值方法.

对于一元函数来说, 函数的梯度就是其导数. 假设函数为

\begin{equation} f(x) = 2x^2-4x+3 \end{equation}

则函数的梯度函数,也即导数为

\begin{equation} Grad(x) = 4x-4 \end{equation}

梯度下降算法的基本原理如下:

对于任意一个自变量 \(x\) 的值 \(x_1\), 我们可以计算此时函数的梯度为 \(Grad(x_1)\), 用当前的 \(x\) 的值 \(x_1\) 减去梯度值的一个比例, 得到一个新的自变量 \(x\) 的值 \(x_2 = x_1 - 0.01*Grad(x_1)\). 则函数在这个新的自变量 \(x\) 的值的地方肯定是小于原来的值的地方, 即

\begin{equation} f(x_2) < f(x_1) \end{equation}

其中 \(0.01\) 为步长值.

比如我们取 \(x_1 = 2\), 此时梯度值为 \(4*2-4=4\), 则 \(x_2 = 2 - 0.01*(4) = 1.96\),

\begin{equation} f(x_1) = 2*2^2-4*2+3 = 3\\ f(x_2) = 2*1.96^2-4*1.96+3 = 2.843 \end{equation}

可见 \(f(x_2) < f(x_1)\)

其中

  • \(x_1=2\) 中的 \(2\) 为自变量的初值. 初值可以随机选择, 如果函数是凸的, 不管初值为何,总能找到相同的极值点
  • \(0.01\) 为每次迭代的步长值

重复以上步骤, 选定初值后,根据以上方法不断变化自变量的值, 随着我们每一次的迭代,自变量的值将慢慢向最优值所对应的 \(x\) 值逼近 (对于这个例子, 最优值对应的 \(x = 1\)). 那么只要迭代的次数足够多,我们总会达到这个最优点,由此便求得函数的最小值.

梯度的概念

以上提到对于一元函数, 其梯度就是函数的导数,梯度值为一个数值。梯度概念是对导数的扩展, 当函数有多于一个自变量的时候. 只是梯度此时是一个向量,向量的每一维分别是对于每一个自变量求偏导数。

以一个二元函数为例

\begin{equation} f(x_1, x_2) = (x_1-2)^2 + 3x_2 \end{equation}

函数的梯度函数为

\begin{equation} Grad(x_1) = \frac{\partial f}{\partial x_1} = 2x_1-4\\ Grad(x_2) = \frac{\partial f}{\partial x_2}=3\\ Grad(x_1, x_2) = [Grad(x_1), Grad(x_2)] = [2x_1-4, 3] \end{equation}

以上讲到的关于自变量沿梯度反方向变化时, 函数值将减小的规则同样适用于二元及更高元的函数. 梯度下降算法的原理也一样, 不同点为此时更新自变量时,是向量操作.

函数的等值线

梯度总是垂直于函数的等值线。从等值线中可以更加形象地看出梯度下降的原理. 当自变量沿着梯度的方向变化时, 函数值将增加, 等值线所对应的值会增加. 因此,当我们将自变量沿着梯度的反方向变化时,函数的值将会减小. 由此我们可以求出函数的一个极小值, 通过让自变量不断的向梯度的反方向变化.

步长值

梯度给出了自变量变化的方向, 而步长值指定了每次变化的幅度. 如果步长值选得过大,则可能会导致在一次更新自变量后, 错过极值点,从而造成震荡, 无法求得函数的极值. 因此我们要保证步长值足够小,避免震荡现象的出现.

收敛准则

由于是通过迭代的方式一步一步的改变自变量的值来求函数的极值, 那么怎样判断函数已经达到一个极值了呢? 此时需要有一个收敛准则, 即判断一次迭代后,函数是否达到极值点. 一般使用的收敛准则为:指定一个精确率, 当函数值的变化率小于这个精确率时,我们就认为收敛了,此时函数的极值已经被找到.

在机器学习算法中的应用

对于一个机器学习算法,如果其目标函数可以表示成连续可微的凸函数,则我们可以用梯度下降算法进行求解其最小值或者最大值.

例如在对数几率回归算法中, 可以将目标函数写成一个连续可微的凸函数, 然后用梯度下降算法求函数的最小值, 从而求得模型的参数。