我问自己同样的问题,并想知道为什么它不会改变。通过查看原纸 https://arxiv.org/pdf/1412.6980v8.pdf(第 2 页),人们看到self._lr
步长(设计为alpha
论文中)是算法所需要的,但从未更新。我们还看到有一个alpha_t
为每个更新t
步骤,并且应该对应于self._lr_t
属性。但事实上,正如你所观察到的,评估 的价值self._lr_t
训练过程中任何时刻的张量始终返回初始值,即_lr
.
所以,据我了解,你的问题是如何获得alpha_t
对于 TensorFlow 的 AdamOptimizer,如本文第 2 节和相应的TF v1.2 API 页面 https://www.tensorflow.org/versions/r1.2/api_docs/python/tf/train/AdamOptimizer:
alpha_t = alpha * sqrt(1-beta_2_t) / (1-beta_1_t)
背景
正如您所观察到的,_lr_t
张量在训练过程中不会改变,这可能会导致优化器不适应的错误结论(这可以通过切换到vanilla GradientDescentOptimizer
与相同的alpha
)。事实上,其他值确实会发生变化:快速浏览一下优化器的__dict__
显示以下键:['_epsilon_t', '_lr', '_beta1_t', '_lr_t', '_beta1', '_beta1_power', '_beta2', '_updated_lr', '_name', '_use_locking', '_beta2_t', '_beta2_power', '_epsilon', '_slots']
.
通过训练检查他们,我注意到only _beta1_power
, _beta2_power
和_slots
得到更新.
进一步检查优化器的代码 https://github.com/tensorflow/tensorflow/blob/927f811b0303e51126531c135f8b093383de2d6d/tensorflow/python/training/adam.py#L211,在第 211 行,我们看到以下更新:
update_beta1 = self._beta1_power.assign(
self._beta1_power * self._beta1_t,
use_locking=self._use_locking)
这基本上意味着_beta1_power
,即初始化为_beta1 https://github.com/tensorflow/tensorflow/blob/927f811b0303e51126531c135f8b093383de2d6d/tensorflow/python/training/adam.py#L120,将乘以_beta_1_t
每次迭代之后,也初始化为beta_1_t https://github.com/tensorflow/tensorflow/blob/927f811b0303e51126531c135f8b093383de2d6d/tensorflow/python/training/adam.py#L133.
但令人困惑的部分来了:_beta1_t
and _beta2_t
永远不会更新,因此它们有效地保持初始值(_beta1
and _beta2
)在整个训练过程中,以类似的方式与论文的符号相矛盾_lr
and lr_t
do. 我想这是有原因的,但我个人不知道为什么,无论如何,这是实现的受保护/私有属性(因为它们以下划线开头)并且不属于公共接口(它们甚至可能会改变) TF 版本之间)。
所以在这个小背景之后我们可以看到_beta_1_power
and _beta_2_power
是原始 beta 值对当前训练步骤的幂,即相当于用beta_t
在报纸上。回到定义alpha_t
在本文的第 2 节中,我们看到,有了这些信息,实施起来应该非常简单:
SOLUTION
optimizer = tf.train.AdamOptimizer()
# rest of the graph...
# ... somewhere in your session
# note that a0 comes from a scalar, whereas bb1 and bb2 come from tensors and thus have to be evaluated
a0, bb1, bb2 = optimizer._lr, optimizer._beta1_power.eval(), optimizer._beta2_power.eval()
at = a0* (1-bb2)**0.5 /(1-bb1)
print(at)
变量at
持有alpha_t
对于当前的训练步骤。
免责声明
我找不到一种仅使用优化器界面来获取此值的更干净的方法,但请告诉我它是否存在!我想没有,这实际上让人质疑绘图的有用性alpha_t
, since 它不依赖于数据.
此外,为了完善这些信息,本文的第 2 节还给出了权重更新的公式,该公式更能说明问题,但也更情节密集。对于一个非常漂亮且美观的实现,您可能需要看看这个很好的答案 https://stackoverflow.com/a/44688307/4511978从您链接的帖子中。
希望能帮助到你!干杯,
Andres