物体检测之SSD

先上一个物体检测算法时间轴:
!()[https://upload-images.jianshu.io/upload_images/4987072-d56f272622ecc495?imageMogr2/auto-orient/strip%7CimageView2/2/w/720/format/webp]

从时间轴上看,SSD的发布是在Faster rcnn和YOLO-v1之后,YOLO-v1是one-stage检测算法开山之作,速度上碾压Faster rcnn。SSD沿用了YOLO-v1 one-stage的思想,融合了Faster rcnn的anchor-box,又提出了多尺度检测思想,最终达到了效果和速度都相对比较理想的程度,如下:
!()[https://upload-images.jianshu.io/upload_images/4987072-1e56279546be1398?imageMogr2/auto-orient/strip%7CimageView2/2/w/838/format/webp]

SSD:Single Shot MultiBox Detector 论文下载地址:https://arxiv.org/pdf/1512.02325.pdf

设计理念
SSD和YOLO一样都是采用端到端的方法,采用一个CNN网络进行检测,但采用了不同尺度的Feature Map,核心设计理念总结如下:
!(基本框架)[https://img-blog.csdn.net/20180406150216329?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW9odTIwMjI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70]
(1)采用多尺度特征图用于检测
CNN一般前面的feature map比较大,每个单位视野比较小,适合检测小的物体;后面的feature map相对较小,但每个单位的视野大,适合检测大的物体。
!()[https://img-blog.csdn.net/20180406150249491?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW9odTIwMjI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70]

(2)采用全卷积进行检测
与YOLO-v1后面接全连接层不同,SSD直接采用卷积对提取不同大小的feature map,主要采用3*3的卷积核进行特征提取。

(3)设置先验框

在Yolo中,每个单元预测多个边界框,但是其都是相对这个单元本身(正方块),但是真实目标的形状是多变的,Yolo需要在训练过程中自适应目标的形状。

而SSD借鉴了Faster R-CNN中anchor的理念,每个单元设置尺度或者长宽比不同的先验框,预测的边界框(bounding boxes)是以这些先验框为基准的,在一定程度上减少训练难度。一般情况下,每个单元会设置多个先验框,其尺度和长宽比存在差异,如图下图所示,可以看到每个单元使用了4个不同的先验框,图片中猫和狗分别采用最适合它们形状的先验框来进行训练,后面会详细讲解训练过程中的先验框匹配原则。


image

1.https://blog.csdn.net/xiaohu2022/article/details/79833786

SSD的检测值也与Yolo-v1有一些差异,但是都包括confidence和location,Yolo-v1中confidence指所预测的 box 中含有 object 的置信度和这个 box 预测的有多准两重信息,SSD中confidence指预测的各个类别的置信度。具体说一下,检测值第一部分confidence是各个类别的置信度,SSD也将背景作为了一个特殊类,若检测目标共有c个类,则SSD需要预测c+1个类别置信度。在预测过程中,置信度最高的那个类别就是单签边界框所属的类别,若对应的背景类别置信度最高,则该边界框中不包含目标。第二部分就是边框的location(cx,cy,w,h),但是边框预测值是相对于设置的先验框的offset。d=(d^{cx},d^{cy},d^{w},d^{h}),其对应边界框b=(b^{cx},b^{cy},b^{w},b^{h}),边界框的预测值ljiushi b相对于d的转换:

l^{cx}=(b^{cx}-d^{cx})/d^w,l^{cy}=(b^{cy}-d^{cy})/d^w,l^{w}=log(b^{w}/d^w),l^{h}=log(b^{h}/d^h)

习惯上,我们称上面这个过程为边界框的编码(encode),预测时,你需要反向这个过程,即进行解码(decode),从预测值l中得到边界框的真实位置b
b^{cx}=d^wl^{cx}+d^{cx} ,b^{cy}=d^yl^{cy}+d^{cy},b^w=d^wexp(l^w),b^h=d^hexp(l^h)

综上所述,对于一个大小m×n的特征图,共有mn个单元,每个单元设置的先验框数目记为k,那么每个单元共需要(c+4)k个预测值,所有的单元共需要(c+4)kmn个预测值,由于SSD采用卷积做检测,所以就需要(c+4)k个卷积核完成这个特征图的检测过程。

网络结构
SSD采用VGG16作为基础模型,然后在VGG16的基础上新增了卷积层来获得更多的特征图以用于检测。如下图所示,上面是SSD模型,下面是Yolo-v1模型,可以明显看到SSD利用了多尺度的特征图做检测。模型的输入图片是300300(还可以是512512,其余前者网络结构没有差别,只是最后新增一个卷积层)

image

采用VGG16做基础模型,首先VGG16是在ILSVRC CLS-LOC数据集预训练。分别将VGG16的全连接层fc6和fc7转换成3×3卷积层conv6和1×1卷积层conv7,同时将池化层pool5由原来的2×2−s2变成3×3−s1(reduce特征图大小)

为了配合这种变化,采用了一种Atrous Algorithm,其实就是conv6采用扩展卷积或带孔卷积(Dilation Conv),其在不增加参数与模型复杂度的条件下指数级扩大卷积的视野,其使用扩张率(dilation rate)参数,来表示扩张的大小,如下图所示,(a)是普通的3×3卷积,其视野就是3×3,(b)是扩张率为2,此时视野变成7×7,(c)扩张率为4时,视野扩大为15×15,但是视野的特征更稀疏了。Conv6采用3×3大小但dilation rate=6的扩展卷积。


扩张卷积

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

其中VGG16中的Conv4_3层将作为用于检测的第一个特征图。conv4_3层特征图大小是38×38,但是该层比较靠前,其norm较大,所以在其后面增加了一个L2 Normalization层,以保证和后面的检测层差异不是很大,这个和Batch Normalization层不太一样,其仅仅是对每个像素点在channle维度做归一化,而Batch Normalization层是在[batch_size, width, height]三个维度上做归一化。归一化后一般设置一个可训练的放缩变量gamma,使用TF可以这样简单实现:

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

s_k=s_{min}+\frac{s_{max}-s_{min}}{m-1}(k-1),k \in [1,m]

其中m指的特征图个数,但却是5,因为第一层(Conv4_3层)是单独设置的,s_k表示先验框大小相对于图片的比例,而s_mins_max表示比例的最小值和最大值,paper里面取0.2和0.9,。对于第一个特征图,其先验框的尺度比例一般设置为s_min/2=0.1,那么尺度为300*0.1=30。对于后面的特征图,先验框尺度按照上面公式线性增加,但是先将尺度比例先扩大100倍,此时增长步长为\frac{s_{max}*100-s_{min}*100}{m-1}=17,这样各个特征图的s_k为20,37,54,71,88,将这些比例除以100,然后再乘以图片大小,可以得到各个特征图的尺度为60,111,162,213,264,对于长宽比,一般选取a_r \in {1,2,3,\frac{1}{2},\frac{1}{3}},对于特定的长宽比,按照如下公式计算先验框的宽度和高度(后面的s_k均指的是先验框实际尺寸,而不是尺度比例):
w_k^a=s_k\sqrt{a_r},h_k^a=s_k/\sqrt{a_r}

得到了特征图之后,需要对特征图进行卷积得到检测结果,下图给出了一个5×5大小的特征图的检测过程。其中Priorbox是得到先验框,前面已经介绍了生成规则。检测值包含两个部分:类别置信度和边界框位置,各采用一次3×3卷积来进行完成。令m_k为该特征图所采用的先验框数目,那么类别置信度需要的卷积核数量为n_k*c,而边界框位置需要的卷积核数量为n_k*4。由于每个先验框都会预测一个边界框,所以SSD300一共可以预测38×38×4+19×19×6+10×10×6+5×5×6+3×3×4+1×1×4=8732个边界框,这是一个相当庞大的数字,所以说SSD本质上是密集采样。

基于卷积得到检测结果

训练过程
(1)先验框匹配

在训练过程中,首先要确定训练图片中的ground truth(真实目标)与哪个先验框来进行匹配,与之匹配的先验框所对应的边界框将负责预测它。在Yolo-v1中,ground truth的中心落在哪个单元格,该单元格中与其IOU最大的边界框负责预测它。但是在SSD中却完全不一样,SSD的先验框与ground truth的匹配原则主要有两点。首先,对于图片中每个ground truth,找到与其IOU最大的先验框,该先验框与其匹配,这样,可以保证每个ground truth一定与某个先验框匹配。通常称与ground truth匹配的先验框为正样本,反之,若一个先验框没有与任何ground truth进行匹配,那么该先验框只能与背景匹配,就是负样本。一个图片中ground truth是非常少的, 而先验框却很多,如果仅按第一个原则匹配,很多先验框会是负样本,正负样本极其不平衡,所以需要第二个原则。第二个原则是:对于剩余的未匹配先验框,若某个ground truth的IOU大于某个阈值(一般是0.5),那么该先验框也与这个ground truth进行匹配。这意味着某个ground truth可能与多个先验框匹配,这是可以的。但是反过来却不可以,因为一个先验框只能匹配一个ground truth,如果多个ground truth与某个先验框IOU大于阈值,那么先验框只与IOU最大的那个先验框进行匹配。第二个原则一定在第一个原则之后进行,仔细考虑一下这种情况,如果某个ground truth所对应最大IOU小于阈值,并且所匹配的先验框却与另外一个ground truth的IOU大于阈值,那么该先验框应该匹配谁,答案应该是前者,首先要确保某个ground truth一定有一个先验框与之匹配。但是,这种情况我觉得基本上是不存在的。下图为一个匹配示意图,其中绿色的GT是ground truth,红色为先验框,FP表示负样本,TP表示正样本。


先验框匹配示意图

尽管一个ground truth可以与多个先验框匹配,但是ground truth相对先验框还是太少了,所以负样本相对正样本会很多。为了保证正负样本尽量平衡,SSD采用了hard negative mining,就是对负样本进行抽样,抽样时按照置信度误差(预测背景的置信度越小,误差越大)进行降序排列,选取误差的较大的top-k作为训练的负样本,以保证正负样本比例接近1:3。

(2)损失函数
训练样本确定了,然后就是损失函数了。损失函数定义为位置误差(locatization loss, loc)与置信度误差(confidence loss, conf)的加权和:
L(x,c,l,g)=\frac{1}{N}(L_{conf}(x,c))+αL_loc(x,l,g))
其中N是先验框的正样本数量,x_{ij}^p \in{1,0}为一个指示参数,当x_{ij}^p=1时表示第i个先验框与第j个ground truth匹配,并且ground truth的类别为pc为类别置信度预测值。l为先验框的所对应边界框的位置预测值,而g是ground truth的位置参数。对于位置误差,其采用Smooth L1 loss,定义如下:

image

![]https://img-blog.csdn.net/20180406150937425?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpYW9odTIwMjI=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70()

由于x_{ij}^p的存在,所以位置误差仅针对正样本进行计算。值得注意的是,要先对ground truth的gg进行编码得到g^,因为预测值ll也是编码值。

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

image

权重系数αα通过交叉验证设置为1。

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

image

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

性能评估

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


SSD在不同数据集上的性能

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

SSD与其它检测算法的对比结果(在VOC2007数据集)

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

  • 数据扩增技术很重要,对于mAP的提升很大;
  • 使用不同长宽比的先验框可以得到更好的结果;
不同的trick组合对SSD的性能影响

同样的,采用多尺度的特征图用于检测也是至关重要的,这可以从下表看出:

多尺度特征图对SSD的影响

总结
SSD在Yolo的基础上主要改进了三点:多尺度特征图,利用卷积进行检测,设置先验框。这使得SSD在准确度上比Yolo更好,而且对于小目标检测效果也相对好一点。由于很多实现细节都包含在源码里面,文中有描述不准或者错误的地方在所难免,欢迎交流指正。

参考
1.https://blog.csdn.net/xiaohu2022/article/details/79833786

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容