目标检测的Tricks | 【Trick5】学习率调优方法——warmup

简介: 目标检测的Tricks | 【Trick5】学习率调优方法——warmup

1. warmup理论概要


warmup定义:

在模型训练之初选用较小的学习率,训练一段时间之后(如:10epoches或10000steps)使用预设的学习率进行训练。


warmup作用:

  1. 因为模型的weights是随机初始化的,可以理解为训练之初模型对数据的“理解程度”为0(即:没有任何先验知识),在第一个epoches中,每个batch的数据对模型来说都是新的,模型会根据输入的数据进行快速调参,此时如果采用较大的学习率的话,有很大的可能使模型对于数据“过拟合”(“学偏”),后续需要更多的轮次才能“拉回来”;
  2. 当模型训练一段时间之后(如:10epoches或10000steps),模型对数据具有一定的先验知识,此时使用较大的学习率模型就不容易学“偏”,可以使用较大的学习率加速模型收敛;
  3. 当模型使用较大的学习率训练一段时间之后,模型的分布相对比较稳定,此时不宜从数据中再学到新特点,如果仍使用较大的学习率会破坏模型的稳定性,而使用小学习率更容易获取local optima。


warmup类型:

  1. Constant Warmup

学习率从非常小的数值线性增加到预设值之后保持不变,其学习率的系数如下图所示:

image.png


  1. Linner Warmup

学习率从非常小的数值线性增加到预设值之后,然后再线性减小。其学习率的系数如下图所示:

image.png


  1. Cosine Warmup

学习率先从很小的数值线性增加到预设学习率,然后按照cos函数值进行衰减。其学习率系数如下图所示:

image.png


  1. Gradual Warmup

constant warmup的不足之处在于从一个很小的学习率一下变为比较大的学习率可能会导致训练误差突然增大。于是18年Facebook提出了gradual warmup来解决这个问题,即从最初的小学习率开始,每个step增大一点点,直到达到最初设置的比较大的学习率时,采用最初设置的学习率进行训练。

image.png


gradual warmup的实现模拟代码如下:


"""
Implements gradual warmup, if train_steps < warmup_steps, the
learning rate will be `train_steps/warmup_steps * init_lr`.
Args:
    warmup_steps:warmup步长阈值,即train_steps<warmup_steps,使用预热学习率,否则使用预设值学习率
    train_steps:训练了的步长数
    init_lr:预设置学习率
"""
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline 
warmup_steps = 2500
init_lr = 0.1  
# 模拟训练15000步
max_steps = 15000
learning_rate_lists = []
for train_steps in range(max_steps):
    if warmup_steps and train_steps < warmup_steps:
        warmup_percent_done = train_steps / warmup_steps
        warmup_learning_rate = init_lr * warmup_percent_done  #gradual warmup_lr
        learning_rate = warmup_learning_rate
    else:
#         learning_rate = np.sin(learning_rate)  #预热学习率结束后,学习率呈sin衰减
        learning_rate = learning_rate**1.0001 #预热学习率结束后,学习率呈指数衰减(近似模拟指数衰减)
#     if (train_steps+1) % 100 == 0:
#              print("train_steps:%.3f--warmup_steps:%.3f--learning_rate:%.3f" % (
#                  train_steps+1,warmup_steps,learning_rate))
    learning_rate_lists.append(learning_rate)
plt.figure(figsize=(15, 4))
plt.plot(range(max_steps), learning_rate_lists)


2. warmup实现代码


YOLOv3-SPP代码:


def warmup_lr_scheduler(optimizer, warmup_iters, warmup_factor):
    def f(x):
        """根据step数返回一个学习率倍率因子"""
        if x >= warmup_iters:  # 当迭代数大于给定的warmup_iters时,倍率因子为1
            return 1
        alpha = float(x) / warmup_iters
        # 迭代过程中倍率因子从warmup_factor -> 1
        return warmup_factor * (1 - alpha) + alpha
    return torch.optim.lr_scheduler.LambdaLR(optimizer, lr_lambda=f)
# 训练一个epoch
def train_one_epoch(model, optimizer, data_loader, device, epoch,
                    print_freq, accumulate, img_size,
                    grid_min, grid_max, gs,
                    multi_scale=False, warmup=False, scaler=None):
    ...
    lr_scheduler = None
    if epoch == 0 and warmup is True:  # 当训练第一轮(epoch=0)时,启用warmup训练方式,可理解为热身训练
        warmup_factor = 1.0 / 1000
        warmup_iters = min(1000, len(data_loader) - 1)
        lr_scheduler = utils.warmup_lr_scheduler(optimizer, warmup_iters, warmup_factor)
        accumulate = 1
    ...
    if ni % accumulate == 0 and lr_scheduler is not None:  # 第一轮使用warmup训练方式
        lr_scheduler.step()
# 训练过程
def train(hyp):
    ...
    # optimizer
    pg = [p for p in model.parameters() if p.requires_grad]
    optimizer = optim.SGD(pg, lr=hyp["lr0"], momentum=hyp["momentum"],
                          weight_decay=hyp["weight_decay"], nesterov=True)
    ...
    # Scheduler https://arxiv.org/pdf/1812.01187.pdf
    lf = lambda x: ((1 + math.cos(x * math.pi / epochs)) / 2) * (1 - hyp["lrf"]) + hyp["lrf"]  # cosine
    scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=lf)
    scheduler.last_epoch = start_epoch  # 指定从哪个epoch开始
    ...
    for epoch in range(start_epoch, epochs):
        mloss, lr = train_util.train_one_epoch(model, optimizer, train_dataloader,
                                               device, epoch,
                                               accumulate=accumulate,  # 迭代多少batch才训练完64张图片
                                               img_size=imgsz_train,  # 输入图像的大小
                                               multi_scale=multi_scale,
                                               grid_min=grid_min,  # grid的最小尺寸
                                               grid_max=grid_max,  # grid的最大尺寸
                                               gs=gs,  # grid step: 32
                                               print_freq=50,  # 每训练多少个step打印一次信息
                                               warmup=True,
                                               scaler=scaler)
    # update scheduler
    scheduler.step()


ps:这里的学习率调度是呈余弦变换,这里我可视化了一下学习率曲线,其按epochs来进行变换,也就是横坐标表示epochs。


可视化代码如下所示:


# epochs: 30 
# hyp["lrf"]: 0.01
# x:当前的epoch
lf = lambda x: ((1 + math.cos(x * math.pi / 30)) / 2) * (1 - 0.01) + 0.01
plt.figure(figsize=(15, 4))
max_steps = 100
# x = range(max_steps)
y = [lf(x) for x in range(max_steps)]
plt.plot(range(max_steps), y)


yolov3中的学习率变化曲线:

image.png


参考资料:

https://blog.csdn.net/qq_38253797/article/details/116451541


目录
相关文章
|
机器学习/深度学习 开发框架 .NET
YOLOv5的Tricks | 【Trick6】学习率调整策略(One Cycle Policy、余弦退火等)
YOLOv5的Tricks | 【Trick6】学习率调整策略(One Cycle Policy、余弦退火等)
2556 0
YOLOv5的Tricks | 【Trick6】学习率调整策略(One Cycle Policy、余弦退火等)
|
6月前
|
机器学习/深度学习 数据可视化 算法
R语言梯度提升机 GBM、支持向量机SVM、正则判别分析RDA模型训练、参数调优化和性能比较可视化分析声纳数据
R语言梯度提升机 GBM、支持向量机SVM、正则判别分析RDA模型训练、参数调优化和性能比较可视化分析声纳数据
|
6月前
|
机器学习/深度学习 Oracle 固态存储
目标检测涨点小Trick | 回顾Proposal-Based目标检测,启发小改NMS即可带来涨点
目标检测涨点小Trick | 回顾Proposal-Based目标检测,启发小改NMS即可带来涨点
144 1
|
6月前
|
机器学习/深度学习 算法 PyTorch
PyTorch使用Tricks:学习率衰减 !!
PyTorch使用Tricks:学习率衰减 !!
146 0
|
机器学习/深度学习 存储 缓存
YOLOv5的Tricks | 【Trick9】模型剪枝处理与Pytorch实现的剪枝策略
在yolov5项目中的torch_utils.py文件下,有prune这个函数,用来实现模型的剪枝处理。对模型裁剪,模型剪枝这方面之前没有接触到,这里用这篇笔记来学习记录一下这方面内容。
2219 0
YOLOv5的Tricks | 【Trick9】模型剪枝处理与Pytorch实现的剪枝策略
|
机器学习/深度学习 编解码 监控
NWD-Based Model | 小目标检测新范式,抛弃IoU-Based暴力涨点(登顶SOTA)(一)
NWD-Based Model | 小目标检测新范式,抛弃IoU-Based暴力涨点(登顶SOTA)(一)
893 0
|
数据可视化 计算机视觉
NWD-Based Model | 小目标检测新范式,抛弃IoU-Based暴力涨点(登顶SOTA)(二)
NWD-Based Model | 小目标检测新范式,抛弃IoU-Based暴力涨点(登顶SOTA)(二)
719 0
|
机器学习/深度学习 固态存储 计算机视觉
目标检测改进 | 如何使用IOU改进自注意力以提升Sparse RCNN目标检测性能(一)
目标检测改进 | 如何使用IOU改进自注意力以提升Sparse RCNN目标检测性能(一)
148 0
|
算法 计算机视觉 索引
目标检测改进 | 如何使用IOU改进自注意力以提升Sparse RCNN目标检测性能(二)
目标检测改进 | 如何使用IOU改进自注意力以提升Sparse RCNN目标检测性能(二)
349 0
|
机器学习/深度学习 并行计算 PyTorch
用什么tricks能让模型训练得更快?先了解下这个问题的第一性原理(2)
用什么tricks能让模型训练得更快?先了解下这个问题的第一性原理
133 0