背景
SSD,全称Single Shot MultiBox Detector,是Wei Liu在ECCV 2016上提出的一种目标检测算法,截至目前是主要的检测框架之一,相比Faster RCNN有明显的速度优势,相比YOLO又有明显的mAP优势(不过已经被CVPR 2017的YOLO9000超越)。不同算法的性能如图所示,可以看到两类方法在准确度和速度上的差异。
相比Yolo,SSD采用CNN来直接进行检测,而不是像Yolo那样在全连接层之后做检测。其实采用卷积直接做检测只是SSD相比Yolo的其中一个不同点,另外还有两个重要的改变,一是SSD提取了不同尺度的特征图来做检测,大尺度特征图(较靠前的特征图)可以用来检测小物体,而小尺度特征图(较靠后的特征图)用来检测大物体;二是SSD采用了不同尺度和长宽比的先验框(Prior boxes, Default boxes,在Faster R-CNN中叫做锚,Anchors)。
设计理念
SSD和Yolo一样都是采用一个CNN网络来进行检测,但是却采用了多尺度的特征图,其基本架构如图所示。下面将SSD核心设计理念总结为以下三点:
采用多尺度特征图用于检测
所谓多尺度就是采用大小不同的特征图,CNN网络一般前面的特征图比较大,后面会逐渐采用stride=2的卷积或者pool来降低特征图大小,这正如上图所示,一个比较大的特征图和一个比较小的特征图,它们都用来做检测。这样做的好处是比较大的特征图来用来检测相对较小的目标,而小的特征图负责检测大目标。
采用卷积进行检测
与Yolo最后采用全连接层不同,SSD直接采用卷积对不同的特征图来进行提取检测结果。对于形状为mnp的特征图,只需要采用33p这样比较小的卷积核得到检测值。
设置先验框(先验框也就是预测框)
在Yolo中,每个单元预测多个边界框,但是其都是相对这个单元本身(正方块),但是真实目标的形状是多变的,Yolo需要在训练过程中自适应目标的形状。而SSD借鉴了Faster R-CNN中anchor的理念,每个单元设置尺度或者长宽比不同的先验框,预测的边界框(bounding boxes)是以这些先验框为基准的,在一定程度上减少训练难度。一般情况下,每个单元会设置多个先验框,其尺度和长宽比存在差异,如图所示,可以看到每个单元使用了4个不同的先验框,图片中猫和狗分别采用最适合它们形状的先验框来进行训练,后面会详细讲解训练过程中的先验框匹配原则。
输出形式解释
对于每个单元的每个先验框,其都输出一套独立的检测值,对应一个边界框,主要分为两个部分。
第一部分是各个类别的概率得分,其中SSD将背景也当做了一个特殊的类别,如果检测目标共有c-1个类别,则SSD需要预测c个类别,其中第一个概率得分指的是属于背景的概率得分。
网络结构
SSD采用VGG16作为基础模型,然后在VGG16的基础上新增了卷积层来获得更多的特征图以用于检测。利用了多尺度的特征图做检测。模型的输入图片大小是300*300。
具体网络细节如下:
l 采用VGG16(包含13层卷积(卷积核均为3*3,步长为1,填充为1)、5个池化层(kernal_size=2,步长为2)、3个全连接层)做基础模型,首先VGG16是在ILSVRC CLS-LOC数据集预训练。
l 将池化层pool5由原来的stride=2的22变成stride=1的11。
l 将VGG16的全连接层fc6转换成33卷积层 conv6和将全连接层fc7转换成11卷积层conv7。并且conv6为了配合pool5的变化,采用扩展卷积(或带孔卷积),其中dilation rate(扩张率)=6。
下面解释一下扩展卷积(或带孔卷积):在不增加参数与模型复杂度的条件下指数级扩大卷积的视野,其使用扩张率(dilation rate)参数,来表示扩张的大小,如下图所示,(a)是普通的卷积33,其视野就是33,(b)是扩张率为2,此时视野变成77,©扩张率为4时,视野扩大为1515,但是视野的特征更稀疏了。
l 然后移除dropout层和fc8层,并新增一系列卷积层,在检测数据集上对网络权重微调。
多尺度特征图如何利用?
特征图选取
- VGG16中的Conv4_3层作为用于检测的第一个特征图。conv4_3层特征图大小是38*38,但是该层比较靠前,其norm较大,所以在其后面增加了一个L2 Normalization层,以保证和后面的检测层差异不是很大,这个和Batch Normalization层不太一样,其仅仅是对每个像素点在channle维度做归一化。
L2 Norm:计算公式
其是对应每一个通道进行计算,即“”为一个通道上的数据,而不是像BN那样,是整个batch的数据。
- 从后面新增的卷积层中提取Conv7,Conv8_2,Conv9_2,Conv10_2,Conv11_2作为检测所用的特征图,其大小分别是1919、1010、55、33、1*1。加上conv4_3的特征图,共6个。
先验框的设置
Conv10_2和Conv11_2层仅使用4个先验框,它们不使用长宽比为3,1/3的先验框。
- 先验框中心点位置问题:每个单元的先验框的中心点分布在各个单元的中心。
总结“先验框的设置”部分,每一个特征图的每一个单元,有固定的尺度,并且设有6个长宽比;从而共有38384+19196+10106+556+334+114=8732个先验框,SSD本质上属于密集采样。
对每个特征图如何得到检测结果
下面以Conv9_2的55256特征图为例,解释如何生成先验框、相应的类别概率、相应的位置信息(实际中这里输出的是位置偏移量,在“设计理念”中的“4.输出形式”有详细介绍,这里这样说只是为了方便理解)。
-
对于生成先验框,采用上面叙述的规则,即尺度为162,长宽比为,可以生成个先验框。
-
对于相应类别概率的生成,采用3*3卷积,个数为,其中称为类别数,为先验框数。
-
对于相应位置信息的生成,采用3*3卷积,个数为,其中为先验框数。
如下图
训练过程
-
对网络预训练,然后进行结构的变换,对于新的权重进行初始化,从而得到SSD检测网络。
-
对于数据可进行数据增强,如翻转、随机裁剪、颜色扭曲、随机采集块域(针对小目标)。
-
在训练过程中,对于先验框分正负样本打标签。首先要确定训练图片中的ground truth(真实目标)与哪个先验框来进行匹配,与之匹配的先验框所对应的边界框将负责预测它。
对于正样本:首先,对于图片中每个ground truth,找到与其IOU最大的先验框,该先验框与其匹配,这样可以保证每个ground truth一定与某个先验框匹配;其次对于剩余的未匹配先验框,若某个ground truth的IOU大于某个阈值(一般是0.5),那么该先验框也与这个ground truth进行匹配。(这意味着某个ground truth可能与多个先验框匹配,这是可以的。但是反过来却不可以,因为一个先验框只能匹配一个ground truth,如果多个ground truth与某个先验框 IOU大于阈值,那么先验框只与IOU最大的那个ground truth进行匹配。)仔细考虑一下这种情况,如果某个ground truth所对应最大IOU小于阈值,并且所匹配的先验框却与另外一个ground truth的IOU大于阈值,那么该先验框应该匹配谁,答案应该是前者,首先要确保某个ground truth一定有一个先验框与之匹配。但是,这种情况我觉得基本上是不存在的。
对于负样本:剩余部分为负样本。举例,如下图:其中绿色为真实框,红色为先验框,TP为正样本,FP为负样本。
但是即使这样,也存在负样本过多的情况,可以采用其为背景的置信度误差(预测背景的置信度越小,误差越大)进行降序排列,取top-N,尽量保证正负比为1:3。
- 损失函数。在确定训练样本之后,采用损失函数训练参数。其中包含类别损失和位置损失。总体为:
其中N为正样本数量,也就是只对正样本损失回归;为类别损失,x为真实,c为预测,采用softmaxLoss;表示位置损失,其输出为位置偏移量;当其为正样本时为1,为负样本时为0。
其中具体的类别损失采用softmaxLoss,如下:
其中具体的位置损失采用smoothL1损失,如下:
(上面具体符号不进行解释,可能和这篇笔记里表现不同,但含义相同。)
测试过程
对于每个预测框
-
首先根据类别置信度确定其类别(置信度最大者)与置信度值,并过滤掉属于背景的预测框。
-
然后根据置信度阈值(如0.5)过滤掉阈值较低的预测框。
-
对于留下的预测框进行解码,根据先验框得到其真实的位置参数(解码后一般还需要做clip,防止预测框位置超出图片)。
-
解码之后,一般需要根据置信度进行降序排列,然后仅保留top-k(如400)个预测框。
-
最后就是进行NMS算法,过滤掉那些重叠度较大的预测框。
-
最后剩余的预测框就是检测结果了。
SSD的tricks
l 数据扩增技术很重要,对于mAP的提升很大;
l 使用不同长宽比的先验框可以得到更好的结果;
l 采用多尺度的特征图用于检测也是至关重要的;
l 使用了image expansion data augmentation(通过zoom out来创造小的训练样本)技巧来提升SSD在小目标上的检测效果。