论文
SGDR,以一种周期性调整学习率的方法,周期性地增大学习率
原因
梯度收敛的值可能是空间中的鞍点或者是相对较大的极小值点。
鞍点严重影响模型的学习率,较大的极小值点导致模型性能较差。
空间半径较大的极小值点,模型的泛化能力较强
因此,适度增大学习率,可以使模型更快(学习率较大)地逃离鞍点,从而加速模型收敛。同时,假如收敛的极值点的空间半径较小,更大的学习率有利于让模型跳出这个盆地区域,从而收敛到另一个空间半径较大的极小值点。
η m i n \eta_{min} ηmin和 η m a x \eta_{max} ηmax为学习率的范围, T c u r T_{cur} Tcur为目前的训练次数, T T T为总训练次数
代码实现
"""
引用自论文Barlow Twins: Self-Supervised Learning via Redundancy Reduction
https://github.com/facebookresearch/barlowtwins
"""
def adjust_learning_rate(args, optimizer, loader, step):
max_steps = args.epochs * len(loader)
warmup_steps = 10 * len(loader)
base_lr = args.batch_size / 256
if step < warmup_steps: # 热启动
lr = base_lr * step / warmup_steps
else:
# 先减去warm-up的训练次数
step -= warmup_steps
max_steps -= warmup_steps
# SGDR
q = 0.5 * (1 + math.cos(math.pi * step / max_steps))
end_lr = base_lr * 0.001
lr = base_lr * q + end_lr * (1 - q)
optimizer.param_groups[0]['lr'] = lr * args.learning_rate_weights
optimizer.param_groups[1]['lr'] = lr * args.learning_rate_biases