【问题标题】:TensorFlow 2.0 learning rate scheduler with tf.GradientTape带有 tf.GradientTape 的 TensorFlow 2.0 学习率调度器
【发布时间】:2020-03-22 16:14:59
【问题描述】:

我正在使用 TensorFlow 2.0 和 Python 3.8,我想使用一个学习率调度程序,我有一个函数。我必须训练一个神经网络 160 个时期,其中学习率将在 80 和 120 个时期降低 10 倍,其中初始学习率 = 0.01。

def scheduler(epoch, current_learning_rate): 
        if epoch == 79 or epoch == 119: 
            return current_learning_rate / 10 
        else: 
            return min(current_learning_rate, 0.001) 

如何将这个学习率调度程序函数与“tf.GradientTape()”一起使用?我知道如何使用“model.fit()”作为回调来使用它:

callback = tf.keras.callbacks.LearningRateScheduler(scheduler)

在使用带有“tf.GradientTape()”的自定义训练循环时如何使用它?

谢谢!

【问题讨论】:

    标签: python-3.x tensorflow2.0


    【解决方案1】:

    可以使用 tensorflow keras 优化器的 lr 属性设置不同 epoch 的学习率。优化器的 lr 属性仍然存在,因为 tensorflow 2 对 keras 具有向后兼容性(更多详细信息请参阅源代码here)。 下面是一个关于学习率如何在不同时期变化的小 sn-p。 self._train_step 类似于 here 定义的 train_step 函数。

    def set_learning_rate(epoch):
        if epoch > 180:
            optimizer.lr = 0.5e-6
        elif epoch > 160:
            optimizer.lr = 1e-6
        elif epoch > 120:
            optimizer.lr = 1e-5
        elif epoch > 3:
            optimizer.lr = 1e-4
    
    def train(epochs, train_data, val_data):
        prev_val_loss = float('inf')
        for epoch in range(epochs):
            self.set_learning_rate(epoch)
            for images, labels in train_data:
                self._train_step(images, labels)
            for images, labels in val_data:
                self._test_step(images, labels)
    

    另一种选择是使用 tf.keras.optimizers.schedules

    learning_rate_fn = keras.optimizers.schedules.PiecewiseConstantDecay(
        [80*num_steps, 120*num_steps, 160*num_steps, 180*num_steps],
        [1e-3, 1e-4, 1e-5, 1e-6, 5e-6]
        )
    
    optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate_fn)
    

    注意这里不能直接提供epochs,而是必须给出步数,其中每一步是len(train_data)/batch_size。

    【讨论】:

    • self in train 指的是什么?
    • self 可以参考具有自定义训练和验证步骤的自定义模型类here
    【解决方案2】:

    学习率计划需要一个在使用 GradientTape 时无法指定的步长值,后跟 optimizer.apply_gradient()。

    所以你不应该直接将调度作为优化器的 learning_rate 传递。

    相反,您可以先调用调度函数来获取当前步骤的值,然后在优化器中更新学习率值:

    optim = tf.keras.optimizers.SGD()
    lr_schedule = tf.keras.optimizers.schedules.ExponentialDecay(1e-2,1000,.9)
    for step in range(0,1000): 
        lr = lr_schedule(step)
        optim.learning_rate = lr
        with GradientTape() as tape: 
            call func to differentiate 
        optim.apply_gradient(func,...)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-19
      • 2020-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多