文章目录
- 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 // gsimgsz_min, imgsz_max = int(grid_min * gs), int(grid_max * gs)imgsz_train = imgsz_max # initialize with max sizeprint("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 pathfor 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.0targets = targets.to(device)# Multi-Scaleif multi_scale:# 每训练64张图片,就随机修改一次输入图片大小,# 由于label已转为相对坐标,故缩放图片不影响label的值# 结合accumulate,每次更新权重时,换一个img_sizeif ni % accumulate == 0: # adjust img_size (67% - 150%) every 1 batch# 在给定最大最小输入尺寸范围内随机选取一个size(size为32的整数倍)img_size = random.randrange(grid_min, grid_max + 1) * gssf = 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)
注:图来自 太阳花的小绿豆。
3 感谢链接
https://www.bilibili.com/video/BV1t54y1C7ra/?spm_id_from=trigger_reload
https://blog.csdn.net/qq_37541097?type=blog