python - Nesterov 的加速梯度下降是如何在 Tensorflow 中实现的?
问题描述
的文档tf.train.MomentumOptimizer
提供了一个use_nesterov
参数来利用 Nesterov 的加速梯度 (NAG) 方法。
但是,NAG 要求计算当前变量所在位置以外的梯度,并且apply_gradients
接口只允许通过当前梯度。所以我不太明白如何用这个接口来实现 NAG 算法。
该文档对实现进行了以下说明:
use_nesterov
: 如果 True 使用 Nesterov Momentum。参见Sutskever 等人,2013 年。此实现始终以传递给优化器的变量值计算梯度。使用 Nesterov Momentum 使变量跟踪theta_t + mu*v_t
论文中调用的值。
阅读了链接中的论文后,我有点不确定这个描述是否回答了我的问题。当接口不需要提供梯度函数时,如何实现 NAG 算法?
解决方案
TL;博士
TF 对 Nesterov 的实现确实是原始公式的近似值,适用于高动量值。
细节
这是一个很好的问题。在论文中,NAG 更新定义为
vt+1 = μ.vt - λ.∇f(θt + μ.vt)
θt+1 = θt + vt+1
哪里f
是我们的成本函数,我们的时间参数,动量,学习率;是 NAG 的内部累加器。θt
t
μ
λ
vt
与标准动量的主要区别在于使用梯度 at ,而不是at 。但正如你所说,tensorflow 只在. 那么诀窍是什么?θt + μ.vt
θt
θt
您引用的部分文档中实际上提到了部分技巧:算法是 tracking ,而不是. 另一部分来自对高动量值有效的近似值。θt + μ.vt
θt
让我们对论文中的符号稍作更改,以使累加器遵守 tensorflow 的定义。让我们定义. 更新规则略有改变at = vt / λ
at+1 = μ.at - ∇f(θt + μ.λ.at)
θt+1 = θt + λ.at+1
(这种 TF 变化的动机是,nowa
是一个纯梯度动量,与学习率无关。这使得更新过程对 的变化具有鲁棒性λ
,这种可能性在实践中很常见,但本文并未考虑。)
如果我们注意到,那么ψt = θt + μ.λ.at
at+1 = μ.at - ∇f(ψt)
ψt+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
μ.λ.at+1
ψt+1
ψ