學習率調整
import mathdef adjust_learning_rate(optimizer, epoch, args):"""Decay the learning rate with half-cycle cosine after warmup"""if epoch < args.warmup_epochs:lr = args.lr * epoch / args.warmup_epochs else:lr = args.min_lr + (args.lr - args.min_lr) * 0.5 * \(1. + math.cos(math.pi * (epoch - args.warmup_epochs) / (args.epochs - args.warmup_epochs)))for param_group in optimizer.param_groups:if "lr_scale" in param_group:param_group["lr"] = lr * param_group["lr_scale"]else:param_group["lr"] = lrreturn lr
預熱階段的學習率調整:
if epoch < args.warmup_epochs:lr = args.lr * epoch / args.warmup_epochs
如果當前 epoch
小于預熱周期數 args.warmup_epochs
,則學習率 lr
隨著 epoch
線性增加,從 0 增加到初始學習率 args.lr
。公式為 lr = lr * epoch / warmup_epochs
:
lr = lr × epoch w a r m u p _ e p o c h s \text{lr} = \frac{\text{lr} \times \text{epoch}}{warmup\_epochs} lr=warmup_epochslr×epoch?
余弦退火階段的學習率調整
else:lr = args.min_lr + (args.lr - args.min_lr) * 0.5 * \(1. + math.cos(math.pi * (epoch - args.warmup_epochs) / (args.epochs - args.warmup_epochs)))
如果當前 epoch
大于等于預熱周期數 args.warmup_epochs
,則使用余弦退火函數來調整學習率。公式為:
lr = args.min_lr + ( args.lr ? args.min_lr ) × 0.5 × ( 1 + cos ? ( π × epoch ? args.warmup_epochs args.epochs ? args.warmup_epochs ) ) \text{lr} = \text{args.min\_lr} + (\text{args.lr} - \text{args.min\_lr}) \times 0.5 \times \left(1 + \cos\left(\pi \times \frac{\text{epoch} - \text{args.warmup\_epochs}}{\text{args.epochs} - \text{args.warmup\_epochs}}\right)\right) lr=args.min_lr+(args.lr?args.min_lr)×0.5×(1+cos(π×args.epochs?args.warmup_epochsepoch?args.warmup_epochs?))
更新優化器的學習率
for param_group in optimizer.param_groups:if "lr_scale" in param_group:param_group["lr"] = lr * param_group["lr_scale"]else:param_group["lr"] = lr
這個函數根據訓練周期動態調整學習率,先進行線性預熱,然后使用余弦退火策略。這樣可以在初期穩定模型的訓練,避免較大學習率帶來的不穩定性,并在后期逐漸減小學習率,提高模型的收斂效果。