参考论文:SGDR: Stochastic Gradient Descent with Warm Restarts
Bag of Tricks for Image Classification with Convolutional Neural Networks
梯度下降算法需要我们设置一个值,用来控制权重更新幅度,我们将其称之为学习率。它是控制模型学习速度的超参数。学习率越小,loss的变化越慢。虽然使用较低的学习速率可以确保不会错过任何局部极小值,但这也意味着模型收敛速度较慢。
因此,在训练前期,权重处于随机初始化状态,我们可以设置一个相对较大的学习速率以加快收敛速度。在训练后期,权重接近最优值,使用相对较小的学习率可以防止模型在收敛的过程中发生震荡。
Cosine 学习率下降策略
Cosine学习率策略也就应运而生,Cosine学习率策略指的是学习率在训练的过程中,按照余弦的曲线变化。在整个训练过程中,Cosine学习率衰减策略使得在网络在训练初期保持了较大的学习速率,在后期学习率会逐渐衰减至0,其收敛速度相对较慢,但最终收敛精度较好。下图比较了两种不同的学习率衰减策略piecewise decay和cosine decay。
学习率预热策略
模型刚开始训练时,模型权重是随机初始化的,此时若选择一个较大的学习率,可能造成模型训练不稳定的问题,因此学习率预热的概念被提出,用于解决模型训练初期不收敛的问题。
学习率预热指的是将学习率从一个很小的值开始,逐步增加到初始较大的学习率。它可以保证模型在训练初期的稳定性。使用学习率预热策略有助于提高图像分类任务的准确性。在DBNet中,实验表明该策略也是有效的。学习率预热策略与Cosine学习率结合时,学习率的变化趋势如下代码演示。
# Paddle 版本
from ppocr.optimizer import build_lr_scheduler
import numpy as np
import matplotlib.pyplot as plt
# 咱们也可以看看warmup_epoch为2时的效果
lr_config = {'name': 'Cosine', 'learning_rate': 0.1, 'warmup_epoch': 0}
epochs = 20 # config['Global']['epoch_num']
iters_epoch = 100 # len(train_dataloader)
lr_scheduler=build_lr_scheduler(lr_config, epochs, iters_epoch)
iters = 0
lr = []
for epoch in range(epochs):
for _ in range(iters_epoch):
lr_scheduler.step() # 对应 https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.4/tools/program.py#L262
iters += 1
lr.append(lr_scheduler.get_lr())
x = np.arange(iters,dtype=np.int64)
y = np.array(lr,dtype=np.float64)
plt.figure(figsize=(15, 6))
plt.plot(x,y,color='red',label='lr')
plt.title(u'Cosine lr scheduler with Warmup')
plt.xlabel(u'iters')
plt.ylabel(u'lr')
plt.legend()
plt.show()