【问题标题】:Decay parameter of Adam optimizer in KerasKeras 中 Adam 优化器的衰减参数
【发布时间】:2020-05-18 14:34:06
【问题描述】:

我认为 Adam 优化器的设计使其能够自动调整学习率。 但是在 Keras 的 Adam 参数选项中有一个选项可以明确提及衰减。 我想澄清衰减对 Keras 中 Adam 优化器的影响。 如果我们在 lr = 0.001 上使用衰减假设 0.01 编译模型,然后拟合运行 50 个 epoch 的模型,那么每个 epoch 之后学习率会降低 0.01 倍吗?

有什么方法可以指定学习率只在运行一定数量的 epoch 后才衰减?

在 pytorch 中有一个名为 AdamW 的不同实现,它在标准 keras 库中不存在。 这和上面提到的在每个 epoch 之后改变衰减是一样的吗?

提前感谢您的回复。

【问题讨论】:

    标签: python keras tf.keras


    【解决方案1】:

    source codedecay 调整lriterations 根据

    lr = lr * (1. / (1. + decay * iterations))  # simplified
    

    请参阅下面的image。这是与时代无关的。 iterations 在每个批次拟合时增加 1(例如,每次调用 train_on_batch 时,或者 x 中有多少批次 model.fit(x) - 通常是 len(x) // batch_size 批次)。

    要实现您所描述的,您可以使用如下回调:

    from keras.callbacks import LearningRateScheduler
    def decay_schedule(epoch, lr):
        # decay by 0.1 every 5 epochs; use `% 1` to decay after each epoch
        if (epoch % 5 == 0) and (epoch != 0):
            lr = lr * 0.1
        return lr
    
    lr_scheduler = LearningRateScheduler(decay_schedule)
    model.fit(x, y, epochs=50, callbacks=[lr_scheduler])
    

    LearningRateScheduler 将函数作为参数,并在每个 epoch 的开始.fit 向函数提供 epoch 索引和 lr。然后它根据该函数更新lr - 所以在下一个时期,该函数被提供更新的 lr

    此外,我还提供了 AdamW、NadamW 和 SGDW 的 Keras 实现 - Keras AdamW



    澄清:对.fit() 的第一次调用调用on_epoch_beginepoch = 0 - 如果我们不希望lr 立即衰减,我们应该添加一个epoch != 0签到decay_schedule。然后,epoch 表示已经过去了多少个纪元 - 所以当epoch = 5 时,应用衰减。

    【讨论】:

    • 只是想再次澄清一下,所以如果我在 keras Adam(lr=xx,decay=yy) 中使用标准 Adam 优化器,lr 现在会在每个批次大小和每个时期减少吗?
    • 另外这个方法和AdamW有什么区别?
    • @Arjun AdamW 只关注权重衰减 - 而AdamWR 使用循环学习率;有关两者的简要概述,请参阅我的 repo 的 README。您可能还会发现this thread 很有用。至于decay,总的来说,我建议不要这样做,因为大多数训练只是用原始lr 的一小部分进行,最终完全衰减到零。
    • @Arjun 因为decay 独立于epoch - 是的,它将同时适用于纪元结束和批量拟合结束,因为“纪元结束”发生在“批量结束”。 (但不,它不会“堆叠”,即在纪元结束时发生两次)
    • 对我来说,这个答案和其他类似的答案一样有一个主要缺点。我们应该在哪里以及如何在模型的 .compile() 方法中指定优化器。在上面的示例中,您指定了LearningRateScheduler,这很好,model.fit()。但是带有 Adam 优化器 初始化的model.compile() 语句在哪里。显式使用上面的代码不会启动训练过程
    【解决方案2】:

    在内部,每个批次大小之后的每个学习率都会衰减,但不像通常认为的那样在每个 epoch 之后。

    您可以在此处阅读更多信息:https://www.pyimagesearch.com/2019/07/22/keras-learning-rate-schedules-and-decay/

    不过,您也可以通过自定义回调函数实现自己的 learning_rate 调度器:

        def learning_rate_scheduler(epoch, lr): 
            #Say you want to decay linearly by 5 after every 10 epochs the lr
            #(epoch + 1) since it starts from epoch 0
            if (epoch + 1) % 10 == 0:
               lr = lr / 5
    
        callbacks = [
           tensorflow.keras.callbacks.LearningRateScheduler(learning_rate_scheduler, verbose=1)
        ]
    
        model.fit(...,callbacks=callbacks,...)
    

    上述方法适用于所有类型的优化器,不仅是 Adam。

    【讨论】:

    • 其实,别管我评论的后半部分——它只适用于旧的 Keras API;从源代码来看,回调确实是递归应用的,所以除了条件检查之外,你的原件很好 - 也更新了我的答案。
    • 请见谅——epoch + 1 也不太好用;为了避免过于复杂的表达式,我只是明确地编码了条件。
    • 是的,我想可能是我记不太清了,重新更新了;感谢您再次指出。
    猜你喜欢
    • 2021-09-25
    • 2019-04-04
    • 1970-01-01
    • 2020-01-09
    • 2021-02-13
    • 2020-05-21
    • 2017-10-14
    • 2018-10-02
    • 2018-06-04
    相关资源
    最近更新 更多