在TensorFlow

时间:2016-08-10 20:06:48

标签: tensorflow

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

以下是我目前所拥有的代码段:

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与我的相似。但是,我不能在评论部分发布我的发现,因为我没有足够的代表。

1 个答案:

答案 0 :(得分:2)

我问自己完全相同的问题,并想知道为什么它不会改变。通过查看original paper(第2页),我们可以看到算法需要self._lr步长(在论文中设计为alpha),但从未更新过。我们还发现,每个alpha_t步骤都会更新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 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']

通过培训检查,我发现_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_powerinitialized with _beta1)在每次迭代后都会_beta_1_t乘以is also initialized with beta_1_t

但令人困惑的是: _beta1_t_beta2_t永远不会更新,因此它们有效地保留了初始值(_beta1和{{1} }}通过整个培训,与_beta2_lr类似的方式与论文的符号相矛盾。 我想这是有原因的,但我个人不知道为什么,无论如何这是实施的受保护/私有属性(因为它们以下划线开头)并且不属于公共界面(它们甚至可能在TF版本之间发生变化)。

因此,在这个小背景之后,我们可以看到lr_t_beta_1_power是指向当前训练步骤的原始beta值,也就是相当于_beta_2_power引用的变量在论文中。回到本文第2部分中beta_t的定义,我们看到,通过这些信息,实现起来应该非常简单:

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

此外,为了完成这些信息,本文第2部分还给出了权重更新的公式,这更加有说服力,但也更多的是情节密集型。对于非常好看且外观漂亮的实现,您可能需要查看您链接的帖子中的this nice answer

希望它有所帮助!干杯,
安德烈