如何在Tensorflow中实现Nesterov加速梯度下降?

tf.train.MomentumOptimizer的文档提供了一个use_nesterov参数,用于启用Nesterov加速梯度(NAG)方法。

然而,NAG需要计算当前变量位置之外的梯度,而apply_gradients接口只允许传递当前梯度。因此,我不太明白如何使用这个接口来实现NAG算法。

文档中关于实现的描述如下:

use_nesterov:如果为True,则使用Nesterov动量。详见Sutskever等人,2013。此实现始终在传递给优化器的变量值上计算梯度。使用Nesterov动量使得变量跟踪论文中称为theta_t + mu*v_t的值。

阅读了链接中的论文后,我不太确定这个描述是否回答了我的问题。当接口不需要提供梯度函数时,如何实现NAG算法?


回答:

简而言之

TensorFlow对Nesterov的实现实际上是对原始公式的一种近似,适用于高动量值的情况。

详细信息

这是一个很好的问题。在论文中,NAG的更新定义为

vt+1 = μ.vt - λ.∇f(θt + μ.vtt+1 = θt + vt+1

其中f是我们的成本函数,θt是时间t的参数,μ是动量,λ是学习率;vt是NAG的内部累加器。

与标准动量的主要区别在于使用了θt + μ.vt处的梯度,而不是θt处的梯度。但正如你所说,TensorFlow只使用θt处的梯度。那么诀窍是什么呢?

诀窍的一部分实际上在你引用的文档部分中提到了:算法跟踪的是θt + μ.vt,而不是θt。另一部分来自于对高动量值有效的近似。

让我们对累加器的符号做一些小的改动以符合TensorFlow的定义。我们定义at = vt / λ。更新规则略有变化,如下所示:

at+1 = μ.at - ∇f(θt + μ.λ.att+1 = θt + λ.at+1

(在TensorFlow中进行此更改的动机是,现在a是一个纯粹的梯度动量,与学习率无关。这使得更新过程对λ的变化具有鲁棒性,这在实践中很常见,但论文中并未考虑这种情况。)

如果我们记ψt = θt + μ.λ.at,那么

at+1 = μ.at - ∇f(ψtt+1 = θt+1 + μ.λ.at+1    = θt + λ.at+1 + μ.λ.at+1    = ψt + λ.at+1 + μ.λ.(at+1 - at)    = ψt + λ.at+1 + μ.λ.[(μ-1)at - ∇f(ψt)]    ≈ ψt + λ.at+1

这个最后的近似在动量值强的情况下成立,其中μ接近1,因此μ-1接近零,且∇f(ψt)a相比较小——实际上,这个最后的近似更具争议性,对于梯度经常变化的方向不太有效。

我们现在有一个使用当前位置梯度的更新,规则相当简单——实际上它们就是标准动量的规则。

然而,我们想要的是θt,而不是ψt。这就是为什么在返回之前我们从ψt+1中减去μ.λ.at+1——为了恢复ψ,在下一次调用时首先会再次加上它。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注