SSD-学习笔记

Reference:https://blog.csdn.net/jy001227801/article/details/80388192

                    https://blog.csdn.net/a8039974/article/details/77592395

SSD具有如下主要特点:

  1. 从YOLO中继承了将detection转化为regression的思路,同时一次即可完成网络训练
  2. 基于Faster RCNN中的anchor,提出了相似的prior box;
  3. 加入基于特征金字塔(Pyramidal Feature Hierarchy)的检测方式,相当于半个FPN思路

算法概述:

ssd算法是一种直接预测目标类别和bounding box的多目标检测算法。与传统的faster rcnn相比,该算法没有生成 region proposal 的过程,因此极大提高了检测速度。

ssd算法的结构如下:

  1. SSD模型的第一环节是特征提取。特征提取可以采用主流的一些卷积模型(如VGG,Inception等),特征提取时的不同卷积层feature map的输出将同时送到到下一环节”检测“。
  2. SSD模型的第二环节是检测SSD使用低层feature map检测小目标,使用高层feature map检测大目标。检测环节采用一系列的小卷积模块(3*31*1)来预测物体的类别与坐标。由于上一层输入的不同层数的feature map有不同的感受野,因此检测环节可以认为是对不同尺寸的图像进行回归和分类。检测环节可以细分成如下几个子模块。

    • box generator: 针对不同卷积层(如19*1910*10)的feature map cell(feature map中的每个小格子),产生不同尺寸(scale)、不同纵横比(aspect ratios)的default boxes。
    • classification: 上述的default boxes通过classification预测对应feature map cell的类别(C+1类别, C为所有分类,1为背景)
    • localization:上述的default boxes通过localization预测对应feature map cell的坐标
  3. SSD模型的第三环节是损失计算。该环节主要用于训练过程,损失函数包括Classification lossLocalization losses。通过损失的最小化,缩短Classification 和Localization的预测误差。
  4. SSD模型的第四环节是后处理。 该环节主要用于验证过程,通过NMS(非极大值抑制)筛选出置信度最高、存在目标的区域。

注:后文出现的default box和anchor, anchor box的意思均指同一个box。


Box generator:

SSD是特征图上的每一个点对应一组预选框。然后每一层中每一个点对应的prior box的个数由PriorBox这一层的配置文件决定的。拿conv4-3对应的priorbox来说,caffe的模型配置文件如下:

SSD生成对应的四个priorbox框的生成过程:

  1. 以feature map上每个点的中点为中心(offset=0.5),生成一些列同心的prior box(然后中心点的坐标会乘以step,相当于从feature map位置映射回原图位置)
  2. 先以 min_size为宽高生成一个框。(第一个)
  3. 如果存在max_size则用sqrt(min_size_ * max_size_),生成一个框。(第二个)
  4. 然后根据 aspect_ratio,再去生成。如上面的配置文件,aspect_ratio=2,那么会自动的再添加一个aspect_ratiod = 1/2,然后根据下面的计算方法:


         分别生成两个框,一个对应 ar = 2 一个对应 ar= 1/2(第三个、第四个)

总结:

min_size和max_size会分别生成一个正方形的框,aspect_ratio参数会生成2个长方形的框。

所以输出框的个数 :prior_box_num = count(min_size)*1+count(max_size)*1+count(aspect_ratio)*2

注:min_size是必须要有的参数,否则不会进入对应的框的生成过程。

       还有一个比较关键的参数,就是step,在conv4-3中设置为8,这个又是怎么来的呢?还是用一个表来看一下:

nameOut_sizeCal_scaleReal_scale
conv4-338x387.88
fc719x1915.7816
conv5-210x103032
conv7-25x56064
conv8-23x3100100
conv9-21x1300300

Cal_scale = 300/out_size实际就是原图与特征图大小的比值,比如conv4-3 width = 38 ,输入的大小为300,那么scale=7.8,所以这里设置的step=8。代码中实现如下:

这一部分的计算过程可以在 prior_box_layer.cpp的Forward_cpu中看到。


Classification & Localization:

从上图可以看到,在conv4_3 feature map网络pipeline分为了3条线路:

 

后续通过softmax分类+bounding box regression即可从priox box中预测到目标。其实pribox box的与Faster RCNN中的anchor非常类似,都是目标的预设框,没有本质的差异。区别是每个位置的prior box一般是4~6个,少于Faster RCNN默认的9个anchor;同时prior box是设置在不同尺度的feature maps上的,而且大小不同。

  1. 经过一次batch norm+一次卷积后,生成了[1, num_class*num_priorbox, layer_height, layer_width]大小的feature用于softmax分类目标和非目标(其中num_class是目标类别,SSD 300中num_class = 21)。
  2. 经过一次batch norm+一次卷积后,生成了[1, 4*num_priorbox, layer_height, layer_width]大小的feature用于bounding box regression(即每个点一组[dxmin,dymin,dxmax,dymax])就是偏移量
  3. 生成了[1, 2, 4*num_priorbox]大小的prior box blob,其中2个channel分别存储prior box的4个点坐标和对应的4个variance

还有一个细节就是上面prototxt中的4个variance,这实际上是一种bounding regression中的权重。在上图线路(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()函数见到。

Permute,Flatten And Concat

SSD 300是使用包括conv4_3在内的共计6个feature maps一同检测出最终目标的。在网络运行的时候显然不能像图6一样:一个feature map单独计算一次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  
  }  
}  

注:使用CAFFE的同学都知道 ,CAFFE的数据结构是 NCHW的形式(N:样本个数, C:通道数,H:高,W:宽),而SSD的 XX_conf 和 XX_loc层的输出,是用通道来保存特征向量的,所以这里需要将通道数调整到最后,也就是 permute所做的事情,通过该层后,数据的顺序被换成了 NHWC,再通过 flatten拉成一列。如下图所示:

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]

上展示了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_confchannel值为num_priorbox * num_class = 4 * 21 = 84;而每个prior box都要回归出4个位置变换量,所以conv4_3_norm_mbox_locchannel值为4 * 4 = 16
  • fc7每个点有6个prior box,其他feature map同理。
  • 经过一系列图7展示的caffe blob shape变化后,最后拼接成mbox_confmbox_loc。而mbox_conf后接reshape,再进行softmax(为何在softmax前进行reshape,Faster RCNN有提及)。
  • 最后这些值输出detection_out_layer,获得检测结果。

总结:

SSD的最后几层的输出信息都是保存在Channel这一维度的,而一个LOC+CONF+PRIOR的模块可以认为等效于一个 Faster-rcnn的最后的回归+分类过程,通过将这些子模块的特征拼接起来,得到一组特征向量,达到提取多尺度特征的目的(多个F-RCNN同时工作于同一图片的不同尺度上)。


Loss:

损失函数定义为位置误差(locatization loss, loc)与置信度误差(confidence loss, conf)的加权和。也可以说是:三部分的loss:前景分类的loss、背景分类的loss、位置回归的loss。

  • 公式中Lconf (x,c)是前景的分类loss和背景的分类loss的和Lloc (x,l,g)是所有用于前景分类的anchor的位置坐标的回归loss
  • 公式里的N表示被选择用作前景分类的anchor的数目
  • 在源码中把IOU>0.5的anchor都用于前景分类,在IOU<0.5的anchor中选择部分用作背景分类。
  • 只选择部分的原因是背景anchor的数目一般远远大于前景anchor,如果都选为背景,就会弱化前景loss的值,造成定位不准确。在作者源码中背景分类的anchor数目定为前景分类anchor数的三倍来保持它们的平衡。
  • 权重系数α通过交叉验证设置为1

confidence loss是典型的softmax loss:

其中,当xpij=1时表示第i个先验框与第j个ground truth匹配,并且ground truth的类别为p。c为类别置信度预测值.

location loss是典型的smooth L1 loss:

l为先验框的所对应边界框的位置预测值,而g是ground truth的位置参数

总结:

整个loss的选取如下图,这只是个示意图,每个点的anchor被定死成了6个来方便演示,实际应用时不同层级是不一样的:


Train:

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

  • 首先,寻找与每一个ground truth box有最大的IoU的default box,这样就能保证每一个groundtruth box与唯一的一个default box对应起来。
  • 然后,又将剩余还没有配对的default box与任意一个groundtruth box尝试配对,只要两者之间的IoU大于阈值(SSD 300 阈值为0.5),就认为match。
  • 显然配对到GT的default box就是positive,没有配对到GT的default box就是negative。

数据增强

SSD训练过程中使用的数据增强对网络性能影响很大,大约有6.7%的mAP提升。

(1) 随机剪裁:采样一个片段,使剪裁部分与目标重叠分别为0.1, 0.3, 0.5, 0.7, 0.9,剪裁完resize到固定尺寸。

(2) 以0.5的概率随机水平翻转。

是否在基础网络部分的conv4_3进行检测

基础网络部分特征图分辨率高,原图中信息更完整,感受野较小,可以用来检测图像中的小目标,这也是SSD相对于YOLO检测小目标的优势所在。增加对基础网络conv4_3的特征图的检测可以使mAP提升4%。

使用瘦高与宽扁默认框

数据集中目标的开关往往各式各样,因此挑选合适形状的默认框能够提高检测效果。作者实验得出使用瘦高与宽扁默认框相对于只使用正方形默认框有2.9%mAP提升。

使用atrous卷积

通常卷积过程中为了使特征图尺寸特征图尺寸保持不变,通过会在边缘打padding,但人为加入的padding值会引入噪声,因此,使用atrous卷积能够在保持感受野不变的条件下,减少padding噪声,关于atrous参考。本文SSD训练过程中并且没有使用atrous卷积,但预训练过程使用的模型为VGG-16-atrous,意味着作者给的预训练模型是使用atrous卷积训练出来的。使用atrous版本VGG-16作为预训模型比较普通VGG-16要提高0.7%mAP。

Hard negative mining

值得注意的是,一般情况下negative default boxes数量>>positive default boxes数量,直接训练会导致网络过于重视负样本,从而loss不稳定。在训练时会依据confidience score排序default box,挑选其中confidience高的box进行训练,控制positive:negative=1:3。这样会有更快的收敛和更稳定的结果。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值