目标检测之SSD

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


一、前言

目标检测近年来已经取得了很重要的进展,主流的算法主要分为两个类型(参考RefineDet):
(1)two-stage方法
如R-CNN系算法,其主要思路是先通过启发式方法(selective search)或者CNN网络(RPN)产生一系列稀疏的候选框,然后对这些候选框进行分类与回归,two-stage方法的优势是准确度高;
(2)one-stage方法
如Yolo和SSD,其主要思路是均匀地在图片的不同位置进行密集抽样,抽样时可以采用不同尺度和长宽比,然后利用CNN提取特征后直接进行分类与回归,整个过程只需要一步,所以其优势是速度快,但是均匀的密集采样的一个重要缺点是训练比较困难,这主要是因为正样本与负样本(背景)极其不均衡(参见Focal Loss),导致模型准确度稍低。不同算法的性能如下图所示,可以看到两类方法在准确度和速度上的差异。

在这里插入图片描述


二、SSD(Single Shot MultiBox Detector)

SSD相对于YOLO的优势:

一、是SSD提取了不同尺度的特征图来做检测,大尺度特征图(较靠前的特征图)可以用来检测小物体,而小尺度特征图(较靠后的特征图)用来检测大物体;
二、是SSD采用了不同尺度和长宽比的先验框(Prior boxes, Default boxes,在Faster R-CNN中叫做锚,Anchors)。Yolo算法缺点是难以检测小目标,而且定位不准,但是这几点重要改进使得SSD在一定程度上克服这些缺点。
基本架构如下:
在这里插入图片描述
在Yolo中,每个单元预测多个边界框,但是其都是相对这个单元本身(正方块),但是真实目标的形状是多变的,Yolo需要在训练过程中自适应目标的形状。而SSD借鉴了Faster R-CNN中anchor的理念,每个单元设置尺度或者长宽比不同的先验框,预测的边界框(bounding boxes)是以这些先验框为基准的,在一定程度上减少训练难度。一般情况下,每个单元会设置多个先验框,其尺度和长宽比存在差异,如下图所示,可以看到每个单元使用了4个不同的先验框,图片中猫和狗分别采用最适合它们形状的先验框来进行训练,后面会详细讲解训练过程中的先验框匹配原则。

在这里插入图片描述

对于每个单元的每个先验框,其都输出一套独立的检测值,对应一个边界框,主要分为两个部分。
第一部分是各个类别的置信度或者评分,值得注意的是SSD将背景也当做了一个特殊的类别,如果检测目标共有 c 个类别,SSD其实需要预测 c+1 个置信度值,其中第一个置信度指的是不含目标或者属于背景的评分。后面当我们说 c 个类别置信度时,请记住里面包含背景那个特殊的类别,即真实的检测类别只有 c-1 个。在预测过程中,置信度最高的那个类别就是边界框所属的类别,特别地,当第一个置信度值最高时,表示边界框中并不包含目标。
第二部分就是边界框的location,包含4个值 (cx, cy, w, h) ,分别表示边界框的中心坐标以及宽高。但是真实预测值其实只是边界框相对于先验框的转换值:
先验框位置用 d=(d cx , d cy , d w ,d h ) 表示,其对应边界框用 b=(b cx , b cy , b w ,b h ) 表示,那么边界框的预测值 l 其实是 b 相对于 d 的转换值
在这里插入图片描述
习惯上,我们称上面这个过程为边界框的编码(encode),预测时,你需要反向这个过程,即进行解码(decode),从预测值 l 中得到边界框的真实位置 b :
在这里插入图片描述
综上所述,对于一个大小 m×n×c 的特征图m×n×c 分别宽高通道数,每个像素生成先验框数目记为 k×anchor,需要 k×4个3×3×c 的 卷积核来预测每个先验框的坐标;需要 k*(C+1)个33c的卷积核来预测每个先验框的类别。


三、SSD训练过程

膨胀卷积:

在上面的SSD基本结构图中可以看出,SSD采用VGG16做基础模型,首先VGG16是在ILSVRC CLS-LOC数据集预训练。将VGG16的
全连接层fc6和fc7转换成 33 卷积层 conv6和 11 卷积层conv7,同时将池化层pool5由原来的变成(猜想是不想reduce特征图大小),为了配合这种变化,采用了一种膨胀卷积神经网络,其实就是conv6采用扩展卷积或带孔卷积(Dilation Conv),其在不增加参数与模型复杂度的条件下指数级扩大卷积的视野,其使用扩张率(dilation rate)参数,来表示扩张的大小,如下图所示,(a)是普通的 3 3卷积,其视野就是 3 3 ,(b)是扩张率为1,此时视野变成 77 ,©扩张率为3时,视野扩大为 1515 ,但是视野的特征更稀疏了。Conv6采用 3 *3大小但dilation rate=6的扩展卷积。然后移除dropout层和fc8层,并新增一系列卷积层,在检测数据集上做finetuing。
在这里插入图片描述
训练过程

(1)先验框匹配

第一个原则:一个先验框只能匹配一个ground truth,如果多个ground truth与某个先验框 IOU大于阈值,那么先验框只与IOU最大的那个先验框进行匹配。
第二个原则一定在第一个原则之后进行,仔细考虑一下这种情况,如果某个ground truth所对应最大 IOU小于阈值,并且所匹配的先验框却与外一个ground truth的 IOU 大于阈值,那么该先验框应该匹配谁,答案应该是前者,首先要确保某个ground truth一定有一个先验框与之匹配。但是,这种情况我觉得基本上是不存在的。由于先验框很多,某个ground truth的最大 IOU}肯定大于阈值,所以可能只实施第二个原则既可以了,TensorFlow版本就是只实施了第二个原则。下图为一个匹配示意图,其中绿色的GT是ground truth,红色为先验框,FP表示负样本,TP表示正样本。
在这里插入图片描述
尽管一个ground truth可以与多个先验框匹配,但是ground truth相对先验框还是太少了,所以负样本相对正样本会很多。为了保证正负样本尽量平衡,SSD采用了hard negative mining,就是对负样本进行抽样,抽样时按照置信度误差(预测背景的置信度越小,误差越大)进行降序排列,选取误差的较大的top-k作为训练的负样本,以保证正负样本比例接近1:3。

(2)损失函数

训练样本确定了,然后就是损失函数了。损失函数定义为位置误差(locatization loss, loc)与置信度误差(confidence loss, conf)的加权和:
在这里插入图片描述
在这里插入图片描述
(3)数据扩增

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


四、SSD预测过程

预测过程比较简单,对于每个预测框,首先根据类别置信度确定其类别(置信度最大者)与置信度值,并过滤掉属于背景的预测框。然后根据置信度阈值(如0.5)过滤掉阈值较低的预测框。对于留下的预测框进行解码,根据先验框得到其真实的位置参数(解码后一般还需要做clip,防止预测框位置超出图片)。解码之后,一般需要根据置信度进行降序排列,然后仅保留top-k(如400)个预测框。最后就是进行NMS算法,过滤掉那些重叠度较大的预测框。最后剩余的预测框就是检测结果了。

性能评估
SSD与其它检测算法的对比结果(在VOC2007数据集)如表所示,基本可以看到,SSD与Faster R-CNN有同样的准确度,并且与Yolo具有同样较快地检测速度。
在这里插入图片描述