5、SSD原理(Single Shot MultiBox Detector)

主流的算法主要分为两个类型:ios

(1)tow-stagees6

R-CNN系列算法,其主要思路是先经过启发式方法(selective search)或者CNN网络(RPN)产生一些列稀疏的候选框,而后对这些候选框进行分类和回归。two-stage方法的优点是准确度高。算法

(2)one-stage网络

如YOLO和SSD,主要思路是均匀的在图片的不一样位置进行密集抽样,抽样时能够采用不一样尺度和长宽比,而后利用CNN提取特征后直接进行分类和回归,整个过程只须要一部,因此其优点是速度快。架构

均匀的密集采样的一个重要缺点是训练比较困难,这主要是由于正样本与负样本极其不平衡,致使模型准确度稍低,不一样算法的性能如图:app

SSD英文名是(Single Shot MultiBox Detector),single shot指的是SSD算法属于one-stage方法,MultiBox说明SSD是多框预测框架

上图能够看出SSD在准确度和速度(除了SSD512)上都比YOLO要好不少。dom

下图是不一样算法的基本框架图,对于Faster R-CNN,其先经过CNN获得候选框,而后再进行分类和回归,而Yolo与SSD能够一步到位完成检测。相比于YOLO,SSD采用CNN来直接进行检测,而不是像YOLO那样在全链接层以后再作检测。ide

其实采用卷积直接作检测只是SSD相比于YOLO的其中一个不一样点,另外还有两个重要的改变,一是SSD提取不一样尺度的特征图来作检测,大尺度特征图(较靠前的特征图)用来检测小物体,小尺度特征图(较靠后的特征图,感觉野大)用来检测大物体;二是SSD采用了不一样尺度和长宽比的先验框(Prior boxes, Default boxes,在Faster R-CNN中叫作锚,Anchors)。Yolo算法的缺点是难以检测小目标,并且定位不许,可是这几点重要的改进使得SSD在必定程度上克服这些缺点。函数

设计理念

SSD和YOLO都是采用一个CNN网络来进行检测,可是却采用了多尺度的特征图,其基本架构以下图,下面将SSD核心设计理念总结为如下三点:

(1)采用多尺度特征图用于检测

所谓多尺度采用大小不一样的特征图,CNN网络通常前面的特征图比较大,后面会逐渐采用stride=2的卷积或者pool来下降特征图大小,下图所示,一个比较大的特征图和一个比较小的特征图,他们都用来作检测。这样作的好处是比较大的特征图用来检测相对较小的目标,而小的特征图负责检测大目标,8x8的特征图能够划分更多的单元,可是其每一个单元的default box尺度比较小。

(2)采用卷积进行检测

与Yolo最后采用全链接层不一样,SSD直接采用卷积对不一样的特征图来进行提取检测结果。对于形状为的特征图,只须要采用这样比较小的卷积核获得检测值。

(3)设置先验框default boxes

在YOLO中,每一个单元预测多个边界框,可是其都是相对这个单元自己(正方块),可是真实目标的形状是多变的,Yolo须要在训练过程当中自适应目标的形状。而SSD借鉴了Faster R-CNN中anchor的理念,每一个单元设置尺度或者长宽比不一样的default boxes预测的边界框(bounding boxes)是以这些先验框为基准的,在必定程度上减小训练难度。

通常状况下,每一个单元会设置多个default boxes,其尺度和长宽比存在差别,以下图所示,能够看到每一个单元使用了4个不一样的default boxes,图片中猫和狗分别采用最适合它们形状的先验框来进行训练,后面会详细讲解训练过程当中的先验框匹配原则。

SSD的检测值也与YOLO不太同样,对于每一个单元cell的每一个先验框default box,其都输出一套独立的检测值,对于一个bouding box,主要分为两个部分:

  • 第一个部分是各个类别的置信度或者评分
    • 值得注意的是SSD将背景也当作了一个特殊的类别,若是检测目标共有c个类别,SSD其实须要预测c+1个置信度值,其中第一个置信度是不含目标或者属于背景的评分。后面当咱们说c个类别置信度时,请记住里面包含背景那个特殊的类别,即真实的检测类别只有c-1个。
    • 在预测过程当中,置信度最高的那个类别就是边界框所属的类别。特别的,当第一个置信度最高时,表示边界框中并不包含目标。
  • 第二个部分就是边界框的location,包含4个值,分别表示边界框的中心坐标以及宽高。可是真实预测其实只是预测边界框相对于先验框的转换值(offset)
    • 先验框(anchor)位置用表示,其对应预测的边界框表示,那么边界框的预测值l实际上是b相对于d的转换值:

习惯上,咱们称上面这个过程为边界框的编码(encode),预测时,你须要反向这个过程,即进行解码(decode),从预测值l中获得边界框的真实值b:

然而,在SSD的caffe源码实现中还有trick,那就是设置variance超参数来调整检测值,经过bool参数variance_encoded_in_target来控制两种模式。当其为true时,表示variance(方差)被包含在预测值中,就是上面那种状况,若是是false(大部分采用这种方式,训练更容易),就须要手动设置超参数variance,用来对l的4个值进行放缩,此时边界框须要这样解码:

综上所述,对于一个大小的特征图,共有m x n 个单元,每一个单元设置的先验框数目记为k,那么每一个单元共须要个预测值,全部的单元共须要个预测值,因为SSD采用卷积作检测,因此就须要个卷积核来完成这个特征图的检测过程。(卷积核参数共享)。

网络结构

SSD采用VGG16做为基础模型,而后在VGG16的基础上新增了卷几层来得到更多的特征图以用于检测。SSD网络结构如图所示:

很明显能够看出SSD利用了多尺度的特征图作检测,模型的输入图片大小是(还能够是),其与前者网络结构没有差异,只是最后新增一个卷积层。

采用VGG16作基础模型,首先VGG16是在ILSVRC CLS-LOC数据集预训练。而后借鉴了DeepLab-LargeFOV,分别将VGG16的全链接层fc6和fc7转换成 3\times3 卷积层 conv6和 1\times1 卷积层conv7,同时将池化层pool5由原来的stride=2的 2\times 2 变成stride=1的 3\times 3 (猜测是不想reduce特征图大小),为了配合这种变化,采用了一种Atrous Algorithm,其实就是conv6采用扩展卷积或带孔卷积(Dilation Conv),其在不增长参数与模型复杂度的条件下指数级扩大卷积的视野,其使用扩张率(dilation rate)参数,来表示扩张的大小,以下图6所示,(a)是普通的 3\times3 卷积,其视野就是 3\times3 ,(b)是扩张率为1,此时视野变成 7\times7 ,(c)扩张率为3时,视野扩大为 15\times15 ,可是视野的特征更稀疏了。Conv6采用 3\times3 大小但dilation rate=6的扩展卷积。

 

而后移除dropout层和fc8层,并新增一系列卷积层,在检测数据集上作finetuing。

其中VGG16中的Conv4_3层将做为用于检测的第一个特征图。conv4_3层特征图大小是 38\times38 ,可是该层比较靠前,其norm(范数)较大,因此在其后面增长了一个L2 Normalization层(参见ParseNet),以保证和后面的检测层差别不是很大,这个和Batch Normalization层不太同样,其仅仅是对每一个像素点在channle维度作归一化,而Batch Normalization层是在[batch_size, width, height]三个维度上作归一化。归一化后通常设置一个可训练的放缩变量gamma,使用TF能够这样简单实现:

1 # l2norm (not bacth norm, spatial normalization)
2 def l2norm(x, scale, trainable=True, scope="L2Normalization"):
3     n_channels = x.get_shape().as_list()[-1]
4     l2_norm = tf.nn.l2_normalize(x, [3], epsilon=1e-12)
5     with tf.variable_scope(scope):
6         gamma = tf.get_variable("gamma", shape=[n_channels, ], dtype=tf.float32,
7                                 initializer=tf.constant_initializer(scale),
8                                 trainable=trainable)
9         return l2_norm * gamma

从后面新增的卷积层中提取Conv7,Conv8_2,Conv9_2,Conv10_2,Conv11_2做为检测所用的特征图,加上Conv4_3层,共提取了6个特征图,其大小分别是 (38, 38), (19, 19), (10, 10), (5, 5), (3, 3), (1, 1) ,可是不一样特征图单元cell设置的先验框数目不一样同一个特征图上每一个单元设置的先验框是相同的,这里的数目指的是一个单元的先验框数目)。先验框的设置,包括尺度(或者说大小)和长宽比两个方面。对于先验框的尺度,其遵照一个线性递增规则:随着特征图大小下降,先验框尺度线性增长

每个feature map中的每个小格子(cell)都包含多个default box,同时每一个box对应loc(位置坐标)和conf(每一个种类的得分)。

default box长宽比例默认有四个六个:

四个default box是长宽比(aspect ratios)为(1:1)、(2:1)、(1:2)、(1:1);六个则是添加了(1:3)、(3:1)

为何会有两个(1:1)呢。这时候就要讲下论文中Choosing scales and aspect ratios for default boxes这段内容了。做者认为不一样的feature map应该有不一样的比例(一个大框一个小框,长宽比相同,大框是指不一样feature map 相对于原图的尺寸比例不一样),这是什么意思呢,表明的是default box中这个1在原图中的尺寸是多大的,计算公式以下所示:

Sk即表明在300*300输入中的比例,表示先验框大小相对于图片的比例

m为当前的feature map是第几层;   m=5,由于一共有6个feature map,可是第一层(Conv4_3层)是单独设置的

k表明的是一共有多少层的feature map

Smin和Smax表明的是第一层和最后一层所占的比例,比例的最小值和最大值,在ssd300中为0.2-0.9。

计算:

第一个feature map 是 conv4_3:默认设置比例为0.2/2=0.1, 此时k=1

第二个feature map 是 conv7: k=2,s = 0.2 +(0.7/4) x (2-1) =0.375 ,最后300x0.375 = 112.5,这个就是在这个feature map中比例为1的这个default box 的尺寸相对于原图300x300 的大小。

为何default box的size有两个1吗?

做者在这有引入了一个s'_{k}=\sqrt{s_k s_{k+1}},也就是每一个特征图都设置了两个长宽比为1大小不一样的正方形default box。有的小伙伴可能会有疑问,这有了Sk+1则须要多出来一部分的Sk啊,是的没错,最后一个特征图须要参考s_{m+1}=300\times105/100=315来计算s'_{m},所以每一个特征图(的每一个cell)都有6个default box\{1,2,3,\frac{1}{2},\frac{1}{3},1'\}aspect ratios),可是在实现时, Conv4_3,Conv10_2,Conv11_2仅仅使用4个先验框(default box),不使用长宽比为3,1/3的先验框(default box)。做者的代码中就添加了两层,第一层取0.1最后一层取1

注:对于第一个特征图,先验框(default box)的尺度比例通常s_{min}/2=0.1,则尺度为300x0.1=30。

对于后面的特征图,先验框尺度比例按照上面公式线性增长,先将尺度比例放大100倍,而后再计算获得Sk,而后再将Sk除以100,再乘以图片大小,就能够获得各个特征图的先验框的size30,60,111, 162,213,264

那么S怎么用呢?按以下方式计算先验框的宽高(这里的Sk是上面求得的各个特征图的先验框的实际size,再也不是尺度比例):

w^a_{k}=s_k\sqrt{a_r},\space h^a_{k}=s_k/\sqrt{a_r}

ar表明的是以前提到的default box(aspect ratios)比例,即a_r\in \{1,2,3,\frac{1}{2},\frac{1}{3}\}

对于default box中心点的值取值为:

(\frac{i+0.5}{|f_k|},\frac{j+0.5}{|f_k|}),i,j\in[0, |f_k|)

其中i,j表明在feature map中的水平和垂直的第几格

fk表明的是feature map的size

每一个单元的先验框中心点分布在各单元的中心

获得特征图后,须要对特征图进行卷积获得检测结果,下图给出了一个5x5大小的特征图检测过程:

Priorbox是获得先验框,生成规则前面已经讲了。

检测值包含两个部分:类别置信度和边界框位置,各采用一次3x3卷积来进行完成。

n_k是该特征图所采用的先验框数目,那么类别置信度须要的卷积核数量为n_k\times c,而边界框位置须要的卷积核数量为n_k\times 4。因为每一个先验框都会预测一个边界框,因此SSD300一共能够预测

    Conv4_3  获得的feature map大小为38*38:38*38*4 = 5776

  Conv7      获得的feature map大小为19*19:19*19*6 = 2166

  Conv8_2  获得的feature map大小为10*10:10*10*6 = 600

  Conv9_2  获得的feature map大小为5 * 5  :5 * 5 * 6 = 150

  Conv10_2获得的feature map大小为3 * 3  :3 * 3 * 4 = 36

  Conv11_2获得的feature map大小为1 * 1  :1 * 1 * 4 = 4

  最后结果为:8732

38\times38\times4+19\times19\times6+10\times10\times6+5\times5\times6+3\times3\times4+1\times1\times4=8732 个边界框,这是一个至关庞大的数字,因此说SSD本质上是密集采样。

训练过程

(1)先验框匹配

在训练过程当中,首先要肯定训练图片中的ground truth(真实目标)与哪一个先验框来进行匹配,与之匹配的先验框所对应的边界框将负责预测它

Yolo中,ground truth的中心落在哪一个单元格,该单元格中与其IOU最大的边界框负责预测它。

SSD中,先验框与ground truth的匹配原则又两点:

一、每一个ground truth找到与其IOU最大的先验框,互相匹配。该先验框称为正样本(先验框对应的预测box)

如有个先验框没有与ground truth匹配,就只能与背景匹配,就是负样本。(一个图片中ground truth少,但先验框多,这样匹配,不少先验框会是负样本,正负样本不均衡)。

二、对剩余未匹配先验框,若某个ground truth的IOU大于某个阈值(通常是0.5),那么该先验框也与这个ground truth进行匹配。

   这样ground truth可能与多个先验框匹配

FP:负样本       TP:正样本

尽管一个ground truth能够与多个先验框匹配,可是ground truth相对于先验框仍是太少了,因此负样本会不少。为保证正负样本尽可能均衡,SSD采用了hard negative mining,先将每个物体位置上对应 predictions(default boxes)是 negative 的 boxes 进行排序,按照 default boxes 的 confidence 的大小。 选择最高的几个,保证最后 negatives、positives 的比例接近3:1

(2)损失函数

损失函数定义为位置偏差(locatization loss, loc)与置信度偏差(confidence loss, conf)的加权和:

L(x, c, l, g) = \frac{1}{N}(L_{conf}(x,c) + \alpha L_{loc}(x,l,g))

其中 N 是先验框的正样本数量。

这里 x^p_{ij}\in \{ 1,0 \} 为一个指示参数,当 x^p_{ij}= 1 时表示第 i 个先验框与第 j 个ground truth匹配,而且ground truth的类别为 p 。

 c 为类别置信度预测值。

 l 为先验框的所对应边界框的位置预测值

 g 是ground truth的位置参数

对于位置偏差,其采用Smooth L1 loss,定义以下:

因为 x^p_{ij} 的存在,因此位置偏差仅针对正样本进行计算。值得注意的是,要先对ground truth的 g 进行编码获得 \hat{g} ,由于预测值 l 也是编码值,若设置variance_encoded_in_target=True,编码时要加上variance:

\hat{g}^{cx}_j = (g^{cx}_j - d^{cx}_i)/d^w_i/variance[0], \hat{g}^{cy}_j = (g^{cy}_j - d^{cy}_i)/d^h_i/variance[1]

\hat{g}^{w}_j = \log(g^{w}_j/d^w_i)/variance[2], \space \hat{g}^{h}_j = \log(g^{h}_j/d^h_i)/variance[3]

 对于置信度偏差,其采用softmax loss:

权重系数 \alpha 经过交叉验证设置为1。

(3)数据扩增

采用数据扩增(Data Augmentation)能够提高SSD的性能,主要采用的技术有水平翻转(horizontal flip)随机裁剪加颜色扭曲(random crop & color distortion)随机采集块域(Randomly sample a patch)(获取小目标训练样本),以下图所示:

 

预测过程

肯定预测框类别(置信度最大者)与置信度值,而且过滤掉属于背景的预测框,过滤掉置信度阈值较低的预测框;

对留下的预测框进行编码,获得真实的位置参数(解码后还须要clip,防止预测框位置超出图片);

解码以后,根据置信度进行降序排列,保留top-k个预测框;

进行NMS算法,过滤掉那些重叠度比较大的预测框,最后剩余的预测框就是检测结果了。

性能评估

首先总体看一下SSD在VOC2007,VOC2012及COCO数据集上的性能,如表1所示。相比之下,SSD512的性能会更好一些。加*的表示使用了image expansion data augmentation(经过zoom out来创造小的训练样本)技巧来提高SSD在小目标上的检测效果,因此性能会有所提高。

SSD与其它检测算法的对比结果(在VOC2007数据集)如表2所示,基本能够看到,SSD与Faster R-CNN有一样的准确度,而且与Yolo具备一样较快地检测速度。

文章还对SSD的各个trick作了更为细致的分析,表3为不一样的trick组合对SSD的性能影响,从表中能够得出以下结论:

    • 数据扩增技术很重要,对于mAP的提高很大;
    • 使用不一样长宽比的先验框能够获得更好的结果;

 

一样的,采用多尺度的特征图用于检测也是相当重要的,这能够从表4中看出:

 

 补充

一、L2 normalization

二、hard nevigating mining

相关文章
相关标签/搜索