【问题标题】:Learning rate of custom training loop for tensorflow 2.0tensorflow 2.0 的自定义训练循环的学习率
【发布时间】:2021-12-07 22:56:33
【问题描述】:

当我使用 tensorflow 2.0 自定义训练循环时,是否有任何函数或方法可以显示学习率?

这里是一个tensorflow指南的例子:

def train_step(images, labels):
  with tf.GradientTape() as tape:
    predictions = model(images)
    loss = loss_object(labels, predictions)
  gradients = tape.gradient(loss, model.trainable_variables)
  optimizer.apply_gradients(zip(gradients, model.trainable_variables))

  train_loss(loss)
  train_accuracy(labels, predictions)

如何在模型训练时从优化器中检索当前的学习率?

如果您能提供任何帮助,我将不胜感激。 :)

【问题讨论】:

    标签: python tensorflow


    【解决方案1】:

    在 Tensorflow 2.1 中,Optimizer 类有一个未记录的方法 _decayed_lr(参见定义 here),您可以通过提供要转换为的变量类型在训练循环中调用该方法:

    current_learning_rate = optimizer._decayed_lr(tf.float32)
    

    这里还有一个更完整的 TensorBoard 示例。

    train_step_count = 0
    summary_writer = tf.summary.create_file_writer('logs/')
    def train_step(images, labels):
      train_step_count += 1
      with tf.GradientTape() as tape:
        predictions = model(images)
        loss = loss_object(labels, predictions)
      gradients = tape.gradient(loss, model.trainable_variables)
      optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    
      # optimizer._decayed_lr(tf.float32) is the current Learning Rate.
      # You can save it to TensorBoard like so:
      with summary_writer.as_default():
        tf.summary.scalar('learning_rate',
                          optimizer._decayed_lr(tf.float32),
                          step=train_step_count)
    

    【讨论】:

    • 正是我需要的。谢谢!
    【解决方案2】:

    在自定义训练循环设置中,您可以print(optimizer.lr.numpy()) 获取学习率。

    如果您使用的是 keras api,您可以定义自己的回调来记录当前的学习率。

    from tensorflow.keras.callbacks import Callback
    
    class LRRecorder(Callback):
        """Record current learning rate. """
        def on_epoch_begin(self, epoch, logs=None):
            lr = self.model.optimizer.lr
            print("The current learning rate is {}".format(lr.numpy()))
    
    # your other callbacks 
    callbacks.append(LRRecorder())
    

    更新

    w := w - (base_lr*m/sqrt(v))*grad = w - act_lr*grad 我们上面得到的学习率是base_lr。但是,act_lr 在训练期间是自适应变化的。以 Adam 优化器为例,act_lrbase_lrmv 确定。 mv 是参数的第一和第二动量。不同的参数有不同的mv 值。所以如果你想知道act_lr,你需要知道变量的名字。比如想知道变量Adam/dense/kernelact_lr,可以这样访问mv

    for var in optimizer.variables():
      if 'Adam/dense/kernel/m' in var.name:
        print(var.name, var.numpy())
    
      if 'Adam/dense/kernel/v' in var.name:
        print(var.name, var.numpy())
    

    然后您可以使用上面的公式轻松计算act_lr

    【讨论】:

    • 我知道我可以通过 print(optimizer.lr.numpy()) 获得学习率。但是如果我使用 Adam 或其他自适应优化器,学习率应该在训练过程中改变。但是,当我检查 optimizer.lr 的值时,学习率并没有改变。
    • @yun 这样就得到了学习率的常数项。我想你已经发现了这个细节。您是否知道如何获得有效学习率的值?
    【解决方案3】:

    我有同样的问题,但我认为这个问题的目的不是很好。我们知道,Adam 是根据过去的损失函数相对于所考虑的权重的梯度来计算学习率的。

    所以让我们假设存在一个函数,其输出是 Adam 的自适应学习率;那么我们将获得与神经网络权重一样多的学习率

    其实,按照zihaozhihao建​​议的程序:

    for var in actor_optimizer.variables():
      if 'Adam/dense/kernel/m' in var.name:
        print(var.name, len(var.numpy()), len(var.numpy()[0]))
    
      if 'Adam/dense/kernel/v' in var.name:
        print(var.name, len(var.numpy()), len(var.numpy()[0]))
    

    对象的长度不会等于 1,而是取决于神经网络架构。

    另一方面,像 SGD 这样的优化器对每个权重使用相同的 lr,因此在这种情况下,您可以唯一定义一个 lr。

    【讨论】:

      猜你喜欢
      • 2020-04-13
      • 1970-01-01
      • 2020-06-23
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 2021-10-31
      • 2021-08-01
      • 2020-02-22
      相关资源
      最近更新 更多