1. Multi-scale training理论概要
多尺度训练对全卷积网络有效,一般设置几种不同尺度的图片,训练时每隔一定iterations随机选取一种尺度训练。这样训练出来的模型鲁棒性强,其可以接受任意大小的图片作为输入,使用尺度小的图片测试速度会快些,但准确度低,用尺度大的图片测试速度慢,但是准确度高。
训练时,预先定义几个固定的尺度,每个epoch随机选择一个尺度进行训练(实际中还是单个尺度的训练)。
2. Multi-scale training实现代码
YOLOv3-SPP代码:
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): ... # Multi-Scale if multi_scale: # accumulate=16 batch_size=4 # 每训练accumulate个batch(batch_size*accumulate张图片),就随机修改一次输入图片大小 # 由于label已转为相对坐标,故缩放图片不影响label的值 if ni % accumulate == 0: # ni=batch总个数 # 在给定最大最小输入尺寸范围内随机选取一个size(size为32的整数倍) img_size = random.randrange(grid_min, grid_max + 1) * gs # img_size = 320~736 sf = img_size / max(imgs.shape[2:]) # scale factor # 如果图片最大边长不等于img_size, 则缩放一个batch图片,并将长和宽调整到32的整数倍 if sf != 1: # gs: (pixels) grid size ns = [math.ceil(x * sf / gs) * gs for x in imgs.shape[2:]] # new shape (stretched to 32-multiple) # 核心代码: 对图像进行双线性插值来缩放 imgs = F.interpolate(imgs, size=ns, mode='bilinear', align_corners=False) ... pred = model(imgs) def train(hyp): ... # 图像要设置成32的倍数 gs = 32 # (pixels) grid size 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 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)) ... # 多尺度训练 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) ...
简要分析:
从代码上来看,其实Multi-scale Training的理念很简单,就是每次epoch的随机在一个范围内选择一个图像尺度进行训练。
3. Multi-scale testing理论概要
测试时,生成几个不同尺度的feature map,对每个Region Proposal,在不同的feature map上也有不同的尺度,我们选择最接近某一固定尺寸(即检测头部的输入尺寸)的Region Proposal作为后续的输入。
常见的FPN结构,就是使用了多尺度特征层来预测,这里不再介绍。用兴趣的可以看一下之前的关于FPN的笔记:FPN(特征金字塔)结构笔记
参考资料:
https://blog.csdn.net/qq_40992227/article/details/115980500