揭开机器学习优化的神秘面纱

揭开机器学习优化的神秘面纱

机器学习的梯度下降

优化是机器学习算法中最重要的组成部分。它从定义某种损失函数/成本函数开始,最后使用一个或另一个优化例程最小化它。优化算法的选择可以在小时或天内获得良好的精度。机器学习优化的应用是无限的,是业界和学术界广泛研究的课题。在本文中,我们将介绍在深度学习领域中使用的几种机器学习优化算法。

随机梯度下降

随机梯度下降(SGD)是用于查找最小化给定成本函数的参数的最简单的机器学习优化算法。显然,为了使梯度下降收敛到最佳最小值,成本函数应该是凸的。为了演示目的,想象一下成本函数的图形表示。

揭开机器学习优化的神秘面纱

我们首先定义参数的一些随机初始值。机器学习优化算法的目标是找到对应于成本函数的最小值的参数值。具体地,梯度下降开始于计算每个参数wrt成本函数的梯度(导数)。这些渐变为我们提供了我们需要对每个参数进行的数值调整,以便最小化成本函数。这个过程一直持续到我们达到局部/全局最小值(成本函数是周围值的最小值)。在数学上,

for i in range(iterations_count):

param_gradients = evaluate_gradients(loss_function,

data,

params)

params -= learning_rate * param_gradients

揭开机器学习优化的神秘面纱

学习率对梯度下降的影响

学习率定义了每次迭代中应该更改的参数量。换句话说,它控制我们应该收敛到最低的速度或速度。一方面,小学习率可以使迭代收敛,大学习率可能超过最小值,如上图所示。

尽管在实践中很容易应用,但它在深度神经网络中有很多缺点,因为这些网络需要适应大量参数。为了说明梯度下降的问题,我们假设我们只有两个参数的成本函数。假设成本函数对参数之一(例如垂直方向)的变化非常敏感,而对其他参数即水平方向的变化非常小(这意味着成本函数具有高条件数)。

揭开机器学习优化的神秘面纱

Zig zag motion with gradient descent

如果我们对这个函数进行随机梯度下降,我们会得到一种锯齿状的行为。从本质上讲,SGD在向低敏感方向发展缓慢,因此没有向最小方向发展。在实践中,深神经网络可能有数百万个参数,因此有数百万个方向来适应梯度调整,从而使问题复杂化。

SGD的另一个问题是局部最小或鞍点问题。鞍点是在所有方向上梯度为零的点。因此,我们的SGD将仅停留在那里。另一方面,局部最小值是最小值的点,但不是最小值。由于梯度在局部最小值为零,当全局最小值在其他位置时,我们的梯度下降会将其报告为最小值。

为了解决vanilla 梯度下降的问题,近年来开发了几种先进的机器学习优化算法。我们将逐一浏览它们。

有momentum的随机梯度下降

揭开机器学习优化的神秘面纱

我们首先必须掌握指数加权平均的概念。假设我们得到了某一特定城市一年365天每天气温的数据。把它画出来,我们在左上角得到一个图。

现在,如果我们希望计算全年的当地平均温度,我们将按如下方式进行。

NOTE :-

alpha = 0.9 is randomly chosen weight.

t(i) is temperature at ith day.

v(i) is average temperature for ith day averaged over 1/(1 - alpha) days.

v(0) = 0

v(1) = 0.9 * v(0) + 0.1 * t(1)

v(2) = 0.9 * v(1) + 0.1 * t(2)

...

v(i) = alpha * v(i-1) + (1 - alpha) * t(i)

在每一天,我们计算前一天温度和当前日温度的加权平均值。上面计算的图表显示在右上角。该图是过去10天的平均温度(α= 0.9)。左下角(绿线)显示过去50天的平均数据(alpha = 0.98)。

这里需要注意的一个重要问题是,随着我们在更多天数内进行平均,这个图对温度变化的敏感度会降低。相比之下,如果我们平均在更少的天数内,这个图会对温度的变化更敏感,因此会有扭曲的行为。

延迟的增加是由于我们给前一天的温度提供了比当前温度更高的权重。

到目前为止一切顺利,但问题是这一切给我们带来了什么。同样,通过对过去几个值的梯度取平均值,我们倾向于在更敏感的方向上减小振荡,从而使它收敛得更快。

在实践中,基于momentum的优化算法几乎总是比vanilla梯度下降法更快。数学上,

moment = 0

for i in range(iterations_count):

param_gradients = evaluate_gradients(loss_function,

data,

params)

moment = gamma * moment + param_gradients

params += learning_rate * moment

(where moment is building moving average of gradients.

gamma gives kind of friction = 0.9 or 0.99).

AdaGrad优化

我们的想法是,对于每个参数,我们存储其所有历史梯度的平方和。该总和稍后用于缩放学习率。

请注意,与之前的机器学习优化相比,这里我们对每个参数都有不同的学习率。

squared_gradients = 0

for i in range(iterations_count):

param_gradients = evaluate_gradients(loss_function,

data,

params)

squared_gradients += param_gradients * param_gradients

params -= learning_rate * param_gradients/

(np.sqrt(squared_gradients) + 1e-8)

{1e-8 is to avoid divide by zero}

现在的问题是,当我们的损失函数具有非常高的条件数时,这种缩放是如何帮助我们的?

对于具有高梯度值的参数,平方项将很大,因此用大项划分会使梯度在该方向上缓慢加速。类似地,具有低梯度的参数将产生较小的平方项,因此梯度将在该方向上加速更快。

然而请注意,随着梯度在每一步的平方,移动估计将随着时间的推移单调增长,因此我们的算法将收敛到最小值的步长会变得越来越小。

从某种意义上说,这对于凸问题是有益的,因为在这种情况下我们预计会减慢到最小值。然而,在非凸优化问题的情况下,陷入鞍点的机会增加。

RMSProp优化

这是AdaGrad的一个细微变化,在实践中效果更好,因为它解决了它所留下的问题。与AdaGrad类似,这里我们也将保持平方梯度的估计值,但不是让平方估计值累积在训练上,而是让估计值逐渐衰减。为此,我们将当前的平方梯度估计值与衰减率相乘。

squared_gradients = 0

for i in range(iterations_count):

param_gradients = evaluate_gradients(loss_function,

data,

params)

squared_gradients = decay_rate * squared_gradients + (1 -

decay_rate) * param_gradients * param_gradients

params -= learning_rate * param_gradients/

(np.sqrt(squared_gradients) + 1e-8)

Adam

这包含了RMSProp和Gradient下降的所有优点和momentum。

具体而言,该算法计算梯度的指数移动平均值和平方梯度,而参数 beta_1和 beta_2控制这些移动平均值的衰减率。

first_moment = 0

second_moment = 0

for step in range(iterations_count):

param_gradients = evaluate_gradients(loss_function,

data,

params)

first_moment = beta_1 * first_moment + (1 - beta_1) *

param_gradients

second_moment = beta_2 * second_moment + (1 - beta_2) *

param_gradients * param_gradients

params -= learning_rate * first_moment/(np.sqrt(second_moment) +

1e-8)

请注意,我们已将second_moment初始化为零。因此,在开始时,second_moment将被计算为非常接近零的某个位置。因此,我们通过除以非常小的数来更新参数,从而对参数进行大量更新。这意味着最初,算法会做出更大的步骤。为了纠正这一点,我们通过结合当前步骤创建了对第一和第二时刻的无偏估计。然后我们根据这些无偏估计而不是第一和第二时刻更新参数。在数学上,

first_moment = 0

second_moment = 0

for step in range(iterations_count):

param_gradients = evaluate_gradients(loss_function,

data,

params)

first_moment = beta_1 * first_moment + (1 - beta_1) *

param_gradients

second_moment = beta_2 * second_moment + (1 - beta_2) *

param_gradients * param_gradients

first_bias_correction = first_moment/(1 - beta_1 ** step)

second_bias_correction = second_moment/(1 - beta_2 ** step)

params -= learning_rate * first_bias_correction/

(np.sqrt(second_bias_correction) + 1e-8)

下图演示了迭代经过时每个优化算法的性能。显然增加momentum 可提高准确性。然而,在实践中,众所周知,亚当能够很好地处理大型数据集和复杂特征。

揭开机器学习优化的神秘面纱

相关推荐