目标检测算法——SSD:Single Shot MultiBox Detector,是一篇非常经典的目标检测算法,十分值得阅读和进行代码复现,其论文地址是:https://arxiv.org/abs/1512.02325


一、前言

1.1 什么是SSD

从论文的题目《SSD:Single Shot MultiBox Detector》可以看出,single shot表明是one_stage检测算法,即不需要类似faster R-CNN中的RPN等区域推荐算法,一步就能得到预测坐标和类别,实现真正的end-to-end训练;multibox表示是多框预测,即SSD算法借鉴了faster R-CNN中的锚点框思想,对每个先验锚点框进行预测,判断其类别和目标的预测框。

1.2 为什么提出SSD

在SSD算法提出之前,R-CNN系列的目标检测算法,其准确率很高,但是这些算法需要消耗大量计算资源,特别是对于嵌入式设备或者终端设备,其算力无法满足此类算法,造成了无法进行实时目标检测。

目标检测的检测速度通常使用FPS进行衡量,即1秒能处理多少帧。Faster R-CNN的检测速度只有7FPS,虽然已经比以前的算法快很多了,但远远还达不到实时检测的效果。虽然后续对faster R-CNN做了很多改进来提高FPS,但这些增益都是以牺牲大量精度为前提。

因此,急需一种速度快且精度不低的目标检测算法。

1.3 如何平衡速度与精度

如下图所示,下图是R-CNN系列,YOLO和SSD的性能对比图(Ref.《目标检测算法之SSD》),可以看出SSD在速度和mAP上都有较大的提升。

那么,SSD能实现速度与精度的平衡,是通过以下方式来实现的:

a) 改变网络结构,并使用多尺度融合;

b) 精心设计先验锚点框,和锚点框匹配策略;

c) 使用多个tricks来提高精度,如用于平衡正负样本数量的难例挖掘(hard negative mining)和数据增强。


二、网络结构

如图1所示,是SSD的网络结构。在论文中,图片的输入尺寸为300*300*3,使用VGG16作为主干网络,同时,做出了以下修改:

  1. 将原本VGG16的FC6和FC7换成卷积层Conv6和Conv7,并依次加入新的层:Conv8_2,Conv9_2,Conv10_2,Conv11_2。具体而言,在Conv7层的特征图为19*19*1024,经过1*1*256和3*3*512-s2的卷积操作后,得到Conv8_2的特征图,其尺寸为10*10*512,依次类推。
  2. 为了实现多尺度融合,需要将不同层的特征图提取出来进行判断。在论文中,作者使用Conv4_3、Conv7、Conv8_2、Conv9_2、Conv10_2和Conv11_2的特征图来进行多尺度融合。如图2所示,每层特征图会分别经过3*3的卷积,得到2个tensor,分别用于进行坐标预测和类别置信度预测。其中,用于坐标预测的通道数是(num_anchor*4),num_anchor表示该特征图每个位置对应的锚点框数量,4表示(x_min,y_min,x_max,y_max);用于类别置信度预测的通道数是(num_anchor*num_classes),num_classes表示类别的数量(包含背景),对于VOC来说,num_classes=21,20个类别加上1个背景。另外,论文中会对Conv4_3层的特征图使用L2归一化后,再进行3*3的卷积,这样做的目的是,防止此层特征图的值过大,利于收敛。

对于需要融合的特征图,假设此特征图的尺寸是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框的匹配

四、其余策略

  • SSD的损失函数继承了R-CNN系列的损失函数,如下所示,由位置损失和置信度损失组成,位置损失使用了smooth1,置信度损失使用多类别交叉熵:

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

  • 此外,SSD可以理解成对图片进行密集采样,得到8732个patch,然后对这些patch进行预测和回归。因此,会发现,大部分锚点框都会匹配上背景,也就是被设置成负样本。因此,会造成正负样本之间的不平衡。对于此情况,SSD使用了hard negative mining策略来缓解这一锚段。在SSD中,并没有使用所有的负样本,而是将这些匹配上背景的样本根据置信度损失进行降序排列,取出置信度损失进行排序,将损失较大的样本认为是难例(hard negative),需要模型重点学习。选取损失最大的前N个样本作为负样本,正样本与负样本的比例控制在1:3左右,对于那些没有选上的样本,label设置成-1,不参与训练当中。
  • 为了扩大感受野,加快推理速度,还使用了空洞卷积。
  • SSD中还采用了数据增强的策略,如对原图进行色域变换、扩增、采样的操作,具体可以参考这篇文章。

五、实验结果

(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进行了控制变量实验,结果如下图所示。

  • 数据增强:在R-CNN系列中,采用的是原图或者对原图进行翻转等变换。而SSD中,使用了更多的策略,包括扩增、采样等。可以看出,使用数据增强的SSD,mAP提高了8.8%。但作者认为,同样的数据增强策略,对R-CNN系列可能会失效,因为在进入分类头的时候,使用了特征池化。
  • 锚点框的多样性:在SSD中,对特征图的每个位置使用了6个不同形状的锚点框,每层特征图的锚点框也均不一致。当移除锚点框后,mAP都出现了不同比例的下降。使用不同尺寸的锚点框,使网络能更加简单对锚点框进行回归。但是不是锚点框越多越好呢?锚点框越多,推理速度也就越慢。这中间应该会有折中。
  • 空洞卷积:在本实验中,使用的是带空洞卷积版本的VGG16。如果使用完全版本的VGG16,即保留pool5和对fc6/fc7不使用下采样,增加conv5_3进行特征融合。这样的话,能得到相同精度的结果,但速度却慢了20%。
  • 多尺度融合:SSD的主要贡献在于在不同分辨率的特征层中使用了不同尺寸的锚点框,进行多尺度融合。为了比较这一做法的影响,作者去除某些用于特征融合的层,实验的结果如下表所示。为了保证一致性,锚点框的数量保持接近8732。可以看出,当特征层越来越少的时候,mAP也会随之下降,从74.3下降到62.4。

(3)推理时间

下表是SSD的推理时间对比图。可以看出,SSD中精度和速度上做到了比较好的平衡。


SSD是一种很优秀的one-stage框架,对后面很多目标检测算法有着深远的影响。读完论文,发现还是对SSD的了解不够深入,接下来,会对其源码进行分析。

SSD学习笔记的更多相关文章

  1. 深度学习笔记(十三)YOLO V3 (Tensorflow)

    [代码剖析]   推荐阅读! SSD 学习笔记 之前看了一遍 YOLO V3 的论文,写的挺有意思的,尴尬的是,我这鱼的记忆,看完就忘了  于是只能借助于代码,再看一遍细节了. 源码目录总览 tens ...

  2. 深度学习笔记(七)SSD 论文阅读笔记简化

    一. 算法概述 本文提出的SSD算法是一种直接预测目标类别和bounding box的多目标检测算法.与faster rcnn相比,该算法没有生成 proposal 的过程,这就极大提高了检测速度.针 ...

  3. 深度学习笔记(七)SSD 论文阅读笔记

    一. 算法概述 本文提出的SSD算法是一种直接预测目标类别和bounding box的多目标检测算法.与faster rcnn相比,该算法没有生成 proposal 的过程,这就极大提高了检测速度.针 ...

  4. [学习笔记] SSD代码笔记 + EifficientNet backbone 练习

    SSD代码笔记 + EifficientNet backbone 练习 ssd代码完全ok了,然后用最近性能和速度都非常牛的Eifficient Net做backbone设计了自己的TinySSD网络 ...

  5. Java学习笔记(04)

    Java学习笔记(04) 如有不对或不足的地方,请给出建议,谢谢! 一.对象 面向对象的核心:找合适的对象做合适的事情 面向对象的编程思想:尽可能的用计算机语言来描述现实生活中的事物 面向对象:侧重于 ...

  6. 学习笔记:The Log(我所读过的最好的一篇分布式技术文章)

    前言 这是一篇学习笔记. 学习的材料来自Jay Kreps的一篇讲Log的博文. 原文很长,但是我坚持看完了,收获颇多,也深深为Jay哥的技术能力.架构能力和对于分布式系统的理解之深刻所折服.同时也因 ...

  7. Oracle User Management FAQ翻译及学习笔记

    转载 最近了解到AME 的东西,很迫切,先转载一篇 [@more@] Oracle User Management FAQ翻译及学习笔记 写在前面 本文主要是翻译的英文版的Oracle User Ma ...

  8. 学习笔记:The Log(我所读过的最好的一篇分布式技术文章)

    前言 这是一篇学习笔记. 学习的材料来自Jay Kreps的一篇讲Log的博文. 原文非常长.可是我坚持看完了,收获颇多,也深深为Jay哥的技术能力.架构能力和对于分布式系统的理解之深刻所折服.同一时 ...

  9. OpenCV 学习笔记 07 目标检测与识别

    目标检测与识别是计算机视觉中最常见的挑战之一.属于高级主题. 本章节将扩展目标检测的概念,首先探讨人脸识别技术,然后将该技术应用到显示生活中的各种目标检测. 1 目标检测与识别技术 为了与OpenCV ...

随机推荐

  1. lucene 快速入门

    日常开发中,相信大家经常会用like去匹配一些数据,同时我们也知道,like往往会导致全表扫描,当数据量越来越大的时候,我们会纠结于 数据库的龟速查找,此时我们必须另寻蹊跷,这时lucene就可以大显 ...

  2. 1.Oracle 11g 精简客户端

    大型项目开发中,当属Oracle的使用率最高.通常开发人员的机器上都会装上一个 oracle客户端,但一般我们不会再自己的机器上安装Oracle database,因为我们的项目中有专为开发使用的or ...

  3. Tomcat 8.5 配置 域名绑定

    1.修改Tomcat的Server.xml两处地方即可: a) b)

  4. Selenium 2自动化测试实战23(窗口截图)

    一.窗口截图 WebDriver提供了截图函数get_screenshot_as_file()来截取当前窗口. # -*- coding: utf-8 -*- from selenium import ...

  5. springboot中静态属性/静态方法从YAML(yml)读取配置属性

    启动类添加注解@EnableConfigurationProperties import jnetman.session.SnmpPref; import org.springframework.bo ...

  6. 【VS开发】设备控制台 (DevCon.exe) 示例

    设备控制台 (DevCon.exe) 示例 本部分提供以下设备控制台 (DevCon.exe) 命令的示例: DevCon HwIDs 示例 1:查找所有硬件 ID 示例 2:使用模式查找硬件 ID ...

  7. [c++] 链表各类操作详解

    链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个“头指针”变量,以head表示,它存放一个地址.该地址指向一个元素.链表中每一个元素称 ...

  8. PostgreSQL中with和without time zone两者有什么区别

    with和without time zone两者有什么区别 1.区别 1)名字上看一个是带时区的,另一个是不带时区的,查出来的时间是一样的,只是一个带时区标志,一个不带而已,时区的基准是格林威治时间U ...

  9. 掌握Mybatis的核心配置文件

    一.配置文件结构 MyBatis的核心配置文件配置了MyBatis的一些全局信息,包含数据库连接信息和MyBatis运行时所需的各种特性,以及设置和影响MyBatis行为的一些属性. 该配置文件的元素 ...

  10. git使用技巧集合(持续更新中)

    git使用技巧集合(持续更新中) 在团队协作中,git.svn等工具是非常重要的,在此只记录一些git使用过程中遇到的问题以及解决方法,并且会持续更新. 1.git commit之后,还没push,如 ...