梯度下降算法是最小化代价函数(cost function)最常用的方法
接来下我们对其具体的过程进行一个讲解
问题描述
这里仅以两个参数为例,对于多个参数同理
获取代价函数 J ( θ 0 , θ 1 ) J(\theta_0,\theta_1) J(θ0,θ1)的最小值
主要思路
- 从任意 θ 0 , θ 1 \theta_0,\theta_1 θ0,θ1开始
- 不断的改变 θ 0 , θ 1 \theta_0,\theta_1 θ0,θ1的值从而去减少 J ( θ 0 , θ 1 ) J(\theta_0,\theta_1) J(θ0,θ1)的值,直到最后的到一个最小值
图形化解释
该图中 z z z坐标为取参数为 θ 0 , θ 1 \theta_0,\theta_1 θ0,θ1时代价函数的值,也就是说该图形上每一点的高度就是在当 θ 0 = θ 0 ′ , θ 1 = θ 1 ′ \theta_0=\theta_0',\theta_1=\theta_1' θ0=θ0′,θ1=θ1′时 J J J的取值
我们的思路在图形中呈现便成了:
- 初始时在图上确定一点
- 站在该点处向周围看,往下降最快的方向迈出一步(具体迈多大后面会讲到),然后不断重复该步骤,直到到达最低点
一条可行的路径如下图所示,我们从一个初始点看开始,一步一步向下走,直到走到一个局部最优点,然后停下来
但是对于梯度下降法有一个很神奇的现象,如果我们为 θ 0 , θ 1 \theta_0,\theta_1 θ0,θ1选择不同的初值,那么我们最后得到的最优解会和原来完全不一样,例如在下图中,我们从上一个选中的点稍微右边一点的位置开始,然后重复和上一个一样的步骤,最后我们可以看出会得到与上图中完全不一样的结果,这在梯度下降算法中是一个非常正常的现象。
形式化解释
在看完上面的图形化解释后,相信对于梯度下降算法有一个简单的认识了,无非就是在每一步都选择一个下降最快的方向,然后走出一步,然后不断重复这个过程,直到走到最低点或者训练结束为止。
接下来看一下这个过程怎样用算法实现:
repeat until convergence
{
θ
j
=
θ
j
−
α
∂
J
(
θ
0
,
θ
1
)
∂
θ
j
(
f
o
r
j
=
0
a
n
d
j
=
1
)
}
\begin{aligned} &\text{ repeat\ until\ convergence}\{\\ &\qquad \theta_j = \theta_j - \alpha \frac {\partial J(\theta_0,\theta_1)}{\partial\theta_j}\qquad (for\ j =0\ and\ j=1)\\ &\} \end{aligned}
repeat until convergence{θj=θj−α∂θj∂J(θ0,θ1)(for j=0 and j=1)}
我们来具体分析一下这个算法
θ j \theta_j θj即为我们公式中的每一个代确定的参数,这个公式做的事情就是不断去更新公式中出现的每一个参数,直到收敛(convergence)
其中 α \alpha α叫做学习率,用来控制在梯度下降时我们每一步迈出多大的步子,如果 α \alpha α非常大,那么我们在进行梯度下降时就会下降的非常迅速,我们会迈着大步子下山;相反,下降的速度会比较慢,即我们会迈着小碎步下山。
最后一个即是 ∂ J ( θ 0 , θ 1 ) ∂ θ j \frac {\partial J(\theta_0,\theta_1)}{\partial\theta_j} ∂θj∂J(θ0,θ1)这个偏导数项,这个式子控制参数 θ j \theta_j θj下降的方向,我们从微积分中可以了解到:沿导数方向,函数的值下降的最快,这里也就是利用了这个性质来确保我们走的每一步都可以确保其走的是下降的最快的方向。
在我们经常提到的梯度下降算法中,它的所有参数都是同时更新的,也就是说,我们必须在计算完所有的偏导数后才可以去更新 θ j ( for all j ) \theta_j(\text{for all }j) θj(for all j)的的值,在我们的的例子中(只包含两个参数),可以通过以下算法来实现:
t e m p 0 = θ j − α ∂ J ( θ 0 , θ 1 ) ∂ θ 0 t e m p 1 = θ j − α ∂ J ( θ 0 , θ 1 ) ∂ θ 1 θ 0 = t e m p 1 θ 1 = t e m p 1 temp0=\theta_j - \alpha \frac {\partial J(\theta_0,\theta_1)}{\partial\theta_0}\\ temp1=\theta_j - \alpha \frac {\partial J(\theta_0,\theta_1)}{\partial\theta_1}\\ \theta_0=temp1\\ \theta_1=temp1\\ temp0=θj−α∂θ0∂J(θ0,θ1)temp1=θj−α∂θ1∂J(θ0,θ1)θ0=temp1θ1=temp1
导数项和学习率的解释
接下来让我们再做进一步的简化,去看看导数项和学习率怎样影响代价函数的变化。
先来看一下导数项是怎样影响的。
假设我们的代价函数只有一个参数 θ 1 \theta_1 θ1,即代价函数为 J ( θ 1 ) J(\theta_1) J(θ1),假设它的图像是一个在第一象限的类似抛物线的形状,如下图:
首先我们先在其最低点的右侧取一个点,对于该点来说,代价函数在该点的导数是大于0的,学习率 α \alpha α也是大于0的,因此, θ 1 = θ 1 − positive number \theta_1=\theta_1-\text{ positive number} θ1=θ1− positive number,也就是说 θ 1 \theta_1 θ1在不断减少,即 θ 1 \theta_1 θ1在向使代价函数取值更小的方向移动
再来看另一种情况,我们在最低值的左侧也取一个点,对于该点来说,它的导数值是负数,学习率 α \alpha α是大于零的,因此 θ 1 = θ 1 − negative number = θ 1 = positive number \theta_1=\theta_1-\text{ negative number}=\theta_1=\text{ positive number} θ1=θ1− negative number=θ1= positive number,也就是 θ 1 \theta_1 θ1在不断增大,即 θ 1 \theta_1 θ1在向使得代价函数取值更小的方向移动
接下来来看看学习率是怎样影响的。
同样的,为了简化问题,我们的假设与讨论导数项时候一样。
从上面的讨论中我们已经知道,导数项保证了梯度下降的方向是朝着减少代价函数的方向进行的,而学习率与导数项大小的乘积一起控制每一步走多大。
当学习率比较小的时候,每梯度下降会比较慢,每一步都走的非常非常小
当学习率比较大时,梯度下降会下降的比较快,但是也可能会导致它越过最低点,最终导致代价函数看起来像不收敛一样
假设我们从点1出发,在该点的导数是负数的,因此这一步会向右走,由于学习率比较大,因此这一步就比较大,于是就可能会一步跨过最低点,走到了点2,在点2的导数是正的,因此这一步会往左走,于是到了点3
可以思考一下为什么点1到点2走的步子比点2到点3走的步子小。如果没有思路的话可以结合公式看一下
接下来解释一下为什么在学习率不变的时候,可以确保代价函数一步一步走向收敛。
首先我们从公式来看:
θ
1
=
θ
1
−
α
d
J
(
θ
1
)
d
θ
1
\theta_1 = \theta_1 - \alpha \frac {d J(\theta_1)}{d \theta_1}
θ1=θ1−αdθ1dJ(θ1)
正如我们在前面提到的,影响代价函数每一步的步长的参数有学习率和当前所在点的偏导数,当我们学习率不变的时候,每次所处点的偏导数大小不一致,这样就会导致每一步走的步长不同,同时通过偏导数的符号确定走的方向,于是自然而然就向收敛的方向走出一步。
看一个例子:
在这个图中,我们的初始位置在点1,其导数为正,并且相对比较陡峭(导数绝对值较大),因此会向左迈出一大步到达点2,;在点2会继续根据当前点的导数及其符号判断,于是向左走一步到达点三,因为点2相对于点1没有那么陡峭(导数绝对值较小),所以这一步走的比较小,接下来重复这个过程,直到走到收敛。
接下来我们看看当处于局部最优点时会发生什么现象,当我们处于局部最优点时,导数为0,因此公式中的第二项也就为0,于是更新的公式就变成了 θ 1 = θ 1 \theta_1=\theta_1 θ1=θ1,也就是说并没有做出什么变化,只是停在那个点什么事都没有干,这正是我们想要的性质。