SSD是一种直接预测目标类别和bounding box的多目标检测算法。它使用低层feature map检测小目标,使用高层feature map检测大目标。
一、SSD的优势与劣势
1.优势
(1)没有生成边界框(proposal)的过程,进而提高了速度。
(2)SSD的核心是预测固定的一系列默认边界框的类别分数和边界框偏移,使用更小的卷积滤波器应用到特征映射上。
(3)为了实现高检测精度,我们根据不同尺度的特征映射生成不同尺度的特征映射生成不同尺度的预测,并通过纵横比明确分开预测。
(4)这些设计功能使得即使在低分辨率输入图像上也能实现简单的端到端训练和高精度,从而进一步提高速度与精度之间的权衡。
2.劣势
(1)需要人工设置prior box的min_size,max_size和aspect_ratio值。网络中prior box的基础大小和形状不能直接通过学习获得,而是需要手工设置。而网络中每一层feature使用的prior box大小和形状恰好都不一样,导致调试过程非常依赖经验。
(2)虽然采用了pyramdial feature hierarchy的思路,但是对小目标的recall依然一般,并没有达到碾压Faster RCNN的级别。作者认为,这是由于SSD使用conv4_3低级feature去检测小目标,而低级特征卷积层数少,存在特征提取不充分的问题。
二、模型
1.概述
SSD方法基于前馈卷积网络,该网络产生固定大小的边界框集合,并对这些边界框中存在的目标类别实例进行评分,然后进行非极大值抑制步骤来产生最终的检测结果。然后,我们将辅助结构添加到网络中以产生具有以下关键特征的检测:
用于检测的多尺度特征映射。我们将卷积特征层添加到截取的基础网络的末端。这些层在尺寸上逐渐减小,并允许在多个尺度上对检测结果进行预测。用于预测检测的卷积模型对于每个特征层都是不同的。
用于检测的卷积预测器。每个添加的特征层(或者任选的来自基础网络的现有特征层)可以使用一组卷积滤波器产生固定的检测预测集合。对于具有p通道的大小为m×n的特征层,潜在检测的预测参数的基本元素是3×3×p的小核得到某个类别的分数,或者相对于默认框坐标的形状偏移。在应用卷积核的m×n的每个位置,它会产生一个输出值。边界框偏移输出值是相对每个特征映射位置的相对默认框位置来度量的。
默认边界框和长宽比。对于网络顶部的多个特征映射,我们将一组默认边界框与每个特征映射单元相关联。默认边界框以卷积的方式平铺特征映射,以便每个边界框相对于其对应单元的位置是固定的。在每个特征映射单元中,我们预测单元中相对于默认边界框形状的偏移量,以及指出每个边界框中存在的每个类别实例的类别分数。具体而言,对于给定位置处的k个边界框中的每一个,我们计算c个类别分数和相对于原始默认边界框形状的4个偏移量。这导致在特征映射中的每个位置周围应用总共(c+4)k个滤波器,对于m×n的特征映射取得(c+4)kmn个输出。我们的默认边界框与Faster R-CNN[2]中使用的锚边界框相似,但是我们将它们应用到不同分辨率的几个特征映射上。在几个特征映射中允许不同的默认边界框形状让我们有效地离散可能的输出框形状的空间。
2.基础
feature map cell:是指feature map中每一个小格子,就是上图中的每个小方格,上图分别有64个feature map cell和16个feature map cell.
default box:是指每个feature map cell上都有一系列固定大小的box,也就是上图中的虚线框。
ground truth: 在机器学习中,数据是有标注的
truth。就好像上图中x是框的信息,t就是猫或狗的信息。
prior box:是指在实际选择fdefault box 过程中(在实际选择中我们并不是
每个feature map cell的k个default box都取)也就是说default box是一种概念,prior box则是实际的选取。
训练中一张完整的图片送进网络获得各个feature map,对于正样本训练来说,需要先将prior box与ground truth box做匹配(就是把一张图片输入到 region network中,判断有物体的区域就是prior box,可以看一下fast rcnn的解释),匹配成功说明这个prior box所包含的是个目标,但离完整目标的ground truth box还有段距离,训练的目的是保证default box的分类confidence的同时将prior box尽可能回归到ground truth box。
举个列子:在上图中一个训练样本中有2个ground truth box,所有的feature map中获取的default box一共有8732个。那个可能分别有10、20个prior box能分别与这2个ground truth box匹配上。训练的损失包含定位损失和回归损失两部分。
假设每个feature map cell有k个default box,那么对于每个default box都需要预测c个类别score和4个offset,那么如果一个feature map的大小是m×n,也就是有mn个feature map cell,那么这个feature map就一共有(c+4)k * mn 个输出。这些输出个数的含义是:采用3×3的卷积核对该层的feature map卷积时卷积核的个数,包含两部分(实际code是分别用不同数量的33卷积核对该层feature map进行卷积):数量ckmn是confidence输出,表示每个default box的confidence,也就是类别的概率;数量4kmn是localization输出,表示每个default box回归后的坐标)
卷积核配置 :假设Feature Map通道数为P,SSD网络中每个Stage的卷积核大
小统一为33p。其中padding和stride都为1。保证卷积后的Feature Map和卷积前是一样大小。
卷积滤波器 :每个Feature Map上mxn个大小的特征点对应K个Default Boxes,假设类别数+背景=c,最终通过卷积滤波器得到c+4维特征向量。那么一个Feature Map上的每个点就需要使用kx(c+4)个这样的滤波器。
3.prior box(default box)
https://blog.csdn.net/rainforestgreen/article/details/82762274
4.网络结构
算法的主网络结构是VGG16,将最后两个全连接层改成卷积层,并随后增加了4个卷积层来构造网络结构。对其中5种不同的卷积层的输出(feature map)分别用两个不同的 3×3 的卷积核进行卷积,一个输出分类用的confidence,每个default box 生成21个类别confidence;一个输出回归用的 localization,每个 default box 生成4个坐标值(x, y, w, h)。此外,这5个feature map还经过 PriorBox 层生成 prior box(生成的是坐标)。上述5个feature map中每一层的default box的数量是给定的(8732个)。最后将前面三个计算结果分别合并然后传给loss层。
SSD的结构在VGG16网络的基础上进行修改,训练时同样为conv1_1,conv1_2,conv2_1,conv2_2,conv3_1,conv3_2,conv3_3,conv4_1,conv4_2,conv4_3,conv5_1,conv5_2,conv5_3(512),fc6经过331024的卷积(原来VGG16中的fc6是全连接层,这里变成卷积层,下面的fc7层同理),fc7经过111024的卷积,conv6_1,conv6_2(对应上图的conv8_2),conv7_1,conv7_2,conv,8_1,conv8_2,conv9_1,conv9_2,loss。
然后一方面:针对conv4_3(4),fc7(6),conv6_2(6),conv7_2(6),conv8_2(4),conv9_2(4)(括号里数字是每一层选取的default box种类)中的每一个再分别采用两个33大小的卷积核进行卷积,这两个卷积核是并列的(括号里的数字代表prior box的数量,可以参考Caffe代码,所以上图中SSD结构的倒数第二列的数字8732表示的是所有prior box的数量,是这样来的38384+19196+10106+556+334+114=8732)。这两个33的卷积核一个是用来做localization的(回归用,如果prior box是6个,那么就有64=24个这样的卷积核,卷积后map的大小和卷积前一样,因为pad=1,下同),另一个是用来做confidence的(分类用,如果prior box是6个,VOC的object类别有20个,那么就有6(20+1)=126个这样的卷积核)。
知道prior box如何产生的,下面分析如何使用。以conv4_3为例:
在conv4_3 feature map网络pipeline分为了3条线路:
(1)经过一次batch norm+一次卷积后,生成了[1, num_classnum_priorbox, layer_height, layer_width]大小的feature用于softmax分类目标和非目标(其中num_class是目标类别,SSD 300中num_class = 21)
(2)经过一次batch norm+一次卷积后,生成了[1, 4num_priorbox, layer_height, layer_width]大小的feature用于bounding box regression(即每个点一组[dxmin,dymin,dxmax,dymax])
(3)生成了[1, 2, 4*num_priorbox]大小的prior box blob,其中2个channel分别存储prior box的4个点坐标和对应的4个variance
缩进后续通过softmax分类+bounding box regression即可从priox box中预测到目标,熟悉Faster RCNN的读者应该对上述过程应该并不陌生。其实pribox box的与Faster RCNN中的anchor非常类似,都是目标的预设框,没有本质的差异。区别是每个位置的prior box一般是4~6个,少于Faster RCNN默认的9个anchor;同时prior box是设置在不同尺度的feature maps上的,而且大小不同。 缩进还有一个细节就是上面prototxt中的4个variance,这实际上是一种bounding regression中的权重。在图4线路(2)中,网络输出[dxmin,dymin,dxmax,dymax],其中的dxmin等可以参考这篇文章 https://blog.csdn.net/wfei101/article/details/79809332
Permute,Flatten And Concat Layers
上面以conv4_3 feature map分析了如何检测到目标的真实位置,但是SSD 300是使用包括conv4_3在内的共计6个feature maps一同检测出最终目标的。在网络运行的时候显然不能像图6一样:一个feature map单独计算一次softmax socre+box regression(虽然原理如此,但是不能如此实现)。那么多个feature maps如何协同工作?这时候就要用到Permute,Flatten和Concat这3种层了。
Permute是SSD中自带的层,上面conv4_3_norm_mbox_conf_perm的的定义。Permute相当于交换caffe blob中的数据维度。在正常情况下caffe blob的顺序为: bottom blob = [batch_num, channel, height, width]
经过conv4_3_norm_mbox_conf_perm后的caffe blob为: top blob = [batch_num, height, width, channel]
而Flattlen和Concat层都是caffe自带层。
总结:Permute起到交换的作用,例如卷积后的维度为32241919,则交换后为32191924;Flattlen的作用是将32191924变为328664,32是batchsize的大小,另一方面结合conv4_3(4),fc7(6),…中的每一个和数据层(ground truth boxes)经过prior Box层生成prior box;Concat 在前面所列的5个卷积层输出都执行上述操作后,将结果进行合并,是通道合并而不是数值相加。
那么接下来以conv4_3和fc7为例分析SSD是如何将不同size的feature map组合在一起进行prediction。图展示了conv4_3和fc7合并在一起的过程中caffe blob shape变化(其他层类似,考虑到图片大小没有画出来,请脑补)。
对于conv4_3 feature map,conv4_3_norm_priorbox(priorbox层)设置了每个点共有4个prior box。由于SSD 300共有21个分类,所以conv4_3_norm_mbox_conf的channel值为num_priorbox * num_class = 4 * 21 = 84;而每个prior box都要回归出4个位置变换量,所以conv4_3_norm_mbox_loc的caffe blob channel值为4 * 4 = 16。
fc7每个点有6个prior box,其他feature map同理。 经过一系列图7展示的caffe blob shape变化后,最后拼接成mbox_conf和mbox_loc。而mbox_conf后接reshape,再进行softmax(为何在softmax前进行reshape,Faster RCNN有提及)。 最后这些值输出detection_out_layer,获得检测结果。
三、训练
1.正负样本
将prior box 和 grount truth box 按照IOU(JaccardOverlap)进行匹配,匹配成功则这个prior box就是positive example(正样本),如果匹配不上,就是negative example(负样本),显然这样产生的负样本的数量要远远多于正样本。这里将前向loss进行排序,选择最高的num_sel个prior box序号集合 D。那么如果Match成功后的正样本序号集合P。那么最后正样本集为 ,负样本集为。同时可以通过规范num_sel的数量(是正样本数量的三倍)来控制使得最后正、负样本的比例在 1:3 左右。
jaccard overlap 就是交并比 ,也就是IOU
正样本:
我们已经在图上画出了prior box,同时也有了ground truth,那么下一步就是将prior box匹配到ground truth上。值得注意的是先是从groudtruth box出发给每个groudtruth box找到了最匹配的prior box放入候选正样本集,然后再从prior box出发为prior box集中寻找与groundtruth box满足IOU>0.5IOU>0.5的一个IOU最大的prior box(如果有的话)放入候选正样本集,这样显然就增大了候选正样本集的数量。
负样本:
在生成一系列的 prior boxes 之后,会产生很多个符合 ground truth box 的 positive boxes(候选正样本集),但同时,不符合 ground truth boxes 也很多,而且这个 negative boxes(候选负样本集),远多于 positive boxes。这会造成 negative boxes、positive boxes 之间的不均衡。训练时难以收敛。
因此,本文采取,先将每一个物体位置上对应 predictions(prior boxes)loss 进行排序。 对于候选正样本集:选择最高的几个prior box与正样本集匹配(box索引同时存在于这两个集合里则匹配成功),匹配不成功则删除这个正样本(因为这个正样本不在难例里已经很接近ground truth box了,不需要再训练了);对于候选负样本集:选择最高的几个prior box与候选负样本集匹配,匹配成功则作为负样本。
这就是一个难例挖掘的过程,举个例子,假设在这8732个prior box里,经过FindMatches后得到候选正样本P个,候选负样本那就有8732−P个。将prior box的prediction loss按照从大到小顺序排列后选择最高的M个prior box。如果这P个候选正样本里有a个box在这M个prior box里,将这a个box从候选正样本集中踢出去。如果这8732−P个候选负样本集中包含的8732−P有M−a个在这M个prior box,则将这M−a个候选负样本作为负样本。SSD算法中通过这种方式来保证 positives、negatives 的比例。实际代码中有三种负样本挖掘方式:
Data augmentation
本文同时对训练数据做了 data augmentation,数据增广。
每一张训练图像,随机的进行如下几种选择:
(1)使用原始的图像
(2)随机采样多个 patch(CropImage),与物体之间最小的 jaccard overlap 为:0.1,0.3,0.5,0.7 与 0.9
采样的 patch 是原始图像大小比例是 [0.3,1.0],aspect ratio 在 0.5 或 2。
当 groundtruth box 的 中心(center)在采样的 patch 中且在采样的 patch中 groundtruth box面积大于0时,我们保留CropImage。
在这些采样步骤之后,每一个采样的 patch 被 resize 到固定的大小,并且以 0.5 的概率随机的 水平翻转(horizontally flipped,翻转不翻转看prototxt,默认不翻转)
这样一个样本被诸多batch_sampler采样器采样后会生成多个候选样本,然后从中随机选一个样本送人网络训练。
2.模型损失
对于SSD,虽然paper中指出采用了所谓的“multibox loss”,但是依然可以清晰看到SSD loss分为了confidence loss和location loss两部分,其中N是match到GT(Ground Truth)的prior box数量;而α参数用于调整confidence loss和location loss之间的比例,默认α=1。SSD中的confidence loss是典型的softmax loss:
其中代表第i个prior box匹配到了第j个class为p类别的GT box;而location loss是典型的smooth L1 loss:
参考:https://zhuanlan.zhihu.com/p/31427288
https://blog.csdn.net/wweiainn/article/details/82831701
https://blog.csdn.net/rainforestgreen/article/details/82762274