Keras 中 Adam 优化器的衰减参数

Posted

技术标签:

【中文标题】Keras 中 Adam 优化器的衰减参数【英文标题】:Decay parameter of Adam optimizer in Keras 【发布时间】: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 之后改变衰减是一样的吗?

提前感谢您的回复。

【问题讨论】:

【参考方案1】:

从source code,decay 调整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 也不太好用;为了避免过于复杂的表达式,我只是明确地编码了条件。 是的,我想可能是我记不太清了,重新更新了;感谢您再次指出。

以上是关于Keras 中 Adam 优化器的衰减参数的主要内容,如果未能解决你的问题,请参考以下文章

Pytorch中adam优化器的参数问题

在 ADAM 优化器的 CNTK 实现中,参数 alpha、beta1、beta2 和 epsilon 如何与学习率和动量相关

Adam优化器

ADAM 优化器如何在 keras 中输出 v_t 的特定值?

torch.optim.adam里面的参数可以自动设置吗

我们应该为亚当优化器做学习率衰减吗