目标检测算法——SSD:Single Shot MultiBox Detector,是一篇很是经典的目标检测算法,十分值得阅读和进行代码复现,其论文地址是:https://arxiv.org/abs/1512.02325。git
同时,我使用pytorch对SSD代码进行了复现:https://github.com/Dengshunge/mySSD_pytorchgithub
从论文的题目《SSD:Single Shot MultiBox Detector》能够看出,single shot代表是one_stage检测算法,即不须要相似faster R-CNN中的RPN等区域推荐算法,一步就能获得预测坐标和类别,实现真正的end-to-end训练;multibox表示是多框预测,即SSD算法借鉴了faster R-CNN中的锚点框思想,对每一个先验锚点框进行预测,判断其类别和目标的预测框。算法
在SSD算法提出以前,R-CNN系列的目标检测算法,其准确率很高,可是这些算法须要消耗大量计算资源,特别是对于嵌入式设备或者终端设备,其算力没法知足此类算法,形成了没法进行实时目标检测。网络
目标检测的检测速度一般使用FPS进行衡量,即1秒能处理多少帧。Faster R-CNN的检测速度只有7FPS,虽然已经比之前的算法快不少了,但远远还达不到实时检测的效果。虽而后续对faster R-CNN作了不少改进来提升FPS,但这些增益都是以牺牲大量精度为前提。框架
所以,急需一种速度快且精度不低的目标检测算法。函数
以下图所示,下图是R-CNN系列,YOLO和SSD的性能对比图(Ref.《目标检测算法之SSD》),能够看出SSD在速度和mAP上都有较大的提高。性能
那么,SSD能实现速度与精度的平衡,是经过如下方式来实现的:学习
a) 改变网络结构,并使用多尺度融合;测试
b) 精心设计先验锚点框,和锚点框匹配策略;spa
c) 使用多个tricks来提升精度,如用于平衡正负样本数量的难例挖掘(hard negative mining)和数据加强。
如图1所示,是SSD的网络结构。在论文中,图片的输入尺寸为300*300*3,使用VGG16做为主干网络,同时,作出了如下修改:
对于须要融合的特征图,假设此特征图的尺寸是w*h,那么,对于每一个位置(x,y),会预先生成N个锚点框(具体锚点框的细节,下面会叙述),所以,每张特征图会生成w*h*N个锚点框。SSD经过对每一个锚点框进行位置回归和类别预测,并经过NMS非极大值抑制获得最终的检测结果。
SSD算法会生成一系列预测框(bounding boxes)和每一个预测框的得分,而后经过NMS非极大值抑制获得最终的检测结果。以下图所示,是SSD的网络结构。
图1 SSD的网络结构
图2 特征图的处理
SSD的锚点框借鉴了faster R-CNN的锚点框思想,但不一样的是,在SSD中,每一个特征图对应的锚点框均不相同,即锚点框会根据特征图的尺寸发生变化。例如,Conv4_3的锚点框和Conv7的锚点框的尺寸是不同的。假定使用m张特征图进行预测判断,每张特征图的锚点框大小,能够经过下式进行计算:
$$s_k=s_{min}+\frac{s_{max}-s_{min}}{m-1}(k-1),k\in [1,m]$$
其中,$s_{min}=0.2$和$s_{max}=0.9$,表示Conv4_3特征图的锚点框的尺寸为0.2,Conv11_2特征图的锚点框尺寸为0.9。既然有了锚点框的大小,能够理解为面积,接下来就须要为锚点框设置不一样的宽高比。做者设置了5种宽高比,分别是$a_r={1,2,3,1/2,1/3}$,所以,能够计算获得宽度$w_k^a=s_k\sqrt{a_r}$,高度为$h_k^a=s_k/\sqrt{a_r}$。对于宽高比为1的状况,额外增长一个锚点框,其尺寸为${s_k}'=\sqrt{s_ks_{k+1}}$。因此,通常而言,第i层特征图的(x,y)位置,具备6个锚点框。而第一层特征图和最后两层层特征图,每一个位置只设置4个锚点框。所以,图1中的8732个锚点框是这样计算获得的,$38*38*4+19*19*6+10*10*6+5*5*6+3*3*4+1*1*4=8732$。
经过对不一样特征图设置不一样的锚点框,有利于检测不一样尺寸的物体,大特征图可检测小物体,小特征图能够检测大物体。如图3所示,(a)表示带GT框的图像;(b)表示在8*8的特征图中,每一个位置使用6个不一样尺寸的锚点框,当某个锚点框与GT框的IOU大于阈值时,将其设置成正样本,该位置下其余锚点框为负样本;(c)表示4*4特征图下,红色虚线框用于预测狗的状况,会输出loc和conf两个tensor,loc表示相对于锚点框的偏移量,conf表示每一个类别的置信度。
图3 锚点框匹配
当设定了锚点框后,就须要制定其匹配规则,即制定哪些锚点框用于回归GT框和预测类别。首先,为每一个GT框匹配一个与其IOU最高的先验锚点框,保证了每一个GT框都有对应的锚点框,来预测GT框;其次,当GT框与先验锚点框的IOU大于阈值(0.5)时,也指定该锚点框用来预测该GT框。固然,若锚点框A与多个GT框的IOU都大于阈值,则该锚点框A选择与其IOU最大的GT框。
图4是锚点框与GT框的匹配示意图,为了方便理解,将锚点框映射回原图尺寸,与GT框进行匹配。
图4 锚点框与GT框的匹配
$$L(x,c,l,g)=\frac{1}{N}(L_{conf}(x,c)+\alpha L_{loc}(x,l,g))$$
(1)VOC测试结果
下表是SSD在VOC的实验结果图。与Fast R-CNN和Faster R-CNN进行对比,分别使用了300*300和 512*512的图片做为输入。在07+12+COCO数据集上来看,SSD300比Faster R-CNN的mAP提升了0.8%,SSD512提升了2.8%。此外,SSD的定位偏差更小,由于SSD是直接回归目标的形状和进行分类,将定位和分类合成了一步。可是,对于类似目标,SSD容易产生混淆,多是由于对不一样种类的目标共享了位置。SSD还容易预测框尺寸的干扰,即在小目标上其性能比大目标要差。做者认为这多是因为在浅层的时候,小目标物体包含的信息很少。当增长了分辨率的时候,这种状况获得了较好的改善。
(2)模型分析
为了了解SSD中各组成对结果的影响程度,做者使用SSD300进行了控制变量实验,结果以下图所示。
(3)推理时间
下表是SSD的推理时间对比图。能够看出,SSD中精度和速度上作到了比较好的平衡。
SSD是一种很优秀的one-stage框架,对后面不少目标检测算法有着深远的影响。读完论文,发现仍是对SSD的了解不够深刻,接下来,会对其源码进行分析。