余弦衰减

[源代码]

CosineDecay

tf_keras.optimizers.schedules.CosineDecay(
    initial_learning_rate,
    decay_steps,
    alpha=0.0,
    name=None,
    warmup_target=None,
    warmup_steps=0,
)

一个使用余弦衰减和可选预热的 LearningRateSchedule。

请参阅 Loshchilov & Hutter, ICLR2016,SGDR:带热重启的随机梯度下降。

关于学习率线性预热的想法,请参阅 Goyal et al.

当我们开始训练模型时,我们通常希望学习率先增加,然后再衰减。如果 warmup_target 是一个整数,则此调度会为学习率应用线性增加,从 initial_learning_ratewarmup_target,持续时间为 warmup_steps,每个优化器步骤都会增加。之后,它会应用一个余弦衰减函数,将学习率从 warmup_target 变为 alpha,持续时间为 decay_steps。如果 warmup_target 为 None,我们将跳过预热,衰减会将学习率从 initial_learning_rate 变为 alpha x initial_learning_rate。它需要一个 step 值来计算学习率。您可以只传递一个 TensorFlow 变量,该变量在每个训练步骤中都会递增。

此调度是一个 1 参数的可调用对象,当传递当前优化器步骤时,它会生成一个预热,然后生成一个衰减的学习率。这对于在不同调用优化器函数时更改学习率值很有用。

我们的预热计算公式为

def warmup_learning_rate(step):
    completed_fraction = step / warmup_steps
    total_delta = target_warmup - initial_learning_rate
    return completed_fraction * total_delta + initial_learning_rate

我们的衰减计算公式为

if warmup_target is None:
    initial_decay_lr = initial_learning_rate
else:
    initial_decay_lr = warmup_target

def decayed_learning_rate(step):
    step = min(step, decay_steps)
    cosine_decay = 0.5 * (1 + cos(pi * step / decay_steps))
    decayed = (1 - alpha) * cosine_decay + alpha
    return initial_decay_lr * decayed

不带预热的示例用法

decay_steps = 1000
initial_learning_rate = 0.1
lr_decayed_fn = tf.keras.optimizers.schedules.CosineDecay(
    initial_learning_rate, decay_steps)

带预热的示例用法

decay_steps = 1000
initial_learning_rate = 0
warmup_steps = 1000
target_learning_rate = 0.1
lr_warmup_decayed_fn = tf.keras.optimizers.schedules.CosineDecay(
    initial_learning_rate, decay_steps, warmup_target=target_learning_rate,
    warmup_steps=warmup_steps
)

您可以将此调度直接传递给 tf.keras.optimizers.Optimizer 作为学习率。学习率调度也可以使用 tf.keras.optimizers.schedules.serializetf.keras.optimizers.schedules.deserialize 进行序列化和反序列化。

返回

一个 1 参数的可调用学习率调度,它接受当前优化器步骤,并输出衰减的学习率,一个与 initial_learning_rate 类型相同的标量 Tensor