目标检测(object detection)系列(六) SSD:兼顾效率和准确性

这里写图片描述
目标检测系列:
目标检测(object detection)系列(一) R-CNN:CNN目标检测的开山之作
目标检测(object detection)系列(二) SPP-Net:让卷积计算可以共享
目标检测(object detection)系列(三) Fast R-CNN:end-to-end的愉快训练
目标检测(object detection)系列(四) Faster R-CNN:有RPN的Fast R-CNN
目标检测(object detection)系列(五) YOLO:目标检测的另一种打开方式
目标检测(object detection)系列(六) SSD:兼顾效率和准确性
目标检测(object detection)系列(七) R-FCN:位置敏感的Faster R-CNN
目标检测(object detection)系列(八) YOLOv2:更好,更快,更强
目标检测(object detection)系列(九) YOLOv3:取百家所长成一家之言
目标检测(object detection)系列(十) FPN:用特征金字塔引入多尺度
目标检测(object detection)系列(十一) RetinaNet:one-stage检测器巅峰之作
目标检测(object detection)系列(十二) CornerNet:anchor free的开端
目标检测(object detection)系列(十三) CenterNet:no Anchor,no NMS

目标检测扩展系列:
目标检测(object detection)扩展系列(一) Selective Search:选择性搜索算法
目标检测(object detection)扩展系列(二) OHEM:在线难例挖掘
目标检测(object detection)扩展系列(三) Faster R-CNN,YOLO,SSD,YOLOv2,YOLOv3在损失函数上的区别

前言:兼顾效率和准确性

SDD出现之前,主流的CNN目标检测模型分别是Faster R-CNNYOLO,Faster R-CNN作为two-stage的代表,具有state of the art的准确性,但是速度偏慢,做不到实时。YOLO使得目标检测任务one-stage就能完成,在效率上有了明显改善,但是准确性上确差了很多。这就好比“人有悲欢离合,月有阴晴圆缺,此事古难全。”
但是就在这个时候,SDD出现了,一个兼顾了效率和准确性的网络结构。因为它做到了比Faster R-CNN更准,同时又比YOLO更快的性能表现。
SSD的论文是《SSD: Single Shot MultiBox Detector》,下面我们就来看一下它具体是如何实现的。

YOLO实现

设计理念

  • 从不同的卷积层中分别拉取分支进行检测,不同的卷积层具有多种感受野和语义信息
  • 用卷积层代替全连接层和reshape层,用卷积核的数量控制输出特征图的通道数
  • 借鉴Faster R-CNN,进入用先验atchor box,并对每一个box都预测类别

网络结构

在这里插入图片描述
上图是SSD和YOLO的对比图,它们的主干网络都是VGG16,区别在于YOLO做完了原有VGG16的所有层,只修改了最后一层全连接的输出个数到1470个,然后Reshape成7×7×307\times7\times30的特征图。而SSD则对VGG16做了很多改动,在VGG16的pool5之前,SSD保持了原始结构不变,由于输入图像尺寸是300×300300\times300,所以Conv4_3的卷积层的输出为38×38×51238\times38\times512,Conv5_3的卷积层的输出为19×19×51219\times19\times512,随后舍弃了VGG原有的全连接层,同时将池化层pool5由原来的2×2,stride=22\times2,stride=2 修改为3×3,stride=1,pad=13\times3,stride=1,pad=1,主要是为了后续的扩张卷积补齐特征图宽高,为了进一步增大感受野,新增的Conv6层卷积是一个扩张系数为6的3×33\times3卷积核,并把特征图厚度升为1024,Conv7尺寸为1×11\times1。在此之后,SDD使用1×11\times13×33\times3尺寸卷积核依次使用的方式,向后增加卷积层。1×11\times1卷积核负责降低通道数量,3×33\times3卷积核负责下采样和提升维度,一直到最后一层经过全局平均池化后变成维度为1×1×2561\times1\times256,SSD的主干网络接结束了。
为了做到MultiBox,SSD需要从不同的层拉取分支,从上图中可以看到,选择Conv4_3,Conv7_2,Conv8_2,Conv9_2,Conv10_2,Pool11,总计6个分支。每一层特征图都要拉取2个分支,一个分支用来预测bbox的四个值,一个分支用来预测类别和置信度,为了方便后续说明,把两个分支分别定义为Mbox_loc和Mbox_con。
这些分支最后的特征图输出要控制通道数量,同时保证特征图的长宽不变,这是用尺寸3×33\times3卷积核来完成的。最终,六层特征图的3维shape分别是:

  • Mbox_loc
    Conv4_3:38×38×1638\times38\times16,Conv7_2:19×19×2419\times19\times24,Conv8_2:10×10×2410\times10\times24,Conv9_2:5×5×245\times5\times24,Conv10_2:3×3×163\times3\times16,Pool11:1×1×161\times1\times16
  • Mbox_con
    Conv4_3:38×38×8438\times38\times84,Conv7_2:19×19×12619\times19\times126,Conv8_2:10×10×12610\times10\times126,Conv9_2:5×5×1265\times5\times126,Conv10_2:3×3×843\times3\times84,Pool11:1×1×841\times1\times84

那为啥要控制输出这样的维度呢?
Mbox_loc的维度与特征图上每个点要预测的框的数量有关,六层特征图中每个点分别预测4,6,6,6,4,4个框,每个框需要4个值表达,所以预测为4时,channel为4×4×=164\times4\times=16,预测为6时,channel为4×6×=244\times6\times=24
Mbox_con的维度与SDD要预测类别置信度和框的数量有关,需要注意的是,SDD将背景类同样作为一个类别参与预测,所以当目标类别是0的时候,SDD实际要预测21个类别的置信度,所以当背景类的置信度最高时,也就意味着没有目标。同时,SDD要对每一个框都输出所有的置信度,这是SSD和YOLO不一样的地方,虽然YOLO的每一个格子也输出两个box,但是置信度确对应格子,而不是对应box, 但是SSD是对每个box都输出对应的置信度,所以当box的数量为4时,channel为4×21×=814\times21\times=81,box的数量为6时,channel为6×21×=1266\times21\times=126

SSD与RPN

到这里就会发现,这种操作似曾相识,又很像RPN,RPN也有两个分支:
第一个分支(reg layer)最后输出4k个数,这里的4是一个建议框的参数,即(x,y,w,h);
第二个分支(cls layer)最后输出2k个数,这里的2是该区域到底有没有物体,即(object,non-object)的二分类问题。
在这里插入图片描述
但是这只是卷积核滑动一次的输出,最终RPN会滑动出shape为13×13×4k13\times13\times4k的reg layer和13×13×2k13\times13\times2k的cls layer,这个k在Faster R-CNN中是9,只是在SDD中换成4或6,RPN的类别置信度有两个,在SDD中换成了21个,同时RPN的类别也会对应框产生。

SSD与YOLO

SSD通过六个特征图,每个特征图上的点依次输出4,6,6,6,4,4个框,那么SDD一共可以有8732个预测框。
38×38×4+19×19×6+10×10×6+5×5×6+3×3×6+1×1×16=873238\times38\times4 + 19\times19\times6 + 10\times10\times6 + 5\times5\times6 + 3\times3\times6 + 1\times1\times16 = 8732
并且,这些框都有完整的整套置信度,也就是说SDD可以产生8732个预测结果。
而上一篇提到过,YOLO的类别判断只在格子上产生,和框的数量无关,所以YOLO的类别预测只有49个,同时每个格子会产生两个框,框的信息除了坐标外,只剩下一个是否有目标的置信度,而没有类别。这样算起来,YOLO最后一共有98个预测框。
这完全不在一个量级上,所以密集的预测框是SDD效果好的一个重要保障。

先验框设定

现在我们知道了SSD每一层先验框的数量,那么这些框的目的是什么,预设值是什么,并且它们是如何被使用的?

  • 设定目的
    SSD的先验框是借鉴RPN,RPN中的anchor box有三种比例和三种尺度,这其实是在模拟实际图片中目标ground truth的尺寸和比例,并做一个合理的抽象,这使得预测框的初始值更贴近ground truth,也可以理解为,将原有的ground truth转化为ground truth与archor box的偏差,方便后续的优化训练。这里的反面例子就是YOLO,YOLO其实是一个没有archor的方法,所以YOLO在优化bbox的宽高时,是直接使用输出值逼近bbox宽高的归一化的值,这里是没有先验的从0开始,现对而言这个难度要比存在archor预设大一些。而SSD为了避免这一点,借鉴了RPN的archor预设。
  • 如何设定
    不同层输出的特征图,它们的感受野是不同的,一般情况下,随着下采样次数的增加,感受野在成倍数的放大。在这个前提下,如果用同一个规则设置不同层特征图的先验框是不合理的,所以SSD采用了一种线性规则:随着特征图层数的加深,特征图逐渐变小,先验框尺度线性增加。
    sk=smin+mmaxmminm1(k1),k[1,m]s_{k}=s_{min}+\frac{m_{max}-m_{min}}{m-1}(k-1),k\in[1,m]
    其中m指的特征图个数,但是m=5m=5,而不是6,因为第一层(Conv4_3层)是单独设置的,sks_k表示先验框大小相对于图片的比例,而smins_{min}smaxs_{max}表示比例的最小值与最大值,paper里面取0.2和0.9。对于第一个特征图,其先验框的尺度比例一般设置为0.1。所以特征图比例分别是0.1,0.2,0.375,0.55,0.725,0.9。这样对应300×300300\times300的输入图像,计算出的尺寸就应该是30,60,112,165,217,270。
    当然还有一组数字是30,60,111,162,213,264,这个是从SSD的caffe源码里求得的。当有当前层的尺度sks_{k}和下一层的尺度sk+1s_{k+1},SDD会根据这两个尺寸先计算两个大小不同,但长宽比都是1的正方形先验框,一个长宽是sks_{k},另一个长宽是sk×sk+1\sqrt {s_{k} \times s_{k+1}},需要注意的是,最后一个特征图的尺寸已经没有k+1了,所以这个值是推算出来的315。
    尺寸确定之后,还剩下先验框的比例,这个使用的是{2,3,12,13}\left \{2,3,\frac{1}{2},\frac{1}{3}\right \}这组数,都在尺寸为sks_{k}的正方形框上产生,比如比例是2时,计算方式为:
    w=sk2w=s_{k}\sqrt{2}h=sk2 h=\frac{s_{k}}{\sqrt{2}}
    当预设框是4个时,使用{2,12}\left \{2,\frac{1}{2}\right \},预设框是6个时,使用{2,3,12,13}\left \{2,3,\frac{1}{2},\frac{1}{3}\right \}
  • 如何使用
    这些先验框最终被用于参与目标位置的计算,SSD要预测位置实际上是ground truth和预设框的offset,或者说,预设框被用于重新编码ground truth,这一点和Faster R-CNN很像,假设预设框为{dcx,dcy,dw,dh}\left \{d^{cx},d^{cy},d^{w},d^{h}\right \},ground truth为{gcx,gcy,gw,gh}\left \{g^{cx},g^{cy},g^{w},g^{h}\right \},从公式中可以看出来,{dcx,dcy}\left \{d^{cx},d^{cy}\right \}{gcx,gcy}\left \{g^{cx},g^{cy}\right \}都表示中心点坐标。那么转换后的ground truth坐标{g^cx,g^cy,g^w,g^h}\left \{\hat{g}^{cx},\hat{g}^{cy},\hat{g}^{w},\hat{g}^{h}\right \}依照下面方式求取:
    g^cx=(gcxdcx)dw\hat{g}^{cx}=\frac{\left (g^{cx}-d^{cx} \right )}{d^{w}}g^cy=(gcydcy)dh\hat{g}^{cy}=\frac{\left (g^{cy}-d^{cy} \right )}{d^{h}}g^w=loggwdw\hat{g}^{w}=log{\frac{g_{w}}{d^{w}}}g^h=logghdh\hat{g}^{h}=log{\frac{g_{h}}{d^{h}}}

损失函数

SSD的损失函数由两部分组成,分别是位置误差(locatization loss, loc)与置信度误差(confidence loss, conf):
在这里插入图片描述
在位置损失中{g^cx,g^cy,g^w,g^h}\left \{\hat{g}^{cx},\hat{g}^{cy},\hat{g}^{w},\hat{g}^{h}\right \}的求取和上面是一致的,而{l^cx,l^cy,l^w,l^h}\left \{\hat{l}^{cx},\hat{l}^{cy},\hat{l}^{w},\hat{l}^{h}\right \}就是预测输出了。在损失方法,SSD采用了和Faster R-CNN相同的smooth L1损失。
在这里插入图片描述
在置信度误差方面,损失函数采用的是softmax loss。
在这里插入图片描述

性能评价

在这里插入图片描述
首先batch size=8这样情况先不考虑,它没有可以对比的东西。batch size = 1的SSD300比YOLO快了一倍多,同时mAP高出一大截;batch size = 1的SSD300比Faster R-CNN的mAP也要高一些。

  • SSD为什么比YOLO还快
    SSD的主干网络要比YOLO更大,因为它在VGG之后又加了很多层,同时SSD的分支全部靠卷积,而不是YOLO一样的reshape,那么为什么SSD的速度最后反而比YOLO小了呢?其实这个比较有一些取巧的地方,因为它们的输入图像不是一样大的,SSD300的输入图像只有300×300300\times300,而YOLO是448×448448\times 448,这为SSD节省下了很多算力。不过从两个角度考虑,300×300300\times300分辨率的图像输入,mAP表现比448×448448\times 448分辨率的图像输入还要好,这也说明了SSD算法确实提升非常大。同时YOLO也有更轻量的版本,FPS可以达到45,但是mAP就更低了,所以SDD并没有对比这个版本。
  • SSD为什么对小目标同样不好
    SSD的小目标校测效果,相比YOLO是有所改善的,因为扩张卷积增大感受野以及在特征图还比较大的时候,就拉取分支。但是相比于大的目标,SSD的小目标检测效果还是稍差一些,这是因为深层的特征图具有足够抽象的语义信息,这保证了目标类可以和背景类分开,但是特征图的尺寸确太小了;而浅层的特征图尺寸足够大,但是语义信息不够,不能保证目标类和背景类的区分。
©️2020 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值