ssd系列算法总结(一)

目标检测算法“one stage ”算法的一个主要的系列算法SSD是比较有代表性,比较有研究价值,效果相对较好,在SSD算法出现之后,后续又有一系列的算法对SSD针对不同的角度进行改进,不同算法效果均有了很大的改善,了解SSD系列算法的特点,有助于理解目标检测算法的一些基本的思想。

SSD系列算法的主要文章(仅整理自己读过的几篇论文):

SSD:Single Shot MultiBox Detector

DSSD: Deconvolutional Single Shot Detector

FSSD:Feature Fusion Single Shot Multibox Detector

RefineDet: Single-Shot Refinement Neural Network for Object Detection

RfbNet:Receptive Field Block Net for Accurate and Fast Object Detection

M2Det: A Single-Shot Object Detector based on Multi-Level Feature Pyramid Network

Pelee:Pelee: A Real-Time Object Detection System on Mobile Devices

1、SSD

SSD是ECCV2016的一篇文章,算法效果比yolo v1效果好了非常多,可以说开创了应用多尺度的特征图进行目标检测的先河,其后几乎所有的目标检测算法(自己了解知识范围内),均或多或少采用多尺度的思想。

利用多尺度特征图提高目标检测准确率的思想主要来自,浅层特征图包含着位置信息,对于目标定位非常重要;深层的特征图包含大量的语义信息,对图像目标的分类具有重要的意义。

同时,由于深层的特征图anchor所对应的目标的区域较大,例如特征图缩小为原始尺度的64倍,那么这个特征图每个锚点所对应的原始图像目标尺度为64个像素。因而仅仅采用较高层的特征图进行目标检测,很难检测出较小的物体,这也是ssd效果优于yolo的一个主要的原因。

先看结构图:

v2-92ea90571806c0733bca91e805e01610_b.jpg

图片来自ssd论文原文

算法采用Vgg16作为基础特征提取网络,然后分别利用conv43的特征图(下采样3次,尺度缩小为原始大小的1/8左右)、conv7的特征图(在conv4_3基础上下采样一次),这一部分是vgg16,,然后再利用逐步下采样得到的特征图,分别进行检测。

算法的pytorch源码://github.com/amdegroot/ssd.pytorch

ssd算法的配置:

voc = {
    'num_classes': 21,
    'lr_steps': (80000, 100000, 120000),
    'max_iter': 120000,
    'feature_maps': [38, 19, 10, 5, 3, 1],
    'min_dim': 300,
    'steps': [8, 16, 32, 64, 100, 300],
    'min_sizes': [30, 60, 111, 162, 213, 264],
    'max_sizes': [60, 111, 162, 213, 264, 315],
    'aspect_ratios': [[2], [2, 3], [2, 3], [2, 3], [2], [2]],
    'variance': [0.1, 0.2],
    'clip': True,
    'name': 'VOC',
}

其中feature_maps:所使用用来进行目标检测的特征图尺度

steps: 进行目标检测的特征图乘以step,即可映射回原始位置。

aspectratios: 每层特征图的所用的anchor的长宽比。每个aspect_ratio可以产生两个目标框

Conv4_3: 38 × 38 × 4 = 5776
Conv7: 19 × 19 × 6 = 2166
Conv8_2: 10 × 10 × 6 = 600
Conv9_2: 5 × 5 × 6 = 150
Conv10_2: 3 × 3 × 4 = 36
Conv11_2: 4

那么最终一共有先验框8762个。

先验框的设置:pytorch源码,layer/function/priorboxes.py文件说明这个过程。

计算思路:以feature map上每个点的中点为中心(offset=0.5),生成一些列同心的prior box(然后中心点的坐标会乘以step,相当于从feature map位置映射回原图位置),最后会归一化处理

正方形prior box最小边长为min_size,最大边长为

转存失败重新上传取消\sqrt{min *max}

每在priorbox设置一个aspect ratio,会生成2个长方形,长宽为:

转存失败重新上传取消\sqrt{apect}*min​ 和

转存失败重新上传取消1/\sqrt{apect}*min​ ,

因而在conv4_3上会有38×38×4个,两个正方形两个矩形。

同时在预测阶段,依照论文所说预测的时offset,也就是真实的目标框与先验框的坐标转换后的值。也就是一个编码与解码过程。

先验框的位置表示为

转存失败重新上传取消d=(d^{cx}, d^{cy}, d^w, d^h)

对应的真实边界框的位置为

转存失败重新上传取消b=(b^{cx}, b^{cy}, b^w, b^h)

那么预测得到的值l实际为:

转存失败重新上传取消l^{cx} = (b^{cx} - d^{cx})/d^w, \space l^{cy} = (b^{cy} - d^{cy})/d^h

转存失败重新上传取消l^{w} = \log(b^{w}/d^w), \space l^{h} = \log(b^{h}/d^h)

然后再根据预测的值进行解码得到原始的位置

转存失败重新上传取消b^{cx}=d^w l^{cx} + d^{cx}, \space b^{cy}=d^y l^{cy} + d^{cy}

转存失败重新上传取消b^{w}=d^w \exp(l^{w}), \space b^{h}=d^h \exp(l^{h})

如上边代码段所示,在pytorch源码中还存在variance参数,这个参数将得到的预测值进行变换,将原始的预测值,l进行如下变换。然后进行匹配,也就是decode,这种encode与decode源码存在于utils/box_utils.py中。

转存失败重新上传取消l = l*variance

如此基本上的算法的结构及一些实现的细节(包括先验框的设置,编码与解码)介绍清楚。


下一篇将会介绍几种算法的改进思想