【问题标题】:Learning rate doesn't change for AdamOptimizer in TensorFlowTensorFlow 中 AdamOptimizer 的学习率不会改变
【发布时间】:2016-12-17 09:07:12
【问题描述】:

我想看看学习率在训练期间如何变化(打印出来或创建摘要并在 tensorboard 中可视化)。

这是我目前所拥有的代码 sn-p:

optimizer = tf.train.AdamOptimizer(1e-3)
grads_and_vars = optimizer.compute_gradients(loss)
train_op = optimizer.apply_gradients(grads_and_vars, global_step=global_step)

sess.run(tf.initialize_all_variables())

for i in range(0, 10000):
   sess.run(train_op)
   print sess.run(optimizer._lr_t)

如果我运行代码,我会不断获得初始学习率 (1e-3),即我看不到任何变化。

获取每一步学习率的正确方法是什么?

我想补充一点,this question 与我的非常相似。但是,我无法在评论部分发表我的发现,因为我没有足够的代表。

【问题讨论】:

    标签: tensorflow


    【解决方案1】:

    我问自己同样的问题,想知道为什么不改变。通过查看 original paper(第 2 页),可以看到算法需要 self._lr 步长(在论文中使用 alpha 设计),但从未更新。我们还看到每个t 步骤都会更新一个alpha_t,并且应该对应于self._lr_t 属性。但事实上,正如您所观察到的,在训练期间的任何时候评估 self._lr_t 张量的值总是会返回初始值,即 _lr

    因此,据我了解,您的问题是如何获取 TensorFlow 的 AdamOptimizer 的 alpha_t,如本文第 2 节和相应的 TF v1.2 API page 中所述

    alpha_t = alpha * sqrt(1-beta_2_t) / (1-beta_1_t)

    背景

    正如您所观察到的,_lr_t 张量在训练过程中并没有改变,这可能会导致优化器不适应的错误结论(这可以通过切换到 vanilla 来轻松测试 em> GradientDescentOptimizeralpha 相同)。而且,事实上,其他值确实会发生变化:快速查看优化器的 __dict__ 会发现以下键:['_epsilon_t', '_lr', '_beta1_t', '_lr_t', '_beta1', '_beta1_power', '_beta2', '_updated_lr', '_name', '_use_locking', '_beta2_t', '_beta2_power', '_epsilon', '_slots']

    通过培训检查他们,我注意到只有_beta1_power_beta2_power_slots 得到更新

    进一步检查the optimizer's code,在第 211 行,我们看到以下更新:

    update_beta1 = self._beta1_power.assign(
            self._beta1_power * self._beta1_t,
            use_locking=self._use_locking)
    

    这基本上意味着_beta1_power,即initialized with _beta1,将在每次迭代后乘以_beta_1_t,即is also initialized with beta_1_t

    但令人困惑的部分来了:_beta1_t_beta2_t 永远不会更新,因此它们在整个训练过程中有效地保持初始值(_beta1_beta2),相互矛盾论文的符号与_lrlr_t 类似。 我想这是有原因的,但我个人不知道为什么,无论如何这是实现的受保护/私有属性(因为它们以下划线开头)并且不属于公共接口(它们甚至可能在 TF 版本之间发生变化)。

    所以经过这个小背景我们可以看到_beta_1_power_beta_2_power是对当前训练步取幂的原始beta值,也就是等同于论文中beta_t所指的变量。回到论文第 2 节中alpha_t 的定义,我们看到,有了这些信息,它应该很容易实现:

    解决方案

    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 的有用性,因为它不依赖于数据

    此外,为了完成这些信息,论文的第 2 部分还给出了权重更新的公式,这更能说明问题,但情节也更密集。对于一个非常漂亮和好看的实现,您可能需要查看您链接的帖子中的this nice answer

    希望对您有所帮助!干杯,
    安德烈斯

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-29
      • 1970-01-01
      相关资源
      最近更新 更多