【目标检测】算法训练常用tricks

本文介绍了目标检测训练中的关键技术,包括Rect方法优化图像批次相似性、优化器设置(如学习率调整和积累策略)、Warmup防止梯度爆炸、多尺度训练增强模型泛化、以及混合精度训练以降低内存需求和加速计算。
摘要由CSDN通过智能技术生成


前言

常用tricks:Rect、优化器和学习率设置、warmup、多尺度训练、混合精度训练。


一、Rect

过程:计算所有训练图像的高宽比,再进行排序,目的是让有着类似高宽比的图像挨在一起,后续分配batch时,就能将有相似高宽比的图像放在同一个batch中。
部分代码如下:

# 记录每张图像的原始尺寸
self.shapes = np.array(s, dtype=np.float64)

# Rectangular Training https://github.com/ultralytics/yolov3/issues/232
# 如果为ture,训练网络时,会使用类似原图像比例的矩形(让最长边为img_size),而不是img_size x img_size
# 注意: 开启rect后,mosaic就默认关闭
if self.rect:  # 使得相同batch的图像有类似的高宽比
    # Sort by aspect ratio
    s = self.shapes  # wh
    # 计算每个图片的高/宽比
    ar = s[:, 1] / s[:, 0]  # aspect ratio
    # argsort函数返回的是数组值从小到大的索引值
    # 按照高宽比例进行排序,这样后面划分的每个batch中的图像就拥有类似的高宽比
    irect = ar.argsort()  # 得到的是索引
    # 根据排序后的顺序重新设置图像顺序、标签顺序以及shape顺序
    self.img_files = [self.img_files[i] for i in irect]  # 根据索引排序,从而使得图像具有类似的高宽比
    self.label_files = [self.label_files[i] for i in irect]
    self.shapes = s[irect]  # wh
    ar = ar[irect]

    # set training image shapes
    # 计算每个batch采用的统一尺度
    shapes = [[1, 1]] * nb  # nb: number of batches
    for i in range(nb):
        ari = ar[bi == i]  # bi: batch index  bi = [00001111...], i:0,1,2... ari = [0.222 0.224 0.292 0.294]
        # 获取第i个batch中,最小和最大高宽比
        mini, maxi = ari.min(), ari.max()

        # 如果高/宽小于1(w > h),将w设为img_size
        if maxi < 1:
            shapes[i] = [maxi, 1]
        # 如果高/宽大于1(w < h),将h设置为img_size
        elif mini > 1:
            shapes[i] = [1, 1 / mini]
    # 计算每个batch输入网络的shape值(向上设置为32的整数倍)
    self.batch_shapes = np.ceil(np.array(shapes) * img_size / 32. + pad).astype(np.int) * 32 # 每个batch都有自己的shape值, getitem时,获取图像的index和其对应的batchsize尺寸

二、优化器和学习率设置

# Optimizer
nbs = 64  # nominal batch size
accumulate = max(round(nbs / batch_size), 1)  # accumulate loss before optimizing
hyp['weight_decay'] *= batch_size * accumulate / nbs  # scale weight_decay
optimizer = smart_optimizer(model, opt.optimizer, hyp['lr0'], hyp['momentum'], hyp['weight_decay'])

# Scheduler
if opt.cos_lr:
    lf = one_cycle(1, hyp['lrf'], epochs)  # cosine 1->hyp['lrf']
else:
    lf = lambda x: (1 - x / epochs) * (1.0 - hyp['lrf']) + hyp['lrf']  # linear
scheduler = lr_scheduler.LambdaLR(optimizer, lr_lambda=lf)  # plot_lr_scheduler(optimizer, scheduler, epochs)

accumulate 是自己设置的batchsize要多少轮才能达到名义的batchsize(nbs),例如,batchsize设为4,那么accumulate就为4,即需要4轮才能达到batch_size=64。
当给模型喂了4批图片数据后,将四批图片数据得到的梯度值,做累积。当每累积到4批数据时,才会对参数做更新,这样就实现了与batch_size=64时相同的效果。
由于batch_size发生了变化,hyp[‘weight_decay’]也要做相应的缩放。
学习率的设置常用一下两种方式:
(1)、线性学习率,通过线性插值的方式调整学习率;
(2)、余弦退火学习率,即采用余弦曲线衰减学习率。
线性学习率在这里插入图片描述

三、Warmup

训练时,learning rate如果一开始就设置得比较大,容易出现梯度爆炸,模型难以收敛,一般都是先以较小的学习率进行训练,再慢慢增大到正常学习率。

# Warmup
if ni <= nw:
    xi = [0, nw]  # x interp
    # compute_loss.gr = np.interp(ni, xi, [0.0, 1.0])  # iou loss ratio (obj_loss = 1.0 or iou)
    accumulate = max(1, np.interp(ni, xi, [1, nbs / batch_size]).round())
    for j, x in enumerate(optimizer.param_groups):
        # bias lr falls from 0.1 to lr0, all other lrs rise from 0.0 to lr0
        x['lr'] = np.interp(ni, xi, [hyp['warmup_bias_lr'] if j == 0 else 0.0, x['initial_lr'] * lf(epoch)])
        if 'momentum' in x:
            x['momentum'] = np.interp(ni, xi, [hyp['warmup_momentum'], hyp['momentum']])

在这里插入图片描述

四、多尺度训练

#Multi-scale
if opt.multi_scale:
    sz = random.randrange(int(imgsz * 0.5), int(imgsz * 1.5) + gs) // gs * gs  # size
    sf = sz / max(imgs.shape[2:])  # scale factor
    if sf != 1:
        ns = [math.ceil(x * sf / gs) * gs for x in imgs.shape[2:]]  # new shape (stretched to gs-multiple)
        imgs = nn.functional.interpolate(imgs, size=ns, mode='bilinear', align_corners=False)

多尺度训练是在默认训练尺寸的基础上(0.5~1.5)之间随机选取一个值,作为下一批次训练用的数据的数据大小。

五、混合精度训练

深度学习框架默认的精度一般为32位单精度浮点数(FP32),混合精度训练是使用16位浮点数(FP16)进行训练,从而减少训练深度学习模型所需的内存,同时FP16比FP32运算速度更快,进一步提高硬件效率。
使用pytorch框架通过:import torch.cuda.amp 导入amp模块,可以方便的进行混合精度训练。

#Forward
with torch.cuda.amp.autocast(True):
    pred = model(imgs)  # forward
    loss, loss_items = compute_loss(pred, targets.to(device))  # loss scaled by batch_size

总结

本文主要总结目标检测训练常用的tricks。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值