在TensorFlow中,Gradient Descent vs Adagrad vs Momentum

时间:2016-03-22 18:16:39

标签: tensorflow deep-learning

我正在研究 TensorFlow 以及如何使用它,即使我不是神经网络和深度学习(只是基础知识)的专家。

按照教程,我不理解三个优化器之间的实际和实际差异。我看一下API,我理解原则,但我的问题是:

1。何时优先使用一个而不是其他?

2。是否存在重要差异?

3 个答案:

答案 0 :(得分:168)

根据我的理解,这是一个简短的解释:

  • 势头 helps SGD沿着相关方向导航并软化无关紧要的振荡。它只是将前一步骤的一部分方向添加到当前步骤。这实现了在正确方向上的速度放大并且在错误的方向上软化振荡。该分数通常在(0,1)范围内。使用自适应动量也是有意义的。在学习开始时,一个巨大的动力只会阻碍你的进步,所以使用像0.01这样的东西是有意义的,一旦所有的高梯度消失,你就可以使用更大的动力。动量存在一个问题:当我们非常接近目标时,我们在大多数情况下的势头非常高,并且不知道它应该减速。这可能导致它在最小值周围错过或振荡
  • nesterov加速渐变通过开始减速来克服这个问题。在动量中,我们首先计算梯度,然后在那个方向上跳跃,放大我们之前的动量。 NAG做了同样的事情,但是按照另一种顺序:首先我们根据存储的信息进行大跳,然后我们计算渐变并进行小的修正。这种看似无关紧要的变化带来了显着的实际加速。
  • AdaGrad 或自适应渐变允许学习率根据参数进行调整。它为不频繁的参数执行更大的更新,为频繁的参数执行更小的更新。因此,它非常适合稀疏数据(NLP或图像识别)。另一个优点是它基本上消除了调整学习速率的需要。每个参数都有自己的学习速率,并且由于算法的特殊性,学习速率是单调递减的。这导致了最大的问题:在某个时间点,学习率很小,系统停止学习。
  • AdaDelta resolves AdaGrad单调降低学习率的问题。在AdaGrad中,学习率大致计算为1除以平方根的总和。在每个阶段,您将另一个平方根添加到总和,这会导致分母不断增加。在AdaDelta中,它不是对所有过去的平方根求和,而是使用滑动窗口,允许总和减少。 RMSprop 与AdaDelta非常相似
  • Adam 或自适应动量是一种类似于AdaDelta的算法。但除了存储每个参数的学习率之外,它还分别存储每个参数的动量变化。

    A few visualizationsenter image description here enter image description here

我想说SGD,Momentum和Nesterov都不如过去3年。

答案 1 :(得分:8)

Salvador Dali's answer已经解释了一些流行方法(例如优化程序)之间的区别,但是我会尝试详细说明它们。
(请注意,我们的回答在某些方面存在分歧,尤其是关于ADAGRAD。)

经典动量(CM)与内斯特罗夫的加速梯度(NAG)

(主要基于On the importance of initialization and momentum in deep learning号文件第2节。)

CM和NAG中的每个步骤实际上都由两个子步骤组成:

  • 动量子步骤-这只是最后一步的一小部分(通常在[0.9,1)范围内)。
  • 与梯度有关的子步骤-类似于SGD中的通常步骤-它是学习率和与梯度相反的向量的乘积,而梯度是在此子步骤开始的地方计算的来自。

CM首先采取梯度子步骤,而NAG首先采取动量子步骤。

这是an answer about intuition for CM and NAG的演示:

CM vs NAG example

所以NAG似乎更好(至少在图像中如此),但是为什么呢?

要注意的重要一点是,动量子步骤何时出现并不重要-两种方法都相同。因此,如果动量子步骤已经采取,我们也可能会表现出来。

因此,问题实际上是:假设梯度子步骤是在动量子步骤之后进行的,我们是否应该计算梯度子步骤,就像它在采取动量子步骤之前或之后的位置开始一样?

“之后”似乎是正确的答案,通常来说,在某个点θ处的渐变大致将您指向从θ到最小值(幅度相对正确)的方向,而另一点的渐变不太可能使您指向θ到最小值(幅度相对正确)的方向。

这是一个演示(来自下面的gif):

CM vs NAG in a specific moment in the awesome gif

  • 最小值是星形所在的位置,曲线是contour lines。 (有关轮廓线及其为何垂直于渐变的说明,请参见传奇人物1拍摄的视频23Blue1Brown。)
  • (长)紫色箭头是动量子步骤。
  • 如果透明红色箭头在动量子步骤之前开始,则它是梯度子步骤。
  • 如果黑色箭头在动量子步骤之后开始,则它是梯度子步骤。
  • CM将最终到达深红色箭头的目标。
  • NAG将最终到达黑色箭头的目标。

请注意,关于NAG为何更好的论点与算法是否接近最小值无关。
通常,NAG和CM都经常积聚更多的动力而不是对他们有益,因此,每当他们改变方向时,它们都有一个尴尬的“响应时间”。我们所解释的NAG相对于CM的优势并不能解决问题,而只是使NAG的“响应时间”减少了尴尬(但仍然令人尴尬)。

Alec Radford(出现在Salvador Dali's answer中的gif很好地展示了这个“响应时间”问题:
An example of the embarrassing response time of both momentum methods

ADAGRAD

(主要基于ADADELTA: An Adaptive Learning Rate Method(原始ADADELTA论文)中的2.2.2节,因为我发现它比Adaptive Subgradient Methods for Online Learning and Stochastic Optimization(原始ADAGRAD论文)更易于访问。)
< / p>

SGD中,该步由- learning_rate * gradient给出,而learning_rate是一个超参数。
ADAGRAD还具有一个learning_rate超参数,但是该梯度的每个分量的实际学习率都是单独计算的。
i步的第t步由下式给出:

              learning_rate 
- --------------------------------------- * gradient_i_t
  norm((gradient_i_1, ..., gradient_i_t))

同时:

  • gradient_i_k是第i步中梯度的第k
  • (gradient_i_1, ..., gradient_i_t)是具有t个分量的向量。 (至少对我来说)构造这样的向量不是很直观(但这对我来说),但这就是算法(从概念上)所做的。
  • norm(vector)l2的{​​{3}}(又称vector规范),这是我们对vector长度的直观理解。
  • 令人困惑的是,在ADAGRAD(以及某些其他方法)中,乘以gradient_i_t(在这种情况下为learning_rate / norm(...))的表达式通常称为“学习率”(实际上,我在上一段中将其称为“实际学习率”。我猜这是因为在Eucldiean norm中,learning_rate超参数与该表达式是相同的。
  • 在实际的实现中,会将一些常数添加到分母中,以防止被零除。

例如如果:

  • 第一步中,渐变的第i个分量是1.15
  • 第二步中,梯度的第i个分量是1.35
  • 第三步中,渐变的第i个分量是0.9

然后(1.15, 1.35, 0.9)的范数是黄线的长度,即:
sqrt(1.15^2 + 1.35^2 + 0.9^2) = 1.989
因此,第三步的第i个组件是:- learning_rate / 1.989 * 0.9

SGD

请注意有关该步骤的第i个组件的两件事:

  1. 它与learning_rate成比例。
  2. 在计算中,规范在增加,因此学习率在下降。

这意味着ADAGRAD对超参数learning_rate的选择很敏感。
另外,可能是步骤过了一段时间之后,ADAGRAD实际上陷入了困境。

ADADELTA和RMSProp

来自l2 norm example

  

本文提出的想法源自ADAGRAD,以改善两个主要缺点   的方法:1)学习率的持续下降   整个培训过程中; 2)需要手动选择   全球学习率。

然后,本文解释了旨在解决第一个缺点的改进:

  

而不是累计所有梯度的平方和   时间,我们限制了过去累积的渐变的窗口   为固定大小w [...]。这样可以确保学习继续   即使经过多次更新,也可以取得进步   完成了。
  由于存储w个先前的平方梯度效率很低,   我们的方法以指数形式实现了这种积累   平方梯度的衰减平均值。

通过“平方梯度的指数衰减平均值”,本文意味着,对于每个i,我们计算所有梯度的所有平方i的所有分量的加权平均值。
每个平方i的分量的权重大于上一步中平方i的分量的权重。

这是一个w大小的窗口的近似值,因为前面步骤中的权重很小。

((当我想到指数衰减的平均值时,我想像一条ADADELTA paper踪迹,随着离彗星越来越远,它变得越来越暗:

comet's

如果仅对ADAGRAD进行此更改,则将获得RMSProp,这是Geoff Hinton在a comet's trail as an intuition for a moving average中提出的方法。

因此在RMSProp中,第i步的第t步由下式给出:

                   learning_rate
- ------------------------------------------------ * gradient_i_t
  sqrt(exp_decay_avg_of_squared_grads_i + epsilon)

同时:

  • epsilon是一个超参数,可防止被零除。
  • exp_decay_avg_of_squared_grads_i是所计算的所有梯度(包括i)的第gradient_i_t平方分量的指数衰减平均值。

但是如上所述,ADADELTA还旨在摆脱learning_rate超参数,因此其中必须包含更多内容。

在ADADELTA中,第i步的第t步的组成为:

  sqrt(exp_decay_avg_of_squared_steps_i + epsilon)
- ------------------------------------------------ * gradient_i_t
  sqrt(exp_decay_avg_of_squared_grads_i + epsilon) 

exp_decay_avg_of_squared_steps_i是计算出的所有步骤(直到第i步)的第t-1平方平方的指数衰减平均值。
sqrt(exp_decay_avg_of_squared_steps_i + epsilon)有点类似于动量,根据Lecture 6e of his Coursera Class,它“充当加速项”。 (该文件还提供了添加该文件的另一个原因,但是我的回答已经太长了,因此,如果您很好奇,请参阅第3.2节。)

亚当

(主要基于亚当的原始论文the paper。)

Adam是Adaptive Moment Estimation的缩写(有关名称的说明,请参见Adam: A Method for Stochastic Optimization)。
i步的第t步由下式给出:

                   learning_rate
- ------------------------------------------------ * exp_decay_avg_of_grads_i
  sqrt(exp_decay_avg_of_squared_grads_i) + epsilon

同时:

  • exp_decay_avg_of_grads_i是所有计算出的梯度(包括i)中第gradient_i_t个分量的指数衰减平均值。
  • 实际上,exp_decay_avg_of_grads_iexp_decay_avg_of_squared_grads_i均已得到修正,以解决对0的偏见(有关更多信息,请参见this answer中的第3节,以及{ {3}})。

请注意,Adam使用梯度的第i个分量的指数衰减平均值,其中大多数the paper方法使用当前梯度的第i个分量。正如论文an answer in stats.stackexchange所述,这导致亚当的行为就像“一个沉重的摩擦球”。
有关亚当的类似动量的行为与通常的类似动量的行为有何不同,请参见SGD

答案 2 :(得分:1)

我们将其归结为一个简单的问题:

哪个优化程序会给我最好的结果/准确性?

没有银弹。一些针对您的任务的优化器可能会比其他优化器更好。没有办法事先告诉您,您必须尝试一些才能找到最好的。好消息是,不同优化器的结果可能彼此接近。不过,您必须为您选择的任何单个优化器找到最佳的超参数。

我现在应该使用哪个优化程序?

也许,请使用AdamOptimizer并以learning_rate 0.001和0.0001运行它。如果您想要更好的结果,请尝试以其他学习速度运行。或尝试使用其他优化器并调整其超参数。

长话

选择优化器时需要考虑以下几个方面:

  • 易于使用(即找到适合您的参数的速度);
  • 收敛速度(基本为SGD或更快的速度)
  • 内存占用量(通常在模型的0和x2大小之间);
  • 与培训过程其他部分的关系。

普通SGD 是可以做到的最低要求:只需将梯度乘以学习率,然后将结果加到权重即可。 SGD具有许多出色的品质:只有1个超参数;它不需要任何额外的内存;它对训练的其他部分影响很小。它也有两个缺点:它可能对学习率的选择过于敏感,并且训练可能比其他方法花费更长的时间。

从普通SGD的这些缺点中,我们可以看到更复杂的更新规则(优化器)的用途是:我们牺牲了一部分内存以实现更快的训练,并可能简化了超参数的选择。

内存开销通常不重要,可以忽略。除非模型非常大,或者您正在使用GTX760进行培训,或者正在争夺ImageNet的领导地位。动量或Nesterov加速梯度等较简单的方法需要模型大小(模型超参数的大小)为1.0或更小。二阶方法(亚当,可能需要两倍的内存和计算量。

收敛速度-几乎任何东西都比SGD更好,而其他任何东西都很难比较。一个注意事项可能是AdamOptimizer擅长几乎立即开始训练,而无需热身。

我认为易于使用是选择优化器时最重要的。不同的优化器具有不同数量的超参数,并且对它们的敏感性不同。我认为亚当是所有现有的最简单的。通常,您需要检查0.0010.0001之间的2-4个学习率,以确定模型是否收敛良好。为了比较SGD(和动力),我通常尝试[0.1, 0.01, ... 10e-5]。亚当还有另外2个无需更改的超参数。

优化器与培训其他部分之间的关​​系。超参数调整通常涉及同时选择{learning_rate, weight_decay, batch_size, droupout_rate}。它们都是相互关联的,每个都可以看作是模型正则化的一种形式。例如,如果正好使用weight_decay或L2-norm并可能选择AdamWOptimizer而不是AdamOptimizer,则必须密切注意。