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
调整lr
每iterations
根据
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_begin
和epoch = 0
- 如果我们不希望lr
立即衰减,我们应该添加一个epoch != 0
签到decay_schedule
。然后,epoch
表示已经过去了多少个纪元 - 所以当epoch = 5
时,应用衰减。
【讨论】:
只是想再次澄清一下,所以如果我在 keras Adam(lr=xx,decay=yy) 中使用标准 Adam 优化器,lr 现在会在每个批次大小和每个时期减少吗? 另外这个方法和AdamW有什么区别? @ArjunAdamW
只关注权重衰减 - 而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 优化器的衰减参数的主要内容,如果未能解决你的问题,请参考以下文章
在 ADAM 优化器的 CNTK 实现中,参数 alpha、beta1、beta2 和 epsilon 如何与学习率和动量相关