来源:原始 Jupyter Notebook。内容已转换为网页阅读格式;下载原文件

根据前面介绍的梯度,我们来看几个使用梯度下降法求解极值的例子。对于函数 J(θ)J(\theta),我们首先选取一个初始点 θ0\theta_0,然后沿着梯度方向对初始值进行更新得到 θ1\theta_1

θ1=θ0ηJ(θ)θ \theta_1 = \theta_0 - \eta \frac{\partial J(\theta)}{\partial \theta}

然后再对 θ1\theta_1 进行更新得到 θ2\theta_2,以此类推,直到损失函数的值不再有显著变化,最终得到 θk\theta_k 就是我们要求的参数,它使损失函数达到最小。其中 η\eta 是一个待确定的常数,通常被称为 学习率(learning rate)或步长(step),它是一个超参数。

上面的迭代过程一般写成下面的形式,其中的 :=:= 表示使用右侧的值更新左侧的值:

θ:=θηJ(θ)θ \theta := \theta - \eta \frac{\partial J(\theta)}{\partial \theta}

一元函数的梯度下降

我们首先看一个最简单的一元函数:

J(θ)=θ2 J(\theta) = \theta^2

求一元函数的梯度,也就对其求导:

J(θ)=J(θ)=2θ \nabla J(\theta) = J'(\theta) = 2\theta

θ\theta 一个初始值 θ0=1\theta_0 = 1,并设学习率 η=0.4\eta = 0.4,根据梯度下降的更新公式,我们有:

θ0=1θ1=θ0ηJ(θ0)=10.4(21)=0.2θ2=θ1ηJ(θ1)=0.20.4(20.2)=0.04θ3=0.008θ4=0.0016 \begin{align} \theta_0 &= 1 \\ \theta_1 &= \theta_0 - \eta \nabla J(\theta_0) = 1 - 0.4 * (2*1) = 0.2 \\ \theta_2 &= \theta_1 - \eta \nabla J(\theta_1) = 0.2 - 0.4 * (2*0.2) = 0.04 \\ \theta_3 &= 0.008 \\ \theta_4 &= 0.0016 \\ \end{align}

经过4步,基本上已经到达函数的最低点了。

二元函数的梯度下降

我们再来看一个二元函数:

J(θ)=θ12+θ22 J(\theta) = \theta_1^2 + \theta_2^2

该函数的梯度为:

J(θ)=2θ1,2θ2 \nabla J(\theta) = \langle 2\theta_1, 2\theta_2 \rangle

θ\theta 一个初始值 θ0=1,3\theta^0 = \langle 1,3 \rangle,并设学习率 η=0.1\eta = 0.1,开始迭代更新:

θ0=1,3θ1=θ0ηJ(θ0)=1,30.12,6=0.8,2.4θ2=θ1ηJ(θ1)=0.8,2.40.11.6,4.8=0.64,1.92 \begin{align} \theta^0 &= \langle 1,3 \rangle \\ \theta^1 &= \theta^0 - \eta \nabla J(\theta^0) = \langle 1,3 \rangle - 0.1*\langle 2,6 \rangle = \langle 0.8,2.4 \rangle \\ \theta^2 &= \theta^1 - \eta \nabla J(\theta^1) = \langle 0.8,2.4 \rangle - 0.1*\langle 1.6,4.8 \rangle = \langle 0.64,1.92 \rangle \end{align}

可以写个程序来自动完成迭代过程,可以发现经过若干步的迭代,函数也达到了最低点。

关于学习率

梯度下降算法中的 η\eta 称为 学习率(或者 步长),它是一个超参数,关于它的值,不宜太大,也不宜太小。学习率用于控制每一步走的距离,如果太小,参数更新每次也很小,梯度下降的速度会非常慢,如果太大,参数更新也会很大,可能会直接越过极小值,甚至无法收敛到达最低点。

参考