【multi_scale】多尺度训练——目标检测训练trick

文章目录

  • 1 多尺度训练的介绍
  • 2 代码解析
  • 3 感谢链接

1 多尺度训练的介绍

  • 多尺度训练对全卷积网络有效,在训练时,每隔一定的 iterations,在一定尺寸范围内,随机选取一种 img_size 进行训练。
  • 通过对不同尺度的图像进行训练,在一定程度上提高检测模型对物体大小的鲁棒性。
  • 使用尺度小的图片测试速度快些,但准确度低,用尺度大的图片测试速度慢,但准确度高。

2 代码解析

可以根据代码注释以及最下方的YOLOv3 spp的网络结构图进行理解。

  • 获取一些基础信息:
    # ----------------------------------------------------------------------------------#
    # accumulate n times before optimizer update (bs 64)
    # 每训练64张图片更新一次权重,当batchsize较小时,比如batchsize为4时,每迭代16步更新一次权重
    # ----------------------------------------------------------------------------------#
    accumulate = max(round(64 / batch_size), 1)  
    # ----------------------------------------------------------------------------------#
    # Image sizes
    # 输入图像经过yolo spp网络生成的最小特征图尺寸会变为原来的 1/32,因此图像尺寸要设置成32的倍数
    # ----------------------------------------------------------------------------------#
    gs = 32  # (pixels) grid size
    # math.fmod(a,b):返回给定数字a,b的余数
    assert math.fmod(imgsz_test, gs) == 0, "--img-size %g must be a %g-multiple" % (imgsz_test, gs)
    grid_min, grid_max = imgsz_test // gs, imgsz_test // gs
    # --------------------------------------# 
    #   多尺度训练
    # --------------------------------------#
    if multi_scale:
        imgsz_min = opt.img_size // 1.5		# 这儿的1.5和0.667是自己设置的,表示尺度范围
        imgsz_max = opt.img_size // 0.667

        # 将给定的最大,最小输入尺寸向下调整到32的整数倍
        grid_min, grid_max = imgsz_min // gs, imgsz_max // gs
        imgsz_min, imgsz_max = int(grid_min * gs), int(grid_max * gs)
        imgsz_train = imgsz_max  # initialize with max size
        print("Using multi_scale training, image range[{}, {}]".format(imgsz_min, imgsz_max))
  • 在把图片送入模型训练前进行尺度变换:
    # imgs: [batch_size, 3, img_size, img_size]
    # targets: [num_obj, 6] , that number 6 means -> (img_index, obj_index, x, y, w, h)
    # paths: list of img path
    for i, (imgs, targets, paths, _, _) in enumerate(metric_logger.log_every(data_loader, print_freq, header)):
        # ni 统计从epoch0开始的所有batch数
        ni = i + nb * epoch  # number integrated batches (since train start)
        imgs = imgs.to(device).float() / 255.0  # uint8 to float32, 0 - 255 to 0.0 - 1.0
        targets = targets.to(device)

        # Multi-Scale
        if multi_scale:
            # 每训练64张图片,就随机修改一次输入图片大小,
            # 由于label已转为相对坐标,故缩放图片不影响label的值
            #	结合accumulate,每次更新权重时,换一个img_size
            if ni % accumulate == 0:  # adjust img_size (67% - 150%) every 1 batch
                # 在给定最大最小输入尺寸范围内随机选取一个size(size为32的整数倍)
                img_size = random.randrange(grid_min, grid_max + 1) * gs
            sf = img_size / max(imgs.shape[2:])  # scale factor

            # 如果图片最大边长不等于img_size, 则缩放图片,并将长和宽调整到32的整数倍
            if sf != 1:
                # gs: (pixels) grid size
                # new shape (stretched to 32-multiple)
                # math.ceil(x)返回大于等于参数x的最小整数,即对浮点数向上取整.
                ns = [math.ceil(x * sf / gs) * gs for x in imgs.shape[2:]]  
                # 利用插值方法,对输入imgs进行上\下采样操作,也就是合理改变img尺寸大小
                imgs = F.interpolate(imgs, size=ns, mode='bilinear', align_corners=False)

注:图来自 太阳花的小绿豆。
【multi_scale】多尺度训练——目标检测训练trick_第1张图片

3 感谢链接

https://www.bilibili.com/video/BV1t54y1C7ra/?spm_id_from=trigger_reload
https://blog.csdn.net/qq_37541097?type=blog

你可能感兴趣的:(深度学习基础知识,目标检测系列,目标检测,多尺度训练,multi_scale)