论文地址:https://arxiv.org/abs/1512.02325
code地址:https://github.com/weiliu89/caffe/tree/ssd
文章的主要贡献:
We summarize our contributions as follows:
– We introduce SSD, a single-shot detector for multiple categories that is faster than the previous state-of-the-art for single shot detectors (YOLO), and significantly more accurate, in fact as accurate as slower techniques that perform explicit region proposals and pooling (including Faster R-CNN).
– The core of SSD is predicting category scores and box offsets for a fixed set of default bounding boxes using small convolutional filters applied to feature maps.
– To achieve high detection accuracy we produce predictions of different scales from feature maps of different scales, and explicitly separate predictions by aspect ratio.
– These design features lead to simple end-to-end training and high accuracy, even on low resolution input images, further improving the speed vs accuracy trade-off.
– Experiments include timing and accuracy analysis on models with varying input size evaluated on PASCAL VOC, COCO, and ILSVRC and are compared to a range of recent state-of-the-art approaches.
- 提出SSD算法,一种针对多类别的单次检测器,速度比目前主流的YOLO要快,准确率要高,和目前速度较慢的采用区域提议以及池化技术的网络精度差不多(包括Faster R-CNN)
- SSD的核心是使用小的卷积滤波器到特征图上预测类别以及边界框的偏移量
- 根据不同尺度的特征图产生不同尺度的预测,并采用不同的纵横比将预测结果分离开
- 在PASCAL VOC, COCO, 以及ILSVRC数据集上针对不同尺寸的输入进行时间和精度的分析,并于目前最主流的一系列方法进行比较
网络的核心点:
- Multi-scale feature maps for detection
采用多个特征图进行检测,在基础网络(VGG16)后面加上了若干用于预测的卷积特征层,这些特征层的尺寸逐渐缩小,并且针对每一个特征层用于预测的卷积模型是不一样的 - Convolutional predictors for detection
针对用于预测的特征图使用一系列卷积过滤器能够生成一系列固定的预测结果,对于m x n尺寸的特征图,将filter应用到m x n个位置,它能够产生一个输出值,这个输出值包括该边界框包含某一类目标的score(比如共有c类目标,会得出c+1个score,SSD是要计算背景的得分)以及边界框相对于默认框的位置偏移量,不同于YOLO采用全连接层预测类别分数以及框的位置
- Default boxes and aspect ratios
设置不同比率的先验框,在Yolo中,每个单元预测多个边界框,但是其都是相对这个单元本身(正方块),但是真实目标的形状是多变的,Yolo需要在训练过程中自适应目标的形状。而SSD借鉴了Faster R-CNN中anchor的理念,每个单元设置尺度或者长宽比不同的先验框,预测的边界框(bounding boxes)是以这些先验框为基准的,在一定程度上减少训练难度。一般情况下,每个单元会设置多个先验框,其尺度和长宽比存在差异。如图下图所示,可以看到每个单元使用了4个不同的先验框,图片中猫和狗分别采用最适合它们形状的先验框来进行训练
网络结构:
如下图为SSD300网络模型图,可以看到ssd是以vgg16作为基础网络的,以conv4_3, conv7, conv8_2, conv9_2, conv10_2, conv11_2作为网络的特征层用来预测目标的的位置以及置信度,对于特征层的每一个位置预测K个bounding boxes, 对于每一个bb预测c个类别置信度以及4个相对于先验框的偏移量,因此对于一个m*n的特征层,总共要预测 m ∗ n ∗ k 个 b b m*n*k个bb m∗n∗k个bb,以及 m ∗ n ∗ k ∗ ( c + 4 ) m*n*k*(c+4) m∗n∗k∗(c+4)个预测值
训练过程:
- 匹配策略
在训练过程中,首先要确定训练图片中的ground truth(真实目标)与哪个先验框来进行匹配,与之匹配的先验框所对应的边界框将负责预测它。在Yolo中,ground truth的中心落在哪个单元格,该单元格中与其IOU最大的边界框负责预测它。但是在SSD中却完全不一样,SSD的先验框与ground truth的匹配原则主要有两点。首先,对于图片中每个ground truth,找到与其IOU最大的先验框,该先验框与其匹配,这样,可以保证每个ground truth一定与某个先验框匹配。通常称与ground truth匹配的先验框为正样本(其实应该是先验框对应的预测box,不过由于是一一对应的就这样称呼了),反之,若一个先验框没有与任何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一定有一个先验框与之匹配。但是,这种情况我觉得基本上是不存在的。由于先验框很多,某个ground truth的最大 IOU 肯定大于阈值,所以可能只实施第二个原则既可以了,这里的TensorFlow版本就是只实施了第二个原则,但是这里的Pytorch两个原则都实施了 - 损失函数
总损失是置信度损失和位置损失的加权和
位置损失计算:
其中 x i j k x_{ij}^k xijk = {1, 0}作为一个指示器,表明对于类别 k k k第 i i i个先验框与第 j j j个真实框相匹配,有 ∑ i x i j p ≥ 1 \sum_ix_{ij}^p \geq 1 ∑ixijp≥1,与Faster R-CNN相同的是,位置损失回归的是先验框的位置偏移量,采用的是Smooth L1损失。 l l l表示的是预测框, g g g表示的是真实框, d d d表示的是先验框
置信度损失采用的是softmax损失函数
根据交叉验证,权重 α \alpha α的取值为1
-
选择合适尺寸和比率的先验框
先验框的设置,包括尺度(或者说大小)和长宽比两个方面。对于先验框的尺度,其遵守一个线性递增规则:随着特征图大小降低,先验框尺度线性增加:
s k = s