目标检测之二:多尺度

https://zhuanlan.zhihu.com/p/102817180

Multi-scale Training/Testing 多尺度训练/测试

可参考:

初识CV:MMDetection中文文档—4.技术细节​zhuanlan.zhihu.com图标

输入图片的尺寸对检测模型的性能影响相当明显,事实上,多尺度是提升精度最明显的技巧之一。在基础网络部分常常会生成比原图小数十倍的特征图,导致小物体的特征描述不容易被检测网络捕捉。通过输入更大、更多尺寸的图片进行训练,能够在一定程度上提高检测模型对物体大小的鲁棒性仅在测试阶段引入多尺度,也可享受大尺寸和多尺寸带来的增益。

multi-scale training/testing最早见于[1],训练时,预先定义几个固定的尺度,每个epoch随机选择一个尺度进行训练。测试时,生成几个不同尺度的feature map,对每个Region Proposal,在不同的feature map上也有不同的尺度,我们选择最接近某一固定尺寸(即检测头部的输入尺寸)的Region Proposal作为后续的输入。在[2]中,选择单一尺度的方式被Maxout(element-wise max,逐元素取最大)取代:随机选两个相邻尺度,经过Pooling后使用Maxout进行合并,如下图所示。

使用Maxout合并feature vector

近期的工作如FPN等已经尝试在不同尺度的特征图上进行检测,但多尺度训练/测试仍作为一种提升性能的有效技巧被应用在MS COCO等比赛中。

问题:多尺度的选择有什么规则和技巧吗?

答:如果模型不考虑时间开销,尺寸往大的开。一般来说尺度越大效果越好,主要是因为检测的小目标越多效果越差。如果是新手那就按照默认参数的比例扩大就行了,然后测试的时候取训练集的中间值。比如cascade50默认尺度是(1333,800),多尺度可以按照默认尺度的倍数扩大比如扩大两倍(2666,1600),多尺度训练可以写成[(1333, 800), (2666, 1600)],单尺度测试可以选择(2000, 1200),多尺度测试可以选择为多尺度训练的尺度加上他们的中间值[(1333, 800), (2000, 1200),(2666, 1600)]。keep_ratio=True,一般不考虑长边。

MMDetection中,多尺度训练/测试:(源码解析)

只需要修改train_pipeline 和test_pipeline中的img_scale部分即可(换成[(), ()]或者[(), (), ().....])。带来的影响是:train达到拟合的时间增加、test的时间增加,一旦test的时间增加一定会影响比赛的分数,因为比赛都会将测试的时间作为评分标准之一:

参数解析:

  • train_pipelinedict(type='Resize', img_scale=(1333, 800), keep_ratio=True)keep_ratio解析。假设原始图像大小为(1500, 1000),ratio=长边/短边 = 1.5。
    • keep_ratio=True时,img_scale的多尺度最多为两个。假设多尺度为[(2000, 1200), (1333, 800)],则代表的含义为:首先将图像的短边固定到800到1200范围中的某一个数值假设为1100,那么对应的长边应该是短边的ratio=1.5倍为 [公式] ,且长边的取值在1333到2000的范围之内。如果大于2000按照2000计算,小于1300按照1300计算。
    • keep_ratio=False时,img_scale的多尺度可以为任意多个。假设多尺度为[(2000, 1200), (1666, 1000),(1333, 800)],则代表的含义为:随机从三个尺度中选取一个作为图像的尺寸进行训练。
  • test_pipeline 中img_scale的尺度可以为任意多个,含义为对测试集进行多尺度测试(可以理解为TTA)。
train_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(type='LoadAnnotations', with_bbox=True),
    dict(type='Resize', img_scale=(1333, 800), keep_ratio=True), #这里可以更换多尺度[(),()]
    dict(type='RandomFlip', flip_ratio=0.5),
    dict(type='Normalize', **img_norm_cfg),
    dict(type='Pad', size_divisor=32),
    dict(type='DefaultFormatBundle'),
    dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']),
]
test_pipeline = [
    dict(type='LoadImageFromFile'),
    dict(
        type='MultiScaleFlipAug',
        img_scale=(1333, 800), #这里可以更换多尺度[(),()]
        flip=False,
        transforms=[
            dict(type='Resize', keep_ratio=True),
            dict(type='RandomFlip'),
            dict(type='Normalize', **img_norm_cfg),
            dict(type='Pad', size_divisor=32),
            dict(type='ImageToTensor', keys=['img']),
            dict(type='Collect', keys=['img']),
        ])
]
  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值