目标检测算法面试基础知识合集RCNN、Fast RCNN、FasterRCNN、YOLO系列、SSD、FPN、RetinaNet
目标检测算法
R-CNN
- 利用selective search提出region proposal(RP),将这些RP warp到统一的大小。
- 将上一步的RP一个接一个串联的送入卷积神经网络提取特征,并将这些特征保存到硬盘上。
- 读取硬盘上保存的特征送入SVM进行分类。
- 将SVM分类好的RP送入bbox regressor进行回归处理。
优点
- 使用了卷积神经网络进行特征提取。
- 使用bounding box regression进行目标包围框的修正。
- 精度显著提高,PASCAL VOC2010从35.1%到53.7%。
- 将CNN网络应用于目标检测领域并实现了图像特征自动提取。
缺点
- 耗时的selective search,对一帧图像,需要花费2s。
- 耗时的串行式CNN前向传播,对于每一个RoI,都需要经过一个AlexNet提特征,为所有的RoI提特征大约花费47s。
- 三个模块是分别训练的,并且在训练的时候,对于存储空间的消耗很大。
SPP-Net
pipeline
- 同样也用selective search等方法提取出候选区域(RP)。
- 对原图进行一次特征提取,计算出RP在feature map上的映射patch。
- 将patch送入spp layer统一池化到相同的大小。
- 在送到之后的层,完成分类和回归。
优点
- 引入了空间金字塔池化,适应各种不同尺寸的特征图。
- R-CNN要对每个RP算一次卷积,而SPP-Net只算一次卷积,再找出RP在feature map对应的patch,通过spp layer统一到同样大小,节约了大量时间。
缺点
- 同样该网络不是end-end的。
Fast R-CNN
pipeline
- 同样也是用selective search选择出2000个region proposal(RP)。
- (像SPP-Net一样)对原图进行一次特征提取,找到RP在feature map上映射的patch,将patch送入ROI pooling layer统一下采样到7 x 7。
- 之后跟全连接层,使用softmax替代SVM分类,同时利用多任务损失函数边框回归也加入到了网络中,这样整个的训练过程是端到端的(除去Region Proposal提取阶段)。
优点
- 引入spp pooling,只用对图像做一次特征提取然后在feature map上找到对应patch,pool到统一大小。
- 引入多任务学习,分类和回归共享卷积特征。
- 除去region proposal外整个网络是end to end的。
- 在VOC2012的mAP提升到了68.4%,而R-CNN为62.4%。
缺点
- 还是要预先提取region proposal,非常耗时。
Faster R-CNN
主要改变是取消了region proposal,提出一个新的网络region proposal network(RPN)来生成待检测区域。
pipeline
- 使用共享的卷积层提取图片特征,将提取到的特征送入RPN生成待检测框,并对待检测框进行修正。
- 根据RPN的输出在feature map上选取对应的patch,送入ROI pooling layer,输出统一大小(6 x 6)。
- 之后和Fast R-CNN一样,送入全连接层,然后进行回归和分类。
优点
- Faster R-CNN是真真正正的end to end的网络。
- 采用了先验框,网络学习的是对于先验框的偏移,比直接学习框的位置要容易些。
- 在GPU上达到了实时(5fpsbased VGG & 17fps based ZF)。
- 精度高了,COCO检测42.1%,而Fast R-CNN为39.3%。
缺点
- 对小物体的检测还是不太好。
- 速度还是不够快。
细节
因为faster r-cnn的细节较多,这里单列一个小节来着重讲解。
-
RPN
RPN在feature map上先进行3 x 3的滑动窗口卷积且output_channels = 256,之后在分别进行两个1 x 1的卷积 ,第一个卷积是输出cls,输出channel为2 * k(2是二分类,判断anchor是前景还是背景,即判断这个anchor里有没有目标,k是anchaor数量,文中设置为9);第二个卷积是输出reg,输出channel为4 * k(4是anchor的4个坐标偏移量[x, y, w, h],k同上)。
- k个anchor
文中为每个位置预先设定好了k=9个长宽比与面积的先验框,这9个先验框包含三种面积(128 x128,256 x 256, 512 x 512),每种面积又包含三种长宽比(1:1,1:2, 2:1) 。
- anchor的分类
anchor的分类采用softmaxLoss进行训练,那么anchor的label是什么呢?文中做出了如下定义:如果一个anchor与ground truth的IoU在0.7以上,那这个anchor就算前景(positive)。类似地,如果这个anchor与ground truth的IoU在0.3以下,那么这个anchor就算背景(negative)。在作者进行RPN网络训练的时候,只使用了上述两类anchor,与ground truth的IoU介于0.3和0.7的anchor没有使用。而由于一张图生成的anchor数量比较多(对于40 x 60的特征图,有40 x 60 x 9 = 21600个),因此随机抽取128个前景anchor与128个背景anchor进行训练。
- anchor的回归
anchor的回归主要是训练anchor的修正值[],这四个值的意思是修正后的anchor在原来anchor基础上x和y方向上的偏移(由决定),并且长宽放大一定倍数(由决定)。让我们看看[]的公式定义:
x, y, w, h分别代表anchor的中心点坐标和宽高。x代表预测的anchor,代表事先设置的先验anchor,代表ground truth的anchor(对于y, w, h都同理)。
anchor的回归损失函数采用smooth l1函数,需要注意,只对有物体(前景)的anchor,即只对positive的anchor进行边框修正。
- RPN总的loss
其中第一个loss即为anchor分类loss(softmaxLoss),第二个loss为anchor回归loss(smooth l1 loss),为了保持两部分loss均衡,为mini-batch的数量=256,为anchor的location数量$\approx\lambda$设置为10能保持两部分均衡。
-
ROI pooling
得到RPN提出的region后,将其映射到对应的feature map的patch上,然后通过该层将特征转化成一样的大小**(6 x 6)**。
-
Classifier
此部分就是Fast R-CNN的分类器和RoI边框修正训练。分类器主要是分这个提取的RoI具体是什么类别(人,车,马等等),一共C+1类(包含一类背景)。RoI边框修正和RPN中的anchor边框修正原理一样,同样也是SmoothL1 Loss,值得注意的是,RoI边框修正也是对于非背景的RoI进行修正,对于类别标签为背景的RoI,则不进行RoI边框修正的参数训练。
-
训练方式
对于Faster R-CNN的训练方式有三种,可以被描述如下:
-
RPN和Fast R-CNN交替训练,这种方式也是作者采用的方式。
-
近似联合RPN和Fast R-CNN的训练,在训练时忽略掉了RoI边框修正的误差,也就是说只对anchor做了边框修订,这也是为什么叫"近似联合"的原因。
-
联合RPN和Fast R-CNN的训练。
对于作者采用的交替训练的方式,步骤如下:
-
使用在ImageNet上预训练的模型初始化共享卷积层并训练RPN。
-
使用上一步得到的RPN参数生成RoI proposal。再使用ImageNet上预训练的模型初始化共享卷积层,训练Fast R-CNN部分(分类器和RoI边框修订)。
-
将训练后的共享卷积层参数固定,同时将Fast R-CNN的参数固定,训练RPN。(从这一步开始,共享卷积层的参数真正被两大块网络共享)
-
同样将共享卷积层参数固定,并将RPN的参数固定,训练Fast R-CNN部分。
-
YOLOv1
pipeline
- resize图片到统一大小,因为Detection需要图片的一些细粒度的信息,所以本文中使用高分辨率的输入:448 x 448 。
- 图片输入经过卷积层,全连接层,最后得到7 x 7 x 30的输出。
- 对上述输出进行回归修正。
优点
- 速度快,它是一个single-stage的检测方法,直接使用一个卷积神经网络就可以同时预测bounding box的位置和类别。
- 将目标检测问题转化为一个回归问题求解。
- 直接使用整幅图来进行检测,因此可以encode全局信息,所以可以减少将背景检测为物体的错误。
- 泛化能力强,因为YOLO可以学习到高度泛化的特征,所以可以迁移到其他领域。
缺点
- 因为YOLO中每个cell只预测两个bbox和一个类别,这就限制了能预测重叠或邻近物体的数量,比如说两个物体的中心点都落在这个cell中,但是这个cell只能预测一个类别。
- 不像Faster R-CNN一样预测offset,YOLO是直接预测bbox的位置的,这就增加了训练的难度。
- YOLO是根据训练数据来预测bbox的,但是当测试数据中的物体出现了训练数据中的物体没有的长宽比时,YOLO的泛化能力就变弱了。
- 同时经过多次下采样,使得最终得到的feature的分辨率比较低,就是得到coarse feature,这可能会影响到物体的定位,对小物体检测不太好。
细节
-
YOLO首先会把输入图片分成S x S个grid cell(文中S = 7),若某个物体的中心点落到某个格子中,则该格子负责预测该物体。
-
对于每个格子,YOLO会预测出B个(文中B = 2)bounding box(bbox),而对于每个bbox,会预测出5个值,分别是4个位置值[x, y, w, h]和1个置信度confidence。
- bbox的位置值[x, y, w, h]:(x, y)是bbox的中心点位置,其值是相对于grid cell归一化到0-1之间。(w, h)是bbox的宽和高,这个是相对于整张图片的,即w=bbox实际的宽/图片的宽,h=bbox实际的高/图片的高,这样做可以将w和h归一到0-1之间,这有利于之后的回归。
- bbox的confidence:每个bbox都有个confidence,表示预测的bbox包含一个物体的置信度,计算公式为:,从公式我们可以看出该置信度包含了两个方面:一是该bbox是否包含物体,二是bbox和ground truth的IOU。可以看出如果一个bbox不包含物体,那它的置信度为0,如果包含物体,它的置信度为何gt的IOU。
-
YOLO还会为每个格子进行分类,一共有C类(在VOC上C = 20),为每个grid cell预测一组条件概率:,grid cell中的B个bbox共享这个概率值。
-
除最后一层外,每一层都用的是leaky ReLU**函数。
-
7 x 7 x 30的输出是怎么来的呢?首先被划分为S x S个格子,S = 7,然后每个格子有B个bbox,每个bbox有4个位置值和1个confidence,同时还有C个类别。因此总数为B x (4 + 1) + C = 2 x 5 + 20 = 30。
-
loss:loss是通过和gt的sum-squared error进行计算的,主要分为以下几个部分:
- 位置误差:计算bbox和gt的[x, y, w, h]误差,需要注意的是,并不是所有bbox都参与计算,首先需要格子里有object,然后该格子里和gt有最大iou的bbox参与loss计算,其他bbox都不参与。 此外,因为误差在小的box上体现的更明显,就是一点点小的位置上的偏差可能对大的box影响不是很大,但是对小的box的影响就比较明显了,所以为了给不同size的box的位置loss赋予不同的‘权重’,需要对w和h开方后才进行计算。因为根据 的函数图像可知,当x较小时,x的一点小的变化都会导致y大的变化,而当x较大的时候,x的一点儿小的变化不会让y的变化太大。 但这个方法只能减弱这个问题,并不能彻底解决这个问题。
- 置信度误差:置信度误差的计算分两种情况,一种是有object的格子,一种是没有object的格子,两种情况都是所有的bbox参与计算,也是计算平方误差。对于有object的cell中的bbox的置信度的ground truth就是。需要注意的是这个IOU是在训练过程中不断计算出来的,因为网络在训练过程中每次预测的bbox是变化的,所以bbox和ground truth计算出来的IOU每次也会不一样。而对于没有object的cell中的bbox的置信度的ground truth为 = 0,因为不包含物体。
- 分类误差:在本文中将分类误差当作回归误差来计算,使用sum-squared error来计算分类误差,需要注意的是只有包含object的cell才参与分类loss的计算,即object中心点落入的cell才进行分类loss的计算,而这个cell的ground truth label就是该物体的label。
- 此外,为了使三种误差达到平衡,给不同的误差赋予不同的权重:
- 首先在目标检测问题中,localization的误差比分类的误差更重要,所以给位置误差赋予更大的权重,记为 。
- 其次,因为一张图中大多数的bbox都是没有物体的,那么这些bbox的confidence的误差就会产生比较大的影响,甚至会影响到少量的含有object的bbox的误差优化,就是会产生一个overpowering,我猜测就是对于大部分的bbox来说优化loss是为了让这些bbox的confidence变为0,只有少量的是让confidence接近一个非零值,所以最后优化的结果可能是所有的bbox的confidence都变成0。为了避免这个问题,我们就需要赋予不含物体的bbox的confidence loss更小的权重,记为 。
- 总结起来就是:对于有object的cell,那么计算cell的分类误差,然后cell中两个bbox的置信度误差,然后cell中和ground truth box的IoU最大的bbox的位置误差。对于没有object的cell,那就只计算cell中两个bbox的置信度误差。
-
在测试的时候:
输入一张图到网络,得到7 x 7 x 30的结果,计算一下每个bbox的class-specific confidence score:
则对于7 x 7 x B个bbox我们可以得到98个score,然后对这98个bbox根据score进行NMS,最后得到结果。
YOLOv2
这篇文章实际介绍了两个模型:YOLOv2和YOLO9000
pipeline
- resize图片到统一大小,因为Detection需要图片的一些细粒度的信息,所以本文中使用高分辨率的输入:448 x 448 。
- 相比于YOLOv1,v2移除掉了全连接层,而全部改为了卷积层,输出结果。
- 对输出进行回归修正。
优点
- 采用Multi-Scale Training策略,提升网络对不同训练数据的泛化能力。
- 提高了anchor的recall。
- 使用聚类产生的锚点代替Faster R-CNN和SSD手工设计的anchor。
- 在高分辨率图像上进行迁移学习,提升网络对高分辨图像的响应能力
缺点
在当时来看没啥大的缺点,不如SSD算一个?
细节
-
采用了BN来加快模型收敛,而且可以起到正则化的作用,防止模型过拟合,并且不再使用dropout,使用Batch Normalization后,YOLOv2的mAP提升了2.4%。
-
YOLOv1在采用224 x 224分类模型预训练后,直接将分辨率增加至448 x 448在检测数据集上fine-tune,但是直接切换分辨率,检测模型可能难以快速适应高分辨率,所以YOLOv2增加了在ImageNet数据集上使用448 x 488输入来finetune分类网络这一中间过程(10 epochs),这可以使得模型在检测数据集上finetune之前已经适用高分辨率输入。使用高分辨率分类器后,YOLOv2的mAP提升了约4%。不过值得强调的是,**YOLOv2采用的是416 x 416的输入。**因为YOLOv2模型下采样的总步长为32,对于416 x 416的图片,最后得到的特征图大小为13 x 13。
-
YOLOv2借鉴了Faster R-CNN中RPN网络的先验框(anchor boxes,prior boxes,SSD也采用了先验框)策略,所以YOLOv2移除了YOLOv1中的全连接层而采用了卷积和anchor boxes来预测边界框。
-
YOLOv2使用了anchor boxes之后,每个位置的各个anchor box都单独预测一套分类概率值,在YOLOv1中,每个cell预测一个分类概率值供所有box共享。
-
在Faster R-CNN和SSD中,先验框的维度(长和宽)都是手动设定的,带有一定的主观性。如果选取的先验框维度比较合适,那么模型更容易学习,从而做出更好的预测。因此,YOLOv2采用k-means聚类方法对训练集中的边界框做了聚类分析,聚类分析时选用box与聚类中心box之间的IOU值作为距离指标:
随着聚类中心数目的增加,平均IOU值(各个边界框与聚类中心的IOU的平均值)是增加的,但是综合考虑模型复杂度和召回率,作者最终选取5个聚类中心作为先验框。
-
YOLOv2也像Faster R-CNN那样预测anchor boxes的偏移。anchor的实际中心点位置为(x, y)需要根据预测的坐标偏移值(, ),先验框的宽高()及中心点坐标()来计算。
但是上面的公式是无约束的,预测的边界框很容易向任何方向偏移。所以,YOLOv2弃用了这种预测方式,而是沿用YOLOv1的方法,就是预测边界框中心点相对于对应cell左上角位置的相对偏移值,为了将边界框中心点约束在当前cell中,使用sigmoid函数处理偏移值,这样预测的偏移值在(0,1)范围内(每个cell的尺度看做1)。总结来看,根据边界框预测的4个offsets ,可以按如下公式计算出边界框实际位置和大小:
其中代表对应cell的左上角坐标,代表先验框的宽高,值是相对于特征图大小的。在这里我们记特征图的大小为(W, H)。则我们可以算出anchor相对于整个特征图的位置:
如果再将上面的4个值分别乘以原图片的宽度和长度就可以得到边界框的最终位置和大小了。 -
YOLOv2的输入图片大小是416 x 416,经过32倍下采样得到的feature map大小为13 x 13,该大小的特征图对于检测大物体够了,**但是对于检测小物体还需要更精细一点的特征图(Fine-Grained Features)。**YOLOv2提出了一种passthrough层来利用更精细的特征图,具体地是利用最后一层池化前的输入特征图,该Fine-Grained Features大小为26 x 26 x 512,passthrough层抽取前面层的每个2 x 2的局部区域,然后将其转化为channel维度。具体做法如下图所示:
经过passthrough层,26 x 26 x 512的特征就变为13 x 13 x2048的特征,再与后面的13 x 13 x 1024拼接成13 x 13 x 3072的特征图,然后在此基础上做卷积预测。
另外,作者在后期的实现中借鉴了ResNet网络,不是直接对高分辨特征图处理,而是增加了一个中间卷积层,先采用64个1 x 1卷积核进行卷积,然后再进行passthrough处理,这样26 x 26 x 512的特征图得到13 x 13 x 256的特征图。这算是实现上的一个小细节。使用Fine-Grained Features之后YOLOv2的性能有1%的提升。
-
由于YOLOv2模型中只有卷积层和池化层,所以YOLOv2的输入可以不限于 416 x 416 大小的图片。为了增强模型的鲁棒性,YOLOv2采用了多尺度输入训练策略,具体来说就是在训练过程中每间隔一定的iterations之后改变模型的输入图片大小。由于YOLOv2的下采样总步长为32,输入图片大小选择一系列为32倍数的值:**{320, 352,…, 608} **,输入图片最小为320 x 320 ,此时对应的特征图大小为 10 x 10,而输入图片最大为 608 x 608 ,对应的特征图大小为 19 x 19 。在训练过程,每隔10个iterations随机选择一种输入图片大小,然后只需要修改对最后检测层的处理就可以重新训练。采用Multi-Scale Training策略,YOLOv2可以适应不同大小的图片,并且预测出很好的结果。
-
关于loss:
-
和YOLOv1一样,对于训练图片中的ground truth,若其中心点落在某个cell内,那么该cell内的5个先验框所对应的边界框负责预测它,具体是哪个边界框预测它,需要在训练中确定,即由那个与ground truth的IOU最大的边界框预测它,而剩余的4个边界框不与该ground truth匹配。YOLOv2同样需要假定每个cell至多含有一个grounth truth,而在实际上基本不会出现多于1个的情况。与ground truth匹配的先验框计算坐标误差、置信度误差(此时target为1)以及分类误差,而其它的边界框只计算置信度误差(此时target为0)。YOLOv2和YOLOv1的损失函数一样,为均方差函数。
-
我们来一点点解释,首先W, H分别指的是特征图(13 x 13)的宽与高,而 A 指的是先验框数目(这里是5),各个 值是各个loss部分的权重系数。
-
第一项loss是计算background的置信度误差,需要计算所有预测框,对每个预测框计算它和所有ground truth的IOU值,并且取最大的IOU值记为Max_IOU,如果该值小于一定的阈值(YOLOv2使用的是0.6),那么这个预测框就标记为background,需要计算noobj的置信度误差。
-
第二项是计算先验框与预测框的坐标误差,但是只在前12800个iterations间计算,这里是所有的预测框都要参与计算。
-
第三大项计算与某个ground truth匹配的预测框各部分loss值,包括坐标误差、置信度误差以及分类误差。先说一下匹配原则,对于某个ground truth,**首先要确定其中心点要落在哪个cell上,然后计算这个cell的5个先验框与ground truth的IOU值,IOU值最大的那个先验框与ground truth匹配,对应的预测框用来预测这个ground truth。**在计算obj置信度时,target=1,但与YOLOv1一样而增加了一个控制参数rescore,当其为1时,target取预测框与ground truth的真实IOU值(cfg文件中默认采用这种方式)。对于那些没有与ground truth匹配的先验框(与预测框对应),除去那些Max_IOU低于阈值的,其它的就全部忽略,不计算任何误差。
-
YOLO9000
在80类的COCO数据集中,物体的类别都是比较抽象的,例如类别‘dog’并没有精确到具体狗的品种(哈士奇或者柯基等)。而ImageNet中包含的类别则更具体,不仅包含‘dog’类,还包括‘poodle’和‘Corgi’类。我们将COCO数据集的狗的图片放到训练好的ImageNet模型中理论上是能判断出狗的品种的,同理我们将ImageNet中的狗的图片(不管是贵宾犬,还是柯基犬)放任在COCO训练好的检测模型中,理论上是能够检测出来的。但是生硬的使用两个模型是非常愚蠢且低效的。YOLO9000的提出便是巧妙地利用了COCO数据集提供的检测标签和ImageNet强大的分类标签,使得训练出来的模型具有强大的检测和分类的能力。
暂略
-
YOLOv3
YOLOv3没有太多的创新,主要是借鉴一些好的方案融合到YOLO里面。不过效果还是不错的,在保持速度优势的前提下,提升了预测精度,尤其是加强了对小物体的识别能力。
pipeline
图片输入网络,进行多尺度检测。
优点
- 调整了网络结构,引入了残差网络。
- 利用多尺度特征进行目标检测。
- 对象分类用Logistic取代了softmax。
缺点
- 要求精准的预测边框,采用COCO AP做评估标准的话,YOLO3在精确率上的表现较弱。
细节
-
YOLO2曾采用passthrough结构来检测细粒度特征,在YOLO3更进一步采用了3个不同尺度的特征图来进行对象检测。
结合上图看,卷积网络在79层后,经过下方几个黄色的卷积层得到一种尺度的检测结果。相比输入图像,这里用于检测的特征图有32倍的下采样。比如输入是416 x 416的话,这里的特征图就是13 x 13了。由于下采样倍数高,这里特征图的感受野比较大,因此适合检测图像中尺寸比较大的对象。
为了实现细粒度的检测,第79层的特征图又开始作上采样(从79层往右开始上采样卷积),然后与第61层特征图融合(Concatenation),这样得到第91层较细粒度的特征图,同样经过几个卷积层后得到相对输入图像16倍下采样的特征图。它具有中等尺度的感受野,适合检测中等尺度的对象。
最后,第91层特征图再次上采样,并与第36层特征图融合(Concatenation),最后得到相对输入图像8倍下采样的特征图。它的感受野最小,适合检测小尺寸的对象。
-
随着输出的特征图的数量和尺度的变化,先验框的尺寸也需要相应的调整。YOLO2已经开始采用K-means聚类得到先验框的尺寸,YOLO3延续了这种方法,为每种下采样尺度设定3种先验框,总共聚类出9种尺寸的先验框。在COCO数据集这9个先验框是:(10x13),(16x30),(33x23),(30x61),(62x45),(59x119),(116x90),(156x198),(373x326)。
分配上,在最小的13 x 13特征图上(有最大的感受野)应用较大的先验框(116x90),(156x198),(373x326),适合检测较大的对象。中等的26 x 26特征图上(中等感受野)应用中等的先验框(30x61),(62x45),(59x119),适合检测中等大小的对象。较大的52 x 52特征图上(较小的感受野)应用较小的先验框(10x13),(16x30),(33x23),适合检测较小的对象。
-
预测对象类别时不使用softmax,改成使用logistic的输出进行预测。这样能够支持多标签对象(比如一个人有Woman 和 Person两个标签)。
-
不考虑神经网络结构细节的话,总的来说,对于一个输入图像,YOLO3将其映射到3个尺度的输出张量,代表图像各个位置存在各种对象的概率。
我们看一下YOLO3共进行了多少个预测。对于一个416 x 416的输入图像,在每个尺度的特征图的每个网格设置3个先验框,总共有**13 x 13 x 3 + 26 x 26 x 3 + 52 x 52 x 3 = 10647 **个预测。每一个预测是一个(4 + 1 + 80) = 85维向量,这个85维向量包含边框坐标(4个数值),边框置信度(1个数值),对象类别的概率(对于COCO数据集,有80种对象)。
对比一下,YOLO2采用13 x 13 x 5 = 845个预测,YOLO3的尝试预测边框数量增加了10多倍,而且是在不同分辨率上进行,所以mAP以及对小物体的检测效果有一定的提升。
SSD
优点
- Multi-scale feature map:使用多尺度的feature map来进行检测。在base network之后加了几层卷积,这些卷积层会逐渐减小feature map的size,然后在不同size的feature map上进行检测,进而实现了一个多尺度的检测。因为不同size的feature map的感受野不同,因此可以检测不同大小的物体,比较大的特征图,感受野较小,适合检测相对较小的物体,而较小的特征图,感受野较大,适合检测相对较大的物体。
- Convolutional predictors:在YOLOv1中使用全连接层来进行分类和回归,但是在SSD中改为使用卷积层。
- Default boxes and aspect ratios:我们之前分析过YOLO的缺陷,首先YOLOv1中每个cell只预测两个bbox和一个类别,这就限制了能预测重叠或邻近物体的数量,同时YOLOv1直接预测bbox的位置,这样会增加训练难度。因此在SSD中就借鉴Faster R-CNN中的anchor机制,为feature map中的每个点设置几个不同尺寸和宽高比的default boxes(anchors),然后以这些anchors为基准去拟合ground truth box,这样就减小了训练的难度。同时,在SSD中通过计算anchor和ground truth box的IoU来确定哪个anchor负责哪个物体,而不是像YOLO一样通过物体的中心点来确定,这样就能更好的预测那些重叠或近邻的物体。
缺点
- 在小目标检测方面,其准确度仍然不敌Faster R-CNN。
细节
-
SSD使用VGG16来做为base network,然后在VGG16的基础上添加了新的卷积层以获得不同size的feature map,首先对基础网络VGG16进行了修改,其中Conv5_3之前的卷积层保持不变,而原来的FC6和FC7分别变成 3 x 1 和 1 x 1 的卷积层Conv6和Conv7,去掉了原来的dropout和FC8层。此外,还将池化层pool5由原来的stride = 2 的 2 x 2池化 变成 stride = 1的 3 x 3 池化,为了配合这种变化,Conv6的卷积采用的是 dilation = 6的空洞卷积。在基础网络之上SSD又添加了新的卷积层,如Conv8_2,Conv9_2,Conv10_2,Conv11_2。其中,Conv4_3,Conv7,Conv8_2,Conv9_2,Conv10_2和Conv11_2层输出的特征图用于检测。因为Conv4_3比较靠前,norm会比较大,因此会对Conv4_3输出的特征图先进行了一个L2 normalization,减少其和后边检测层的差异。最终一共有6个特征图,大小分别为(38,38),(19,19),(10,10),(5,5),(3,3),(1,1)。然后在不同size的特征图上设置不同大小和个数的default boxes(anchors),Conv4_3特征图上有4个anchor,Conv7有6个,Conv8_2有6个,Conv9_2有6个,Conv10_2有4个,Conv11_2有4个,所以最终anchor的数量为:38 x 38 x 4 + 19 x 19 x 6 + 10 x 10 x 6 + 5 x 5 x 6 + 3 x 3 x 4 + 1 x 1 x 4 = 8732。
-
为了预测每个anchor的类别和位置offset,SSD将这6个的特征图分别输入到两个3 x 3的卷积中进行结果预测。其中,**classifier的卷积输出维度为: anchor_num x 21, regressor的卷积输出维度为: anchor_num x 4 。**如对 5 x 5 的feature map上的每一点都设置6个anchor,然后用于定位的卷积使用 3 x 3 x (6 x 4) 的卷积核,输出5 x 5 x (6 x 4)的定位结果,用于定位的卷积使用 3 x 3 x (6 x 21) 的卷积核,输出 5 x 5 x (6 x 21) 的分类结果,21是类别数。(在SSD中,背景也算一类)。
-
在训练时,我们首先要确定哪个anchor对应哪个ground truth box。在SSD中主要采取了两种匹配策略;(1)对于每个ground truth box,首先将它匹配给和它有最大的IoU的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。实验证明,这样可以加快收敛速度,使得整个训练过程更稳定。
-
loss: ssd的损失函数如下:
N是匹配的box个数,如果N为0,则loss为0。
-
置信度误差
= {1, 0}是一个指示器,当第i个anchor和第j个ground truth匹配,且ground truth的类别为p,则 = 1,否则为0,代表第i个anchor是负样本。
-
定位误差
l代表预测的anchor, d代表默认的anchor(即人工设置的),g代表ground truth anchor。
(cx, cy)为d的中心点位置,(w, h)为d的宽高。
-
-
anchor设置: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按照下式进行计算:
其中m为我们想要用来预测的feature map的个数, 为0.2,为0.9,第k层的min_size为,max_size为。初始时,**每个点都设置两个正方形anchor,其中小正方形的边长为min_size,大正方形的边长为,**除这两个正方形外,还有多个长方形anchor,长方形anchor的数目每层也不同,由每层anchor的数目决定,长方形anchor的长宽由下式决定:
其中ratio为长宽比,值域为{1, 2, 3, }。
计算好anchor后,我们还需要判断anchor是否超出图片的边缘,对于超出图片边缘的anchor,我们需要进行clip。
-
测试流程:整个测试过程比较简单,就是将测试样本输入到SSD网络中,然后网络会为每个anchor输出类别和位置预测结果。之后,根据类别的预测值确定每个anchor的类别,并过滤掉那些属于背景的anchor,然后根据类别置信度阈值过滤掉置信度较低的anchor。对于留下来的anchor,再根据预测的位置offset进行位置变换,得到预测的box。得到预测的box之后,再根据box的类别置信度进行降序排列,然后保留前k个box。最后进行NMS,去掉重叠度高的box,NMS之后剩下的box就为最终的检测结果。