小言_互联网的博客

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

405人阅读  评论(0)


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

  • Mbox_loc
    Conv4_3: 38 × 38 × 16 38\times38\times16 ,Conv7_2: 19 × 19 × 24 19\times19\times24 ,Conv8_2: 10 × 10 × 24 10\times10\times24 ,Conv9_2: 5 × 5 × 24 5\times5\times24 ,Conv10_2: 3 × 3 × 16 3\times3\times16 ,Pool11: 1 × 1 × 16 1\times1\times16
  • Mbox_con
    Conv4_3: 38 × 38 × 84 38\times38\times84 ,Conv7_2: 19 × 19 × 126 19\times19\times126 ,Conv8_2: 10 × 10 × 126 10\times10\times126 ,Conv9_2: 5 × 5 × 126 5\times5\times126 ,Conv10_2: 3 × 3 × 84 3\times3\times84 ,Pool11: 1 × 1 × 84 1\times1\times84

那为啥要控制输出这样的维度呢?
Mbox_loc的维度与特征图上每个点要预测的框的数量有关,六层特征图中每个点分别预测4,6,6,6,4,4个框,每个框需要4个值表达,所以预测为4时,channel为 4 × 4 × = 16 4\times4\times=16 ,预测为6时,channel为 4 × 6 × = 24 4\times6\times=24
Mbox_con的维度与SDD要预测类别置信度和框的数量有关,需要注意的是,SDD将背景类同样作为一个类别参与预测,所以当目标类别是0的时候,SDD实际要预测21个类别的置信度,所以当背景类的置信度最高时,也就意味着没有目标。同时,SDD要对每一个框都输出所有的置信度,这是SSD和YOLO不一样的地方,虽然YOLO的每一个格子也输出两个box,但是置信度确对应格子,而不是对应box, 但是SSD是对每个box都输出对应的置信度,所以当box的数量为4时,channel为 4 × 21 × = 81 4\times21\times=81 ,box的数量为6时,channel为 6 × 21 × = 126 6\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 × 4 k 13\times13\times4k 的reg layer和 13 × 13 × 2 k 13\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 = 8732 38\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采用了一种线性规则:随着特征图层数的加深,特征图逐渐变小,先验框尺度线性增加。
    s k = s m i n + m m a x m m i n m 1 ( k 1 ) , k [ 1 , m ] s_{k}=s_{min}+\frac{m_{max}-m_{min}}{m-1}(k-1),k\in[1,m]
    其中m指的特征图个数,但是 m = 5 m=5 ,而不是6,因为第一层(Conv4_3层)是单独设置的, s k s_k 表示先验框大小相对于图片的比例,而 s m i n s_{min} s m a x s_{max} 表示比例的最小值与最大值,paper里面取0.2和0.9。对于第一个特征图,其先验框的尺度比例一般设置为0.1。所以特征图比例分别是0.1,0.2,0.375,0.55,0.725,0.9。这样对应 300 × 300 300\times300 的输入图像,计算出的尺寸就应该是30,60,112,165,217,270。
    当然还有一组数字是30,60,111,162,213,264,这个是从SSD的caffe源码里求得的。当有当前层的尺度 s k s_{k} 和下一层的尺度 s k + 1 s_{k+1} ,SDD会根据这两个尺寸先计算两个大小不同,但长宽比都是1的正方形先验框,一个长宽是 s k s_{k} ,另一个长宽是 s k × s k + 1 \sqrt {s_{k} \times s_{k+1}} ,需要注意的是,最后一个特征图的尺寸已经没有k+1了,所以这个值是推算出来的315。
    尺寸确定之后,还剩下先验框的比例,这个使用的是 { 2 , 3 , 1 2 , 1 3 } \left \{2,3,\frac{1}{2},\frac{1}{3}\right \} 这组数,都在尺寸为 s k s_{k} 的正方形框上产生,比如比例是2时,计算方式为:
    w = s k 2 w=s_{k}\sqrt{2} h = s k 2 h=\frac{s_{k}}{\sqrt{2}}
    当预设框是4个时,使用 { 2 , 1 2 } \left \{2,\frac{1}{2}\right \} ,预设框是6个时,使用 { 2 , 3 , 1 2 , 1 3 } \left \{2,3,\frac{1}{2},\frac{1}{3}\right \}
  • 如何使用
    这些先验框最终被用于参与目标位置的计算,SSD要预测位置实际上是ground truth和预设框的offset,或者说,预设框被用于重新编码ground truth,这一点和Faster R-CNN很像,假设预设框为 { d c x , d c y , d w , d h } \left \{d^{cx},d^{cy},d^{w},d^{h}\right \} ,ground truth为 { g c x , g c y , g w , g h } \left \{g^{cx},g^{cy},g^{w},g^{h}\right \} ,从公式中可以看出来, { d c x , d c y } \left \{d^{cx},d^{cy}\right \} { g c x , g c y } \left \{g^{cx},g^{cy}\right \} 都表示中心点坐标。那么转换后的ground truth坐标 { g ^ c x , g ^ c y , g ^ w , g ^ h } \left \{\hat{g}^{cx},\hat{g}^{cy},\hat{g}^{w},\hat{g}^{h}\right \} 依照下面方式求取:
    g ^ c x = ( g c x d c x ) d w \hat{g}^{cx}=\frac{\left (g^{cx}-d^{cx} \right )}{d^{w}} g ^ c y = ( g c y d c y ) d h \hat{g}^{cy}=\frac{\left (g^{cy}-d^{cy} \right )}{d^{h}} g ^ w = l o g g w d w \hat{g}^{w}=log{\frac{g_{w}}{d^{w}}} g ^ h = l o g g h d h \hat{g}^{h}=log{\frac{g_{h}}{d^{h}}}

损失函数

SSD的损失函数由两部分组成,分别是位置误差(locatization loss, loc)与置信度误差(confidence loss, conf):

在位置损失中 { g ^ c x , g ^ c y , g ^ w , g ^ h } \left \{\hat{g}^{cx},\hat{g}^{cy},\hat{g}^{w},\hat{g}^{h}\right \} 的求取和上面是一致的,而 { l ^ c x , l ^ c y , 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 × 300 300\times300 ,而YOLO是 448 × 448 448\times 448 ,这为SSD节省下了很多算力。不过从两个角度考虑, 300 × 300 300\times300 分辨率的图像输入,mAP表现比 448 × 448 448\times 448 分辨率的图像输入还要好,这也说明了SSD算法确实提升非常大。同时YOLO也有更轻量的版本,FPS可以达到45,但是mAP就更低了,所以SDD并没有对比这个版本。
  • SSD为什么对小目标同样不好
    SSD的小目标校测效果,相比YOLO是有所改善的,因为扩张卷积增大感受野以及在特征图还比较大的时候,就拉取分支。但是相比于大的目标,SSD的小目标检测效果还是稍差一些,这是因为深层的特征图具有足够抽象的语义信息,这保证了目标类可以和背景类分开,但是特征图的尺寸确太小了;而浅层的特征图尺寸足够大,但是语义信息不够,不能保证目标类和背景类的区分。

转载:https://blog.csdn.net/chaipp0607/article/details/98962500
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场