在SSD之前,目标检测的主流方法主要分为两大类:
于是为了让检测过程又快又准确,SSD就被提出来了。SSD借鉴了YOLO的one-stage的思想,直接对bbox进行回归和分类,同时也参考了Faster R-CNN中的anchor机制来提升准确率。通过将两种方法的优点结合,并加以改进,SSD保持了很快的检测速度,同时还提高了检测的准确率。
和YOLO类似,SSD也是one-stage的检测方法,即使用一个神经网络直接进行分类和回归,但是为了提高准确率,SSD做了以下改进:
在文中,SSD使用VGG16来做为base network,然后在VGG16的基础上添加了新的卷积层以获得不同size的feature map,具体的网络结构如下图所示:
首先对基础网络VGG16进行了修改,其中Conv5_3之前的卷积层保持不变,而原来的FC6和FC7分别变成
为了预测每个anchor的类别和位置offset,SSD将这6个的特征图分别输入到两个
如下图所示,负责localization的卷积,会输出
得到检测结果之后,再进行非极大值抑制(NMS)来删除掉多余的boxes,便得到最终的检测结果。NMS的具体过程可以参考我这篇文章:Jacqueline:【目标检测】基础知识:IoU、NMS、Bounding box regression
在训练时,我们首先要确定哪个anchor对应哪个ground truth box。在SSD中主要采取了两种匹配策略;(1)对于每个ground truth box,首先将它匹配给和它有最大的IoU(jaccard overlap)的anchor。这样可以保证对于每一个ground truth box都有一个anchor来对应。这些和ground truth对应的anchor为正样本,然后没有匹配到的anchor为负样本,由于一张图中ground truth较少,而最后得到的anchor数量又很多,所以这种方法就会导致正负样本的极不平衡,所以需要第二种匹配策略来缓解。(2)第二种匹配策略就是对于剩余的anchor,如果它和某个ground truth box的IoU大于某个阈值(0.5),那么将这个ground truth box匹配给这个anchor,如果某个anchor和多个ground truth box的IoU大于阈值,那么选择IoU最大的ground truth进行匹配。这样一个ground truth就对应多个anchor,但是每个anchor只能对应一个ground truth。
虽然在上述的匹配过程中一个ground truth可以对应多个anchor,但是由于ground truth box的数量和anchor的数量相差好几个量级,所以正负样本的数量还是很不均衡,因此文中采取了Hard negative mining策略。具体就是:对所有的负样本按照置信度loss(预测背景的置信度越小,loss越大)进行降序排列,然后选取top-k个作为负样本,以保证正负样本的比例为1:3。实验证明,这样可以加快收敛速度,使得整个训练过程更稳定。
目标检测算法的损失函数一般分为两个部分:置信度误差 (confidence loss)和位置误差(localization loss),SSD的损失函数同样也是这两部分的加权和:
其中,
置信度误差
置信度误差是计算预测的类别置信度
其中,
位置误差
位置误差是用来计算预测的位置信息和ground truth位置信息之间的误差:采用的是smooth L1 loss:
和Faster R-CNN相同,预测结果输出的4个值分别为anchor的中心点和宽高的offset(
SSD会为不同size的feature map设置不同大小和数目的anchor。在SSD300中,共有6个feature map,每层对应的anchor数分别为4,6,6,6,4,4。而每层feature map都有两个参数min_size和max_size,分别代表该层上anchor的最小scale和最大scale。其中,每层的anchor的scale按照下式进行计算:
其中,
如下图所示,在计算anchor时,首先,为feature map上的每个点都设置两个正方形的anchor,其中小正方形的长用min_size来表示,大正方形的长用
此外,每个点还有多个长方形的anchor,长方形anchor的数目每层也不同,由每层anchor的数目决定,长方形anchor的长宽由下式决定:
其中,ratio为长宽比,值域为{
计算好anchor的位置之后,我们还需要判断anchor是否超出图片的边缘,对于超出图片边缘的anchor,我们需要进行clip,如下图所示:
为了提高算法对不同size和shape的object的鲁棒性,SSD对训练数据进行了数据扩增,主要方法包括:有水平翻转(horizontal flip),随机裁剪(random crop),颜色扭曲(color distortion),随机采集块域(Randomly sample a patch)等。
整个测试过程比较简单,就是将测试样本输入到SSD网络中,然后网络会为每个anchor输出类别和位置预测结果。之后,根据类别的预测值确定每个anchor的类别,并过滤掉那些属于背景的anchor,然后根据类别置信度阈值过滤掉置信度较低的anchor。对于留下来的anchor,再根据预测的位置offset进行位置变换,得到预测的box。得到预测的box之后,再根据box的类别置信度进行降序排列,然后保留前k个box。最后进行NMS,去掉重叠度高的box,NMS之后剩下的box就为最终的检测结果。
最后,给出一张性能比较图,图中包括了two-stage和one-stage的比较经典的目标检测算法,并对这些算法的检测速度和精确度进行了比较。可以看出,SSD300的的检测速度和精确度都高于这些算法。而SSD512可以获得更高的精确度,但是检测速度也会慢一些,但也和YOLO的检测速度持平,而且也快于two-stage的方法。
本文提出了一种新的one-stage的目标检测方法SSD,主要包括以下的改进和创新:使用多尺度feature map,使用卷积层来进行预测,在不同层设置不同大小和数目的anchor,限制正负样本的比例、数据扩增。这些改进使得SSD检测的速度和准确度都优于state-of-the-art。但是,SSD也仍有不足之处,那就是在小目标检测方面,其准确度仍然不敌Faster R-CNN。
本文都是根据个人理解编写的,希望可以帮到大家。此外,如有误,烦请指正。如果喜欢,请点赞哦,谢谢~
我将持续更新目标检测领域的经典paper,欢迎大家订阅哦!