An Analysis of Scale Invariance in Object Detection – SNIP解读

今天无意中看到这篇好文,在网上搜索时发现Naiyan Wang也在知乎上推荐了,还中了CVPR2018的oral,佩服!

Introduction

这篇文章首先想探讨一个问题:scale变化对识别和检测的影响,然后就是upsample对于小物体的检测有用嘛?根据这两个问题的分析,本文提出了一种端到端的Image Pyramid Network,然后针对大物体在大尺度的图片上、小物体在小尺度的图片上不易识别的问题,提出了一种新颖的训练策略Scale Normalization

分类和检测的难度差异

这里写图片描述

识别数据库ImageNet中,50%的物体在图片中所占的比例为0.556,而检测数据库COCO中50%的物体在图片中所占的比例仅为0.106,在全库图片10%-90%中,物体的尺度从0.024到0.472,跨度约为20倍,可见COCO这个数据库物体尺度变化有多可怕,这就要求detector必须能处理这么多不同尺度的物体。

尺度(分辨率)对分类和检测的影响

为什么要探究这个影响呢,因为我们在检测时,训练尺度是800x1200(原图大多是480x640),而inference时为了检测小物体会使用1400x2000,但是到底这个尺度对检测的影响怎样呢,本文想仔细探究下。

尺度对分类的影响

首先想从对分类的影响出发,然后分析后想想如何把结论应用到检测中

这里写图片描述

  • 原图训练/伪高清测试(a),CNN-B是一个在224x224尺度上训练的模型, 其stride=2. 我们将测试图片降采样到[48x48, 64x64, 80x80, 96x96,128x128] 然后再放大回224x224用于测试。结果发现训/测尺度差距越大, 效果越差,说明这个训练和测试匹配还是很重要的。先降采样是为了生成小物体,然后这个时候再放大送到原来的网络测试是想看看直接吧小物体放大去测试会不会变好,结果发现会因为训练和测试尺度不一致导致变差(因为我们之前为了把小物体检测好通常在测试时直接放大图片,受限于内存训练时尺度不能太大,也会有这种训练和检测尺度不一致的情况) 。这里说的小物体就是指它的绝对像素点个数不是所占图片比例 个人感觉还可以补个实验是全部降采样到48,然后用它训练和测试,网络完全一样,然后用224训练和降采样到48的图放大到224去测试,两者对比一下,如果前者更好说明训测匹配更重,如果后者好说明测试时放大带来的好处能盖过训测不匹配带来的坏处。最后还可以和224训练224测试的结果对比,看看训测匹配时,放大图片训练和测试有木有效果
  • 低清训练/低清测试(b)(c),既然直接放大去测试不能解决小物体识别问题,那么我们能不能专门为小物体设计网络解决呢(其实也是把小物体放大后也去参与训练)?CNN-S是根据上述原则, 做一个训/测尺度匹配的实验. 选取48x48、98x98作为训/测尺度,但根据图的大小调整了原来网络的步长。结果发现训/测尺度一致后, 性能大幅提升,这说明专门为其设计网络(改变步长也算是间接放大小物体)使训练和测试尺度一致, 可以提高小物体的识别 根据这个结论,多训练几个不同结构的分类网络适应各种小尺度的图片,然后把这些结构用到检测网络中,即不同尺度的图片送到不同的检测网络(backbone是不同的分类网络)
  • 原图训练, 伪高清微调/伪高清测试(b)(c) 另一个解决小物体的做法是在原图训练的CNN-B用放大后的小物体去做微调. 结果发现CNN-B-FT的结果甚至好于CNN-S,这就说明在高分辨率图片上学习的kernel是有利于识别低分辨率的,但是一定要finetuning一下 因此以后,我们最好先把物体放大去训练然后再用和测试一致尺度的图片finetuning,这样比CNN-S那样减少步长精度要高一些呢。

就像以上讲的那样,为了提高检测效果,要么根据不同分辨率设计不同的检测网络,要么就是用一个网络适应所有分辨率。最后一个实验也说明了先在高分辨上训练再finetuning比专门为低分辨率设计网络还要好,而且现有的检测模型也都是单一框架,采用在高分辨率上训练的分类模型参数初始化,然后直接放大图片去提高小物体检测,而并没有让小物体在训练时得到finetuning

尺度对检测的影响

这里写图片描述

  • 800all vs 1400all 实验设置: 选用800x1200和1400x2000两种训练尺度, 分别记作800all和1400all. 测试时, 我们都使用1400x2000的尺度,1400all 胜出。但是为什么只超过了一点点呢? 因为在考虑小物体的分类性能而放大图片的同时, 也将中/大尺度的样本放大得太大, 导致无法正确识别.
  • 实验1400<80px 实验设置: 用了大图, 却被中/大尺寸的样本破坏了性能, 那么我们就只用小于某阈值的样本进行训练, 即在原图尺寸中>80px的样本直接抛弃, 只保留<80px的样本参与训练. 结果发现效果更差了,其根本原因是因为这种做法抛去了太多的样本(~30%), 导致训练集丰富性下降, 尤其是抛弃的那个尺度的样本.
  • MST:在Object Detection中,为了提升测试针对不同scale物体的性能,大家一般会使用Multi-scale training/testing这样的测试时融合的技巧来提升结果。但是它的效果还是和800all差不多,它与本文后续提出的SNIP做法最大的区别就在于Multi-scale的做法扩充了不同scale样本的数目,但是引入了更难的极大/极小的训练样本,仍然要求CNN去fit所有scale的物体。

Naiyan Wang: CNN中没有对于scale invariant的结构,CNN能检测不同scale的“假象”,更多是通过CNN来通过capacity来强行memorize不同scale的物体来达到的,这其实浪费了大量的capacity,而SNIP这样只学习同样的scale可以保障有限的capacity用于学习语义信息。

框架

这里写图片描述

RPN阶段

  • 用所有的GroundTruth给Anchors分配好+/-标签
  • 根据第i个尺度下的valid range: [si,ei], 将GroundTruth根据是否落在范围内分为Valid/Invalid GT
  • 去除那些IoU(anchors|InvalidGT)>0.3的Anchors

FC阶段

  • 用所有的GroundTruth给ProposalRoIs分配好类别标签
  • 弃用不在[si,ei]范围内的GT和Proposals
  • 全被剔除了的处理,那这个分辨率下图片被忽略

测试阶段

  • 用多尺度正常进行测试
  • 在合并多尺度Detection之前, 只在各个尺度留下满足其条件的Detection
  • Soft-NMS合并 (对比的其他模型有没有soft-nms?)

Sub-Image采样

训练时采用3中尺度 (480, 800), (800, 1200) and (1400,2000),但是在(1400,2000)分辨率太大了,考虑到GPU显存, 需要crop图片来满足显存局限,打算用最少数量的1000x1000的chips来囊括所有的小物体. 如果没有小物体的话, 这个图片就不参与训练了, 这样做只是为了加速训练,后续也有实验对比说明这个采样对AP没有影响


引用了一下两篇文章的很多地方,特表示感谢!
- An Analysis of Scale Invariance in Object Detection – SNIP
- CVPR18 Detection文章选介(下)