目标检测ssd--2016

pytorch玩转深度学习

共 6834字,需浏览 14分钟

 ·

2021-04-06 15:57

SSD,全称Single Shot MultiBox Detector,是Wei Liu在ECCV 2016上提出的一种目标检测算法,截至目前是主要的检测框架之一,相比Faster RCNN有明显的速度优势,相比YOLO又有明显的mAP优势(不过已经被CVPR 2017的YOLO9000超越)。

图1 速度对比

SSD具有如下主要特点:

  • 从YOLO中继承了将detection转化为regression的思路,一次完成目标定位与分类

  • 基于Faster RCNN中的Anchor,提出了相似的Prior box;

  • 加入基于特征金字塔(Pyramidal Feature Hierarchy)的检测方式,即在不同感受野的feature map上预测目标

本文接下来都以SSD 300为例进行分析。

1 SSD300网络结构

图2 SSD300/YOLO网络结构对比

上图2是原论文中的SSD300与YOLO网络结构图。位什么要把SSD与YOLO对比呢?因为截止到目前目标检测分为了2种主流框架:

  • Two stages:以Faster RCNN为代表,即RPN网络先生成proposals目标定位,再对proposals进行classification+bounding box regression完成目标分类。

  • Single shot:以YOLO/SSD为代表,一次性完成classification+bounding box regression。

那么来看同为Single shot方式的SSD/YOLO区别:

  • YOLO在卷积层后接全连接层,即检测时只利用了最高层Feature maps(包括Faster RCNN也是如此)

  • SSD采用金字塔结构,即利用了conv4-3/conv-7/conv6-2/conv7-2/conv8_2/conv9_2这些大小不同的feature maps,在多个feature maps上同时进行softmax分类和位置回归

  • SSD还加入了Prior box

对比如图3。

图3 单层feature map预测和特征金字塔预测对比

2 Prior Box

在SSD300中引入了Prior Box,实际上与Faster RCNN Anchor非常类似,就是一些目标的预选框,后续通过classification+bounding box regression获得真实目标的位置。

SSD按照如下规则生成prior box:

  • 以feature map上每个点的中点为中心,生成一些列同心的prior box

  • 正方形prior box最小边长为和最大边长为:

  • 每在prototxt设置一个aspect ratio,会生成2个长方形,长宽为:

图4 prior box
  • 而每个feature map对应prior box的min_size和max_size由以下公式决定:

公式中的  是指进行预测时使用feature map的数量,如SSD300使用conv4-3等6个feature maps进行预测,所以  。同时原文设定 , 。

那么:

  • 对于conv4-3:  ,  , 

  • 对于conv-7: ,  , 

  • ....

显然可以用上述公式推导出每个feature maps使用的Prior Box size。但是在SSD300中prior box设置并不能完全和上述公式对应:

不过依然可以看出:SSD使用感受野小的feature map检测小目标,使用感受野大的feature map检测更大目标

更具体一点,来看SSD300在conv4_3层的Prior Box设置conv4_3生成prior box的conv4_3_norm_priorbox层prototxt定义如下,可以清晰的看到  和  以及  等值。

layer {
name: "conv4_3_norm_mbox_priorbox"
type: "PriorBox"
bottom: "conv4_3_norm"
bottom: "data"
top: "conv4_3_norm_mbox_priorbox"
prior_box_param {
min_size: 30.0
max_size: 60.0
aspect_ratio: 2
flip: true
clip: false
variance: 0.1
variance: 0.1
variance: 0.2
variance: 0.2
step: 8
offset: 0.5
}
}

知道了priorbox如何产生,接下来分析prior box如何使用。这里还是以conv4_3分析。

图5

从图5可以看到,在conv4_3网络分为了3条线路:

  1. 经过一次batch norm+一次卷积后,生成了[1, num_class*num_priorbox, layer_height, layer_width]大小的feature用于softmax分类目标和非目标(其中num_class是目标类别,SSD300中num_class = 21,即20个类别+1个背景)

  2. 经过一次batch norm+一次卷积后,生成了[1, 4*num_priorbox, layer_height, layer_width]大小的feature用于bounding box regression(即每个点一组[dxmin,dymin,dxmax,dymax],参考Faster R-CNN 2.5节)

  3. 生成了[1, 2, 4*num_priorbox*layer_height*layer_width]大小的prior box blob,其中2个channel分别存储prior box的4个点坐标(x1, y1, x2, y2)和对应的4个参数variance

后续通过softmax分类判定Prior box是否包含目标,然后再通过bounding box regression即可可获取目标的精确位置,熟悉Faster RCNN的读者应该对上述过程应该并不陌生。其实pribox box的与Faster RCNN中的anchor非常类似,都是目标的预设框,没有本质的差异。区别是每个位置的prior box一般是4~6个,少于Faster RCNN默认的9个anchor;同时prior box是设置在不同尺度的feature maps上的,而且大小不同。

还有一个细节就是上面prototxt中的4个variance,这实际上是一种bounding regression中的权重。在图4线路(2)中,网络输出[dxmin,dymin,dxmax,dymax],即对应下面代码中bbox;然后利用如下方法进行针对prior box的位置回归:

decode_bbox->set_xmin(
prior_bbox.xmin() + prior_variance[0] * bbox.xmin() * prior_width);
decode_bbox->set_ymin(
prior_bbox.ymin() + prior_variance[1] * bbox.ymin() * prior_height);
decode_bbox->set_xmax(
prior_bbox.xmax() + prior_variance[2] * bbox.xmax() * prior_width);
decode_bbox->set_ymax(
prior_bbox.ymax() + prior_variance[3] * bbox.ymax() * prior_height);

上述代码可以在SSD box_utils.cpp的void DecodeBBox()函数见到。

3 SSD的数据流

对于新学习SSD的人,肯定有一个很大的困惑,就是这么多feature maps和Prior Box,如何组合在一起进行forwards/backwards。本节专门介绍SSD的数据流动方式,也许有点难。但是只有了解SSD的数据流动方式才能真的理解。

图6

上一节以conv4_3 feature map分析了如何检测到目标的真实位置,但是SSD 300是使用包括conv4_3在内的共计6个feature maps一同检测出最终目标的。在网络运行的时候显然不能像图6一样:一个feature map单独计算一次multiclass softmax socre+box regression(虽然原理如此,但是不能如此实现)。

那么多个feature maps如何协同工作?这时候就要用到Permute,Flatten和Concat这3种层了。其中conv4_3_norm_conf_perm的prototxt定义如下:

layer {
name: "conv4_3_norm_mbox_conf_perm"
type: "Permute"
bottom: "conv4_3_norm_mbox_conf"
top: "conv4_3_norm_mbox_conf_perm"
permute_param {
order: 0
order: 2
order: 3
order: 1
}
}

Permute是SSD中自带的层,上面conv4_3_norm_mbox_conf_perm的的定义。Permute相当于交换caffe blob中的数据维度。在正常情况下caffe blob的顺序为:

bottom blob = [batch_num, channel, height, width]

经过conv4_3_norm_mbox_conf_perm后的caffe blob为:

top blob = [batch_num, height, width, channel]

而Flattlen和Concat层都是caffe自带层,请参照caffe official documentation理解。

图7 SSD中部分层caffe blob shape变化

那么接下来以conv4_3和fc7为例分析SSD是如何将不同size的feature map组合在一起进行prediction。图7展示了conv4_3和fc7合并在一起的过程中caffe blob shape变化(其他层类似,考虑到图片大小没有画出来,请脑补)。

  • 对于conv4_3 feature map,conv4_3_norm_priorbox(priorbox层)设置了每个点共有4个prior box。由于SSD 300共有21个分类,所以conv4_3_norm_mbox_conf的channel值为num_priorbox * num_class = 4 * 21 = 84;而每个prior box都要回归出4个位置变换量,所以conv4_3_norm_mbox_loc的caffe blob channel值为4 * 4 = 16。

  • fc7每个点有6个prior box,其他feature map同理。

  • 经过一系列图7展示的caffe blob shape变化后,最后拼接成mbox_conf和mbox_loc。而mbox_conf后接reshape,再进行softmax(为何在softmax前进行reshape,Faster RCNN有提及)。

  • 最后这些值输出detection_out_layer,获得检测结果

可以看到,SSD一次判断priorbox到底是背景 or 是20种目标类别之一,相当于将Faster R-CNN的RPN与后续proposal再分类进行了整合。

图8 SSD300


4 SSD网络结构优劣分析

SSD算法的优点应该很明显:运行速度可以和YOLO媲美,检测精度可以和Faster RCNN媲美。除此之外,还有一些鸡毛蒜皮的优点,不解释了。这里谈谈缺点:

  1. 需要人工设置prior box的min_size,max_size和aspect_ratio值。网络中prior box的基础大小和形状不能直接通过学习获得,而是需要手工设置。而网络中每一层feature使用的prior box大小和形状恰好都不一样,导致调试过程非常依赖经验。

  2. 虽然采用了pyramdial feature hierarchy的思路,但是对小目标的recall依然一般,并没有达到碾压Faster RCNN的级别。作者认为,这是由于SSD使用conv4_3低级feature去检测小目标,而低级特征卷积层数少,存在特征提取不充分的问题。

5 SSD训练过程

对于SSD,虽然paper中指出采用了所谓的“multibox loss”,但是依然可以清晰看到SSD loss分为了confidence loss和location loss(bouding box regression loss)两部分,其中N是match到GT(Ground Truth)的prior box数量;而α参数用于调整confidence loss和location loss之间的比例,默认α=1。SSD中的confidence loss是典型的softmax loss:

其中

代表第i个prior box匹配到了第j个class为p类别的GT box;而location loss是典型的smooth L1 loss:

Matching strategy:

在训练时,groundtruth boxes 与 default boxes(就是prior boxes) 按照如下方式进行配对:

  • 首先,寻找与每一个ground truth box有最大的jaccard overlap的default box,这样就能保证每一个groundtruth box与唯一的一个default box对应起来(所谓的jaccard overlap就是IoU,如图9)。

  • SSD之后又将剩余还没有配对的default box与任意一个groundtruth box尝试配对,只要两者之间的jaccard overlap大于阈值,就认为match(SSD 300 阈值为0.5)。

  • 显然配对到GT的default box就是positive,没有配对到GT的default box就是negative。

图9 jaccard overlap

Hard negative mining:

值得注意的是,一般情况下negative default boxes数量>>positive default boxes数量,直接训练会导致网络过于重视负样本,从而loss不稳定。所以需要采取:

  • 所以SSD在训练时会依据confidience score排序default box,挑选其中confidence高的box进行训练,控制 

Data augmentation:

数据增广。即对每一张image进行如下之一变换获取一个patch进行训练:

  • 直接使用原始的图像(即不进行变换)

  • 采样一个patch,保证与GT之间最小的IoU为:0.1,0.3,0.5,0.7 或 0.9

  • 完全随机的采样一个patch

图10 Random crop

同时在原文中还提到:

  • 采样的patch占原始图像大小比例在  之间

  • 采样的patch的长宽比在  之间

  • 当 Ground truth box中心恰好在采样的patch中时,保留整个GT box

  • 最后每个patch被resize到固定大小,并且以0.5的概率随机的水平翻转

最终以这些处理好的patches进行训练。

其实Matching strategy,Hard negative mining,Data augmentation,都是为了加快网络收敛而设计的。尤其是Data augmentation,翻来覆去的randomly crop,保证每一个prior box都获得充分训练而已。后续有Focal loss解决这个问题。


浏览 41
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报