【深度学习】目标检测 R-CNN, SPP-NET, Fast R-CNN, Faster R-CNN, R-FCN ,YOLO, SSD

版权声明:转载请注明出处,谢谢。 https://blog.csdn.net/NNNNNNNNNNNNY/article/details/68483053

在计算机视觉领域,“目标检测”主要解决两个问题:图像上多个目标物在哪里(位置),是什么(类别)。 
围绕这个问题,人们一般把其发展历程分为3个阶段: 
1. 传统的目标检测方法 
2. 以R-CNN为代表的结合region proposal和CNN分类的目标检测框架(R-CNN, SPP-NET, Fast R-CNN, Faster R-CNN, R-FCN) 
3. 以YOLO为代表的将目标检测转换为回归问题的端到端(End-to-End)的目标检测框架(YOLO, SSD)

下面结合参考资料分别对其做一下总结和自己的理解。

传统的目标检测方法

这里写图片描述 
传统目标检测的方法一般分为三个阶段:首先在给定的图像上选择一些候选的区域,然后对这些区域提取特征,最后使用训练的分类器进行分类。分别如下: 
a)区域选择:利用不同尺寸的滑动窗口框住图中的某一部分作为候选区域。 
b)特征提取:提取候选区域相关的视觉特征。比如人脸检测常用的Harr特征;行人检测和普通目标检测常用的HOG特征等。由于目标的形态多样性,光照变化多样性,背景多样性等因素使得设计一个鲁棒的特征并不是那么容易,然而提取特征的好坏直接影响到分类的准确性。 
c)分类器:利用分类器进行识别,比如常用的SVM模型。

传统的目标检测中,多尺度形变部件模型DPM(Deformable Part Model)表现比较优秀,连续获得VOC(Visual Object Class)2007到2009的检测冠军,。DPM把物体看成了多个组成的部件(比如人脸的鼻子、嘴巴等),用部件间的关系来描述物体,这个特性非常符合自然界很多物体的非刚体特征。DPM可以看做是HOG+SVM的扩展,很好的继承了两者的优点,在人脸检测、行人检测等任务上取得了不错的效果,但是DPM相对复杂,检测速度也较慢,从而也出现了很多改进的方法。

总结:传统目标检测存在的两个主要问题:一个是基于滑动窗口的区域选择策略没有针对性,时间复杂度高,窗口冗余;二是手工设计的特征对于多样性的变化并没有很好的鲁棒性。

基于Region Proposal的深度学习目标检测算法

对于滑动窗口存在的问题,region proposal(候选区域)提供了很好的解决方案。region proposal利用了图像中的纹理、边缘、颜色等信息预先找出图中目标可能出现的位置,可以保证在选取较少窗口(几千个甚至几百个)的情况下保持较高的召回率。这大大降低了后续操作的时间复杂度,并且获取的候选窗口要比滑动窗口的质量更高。这里贴两张介绍region proposal的PPT: 
这里写图片描述

2014年,RBG(Ross B. Girshick)大神使用region proposal+CNN代替传统目标检测使用的滑动窗口+手工设计特征,设计了R-CNN框架,使得目标检测取得巨大突破,并开启了基于深度学习目标检测的热潮。

R-CNN

这里写图片描述 
R-CNN的目标检测流程: 
a) 输入图像,用selective search算法在图像中提取2000个左右的region proposal(侯选框),并把所有region proposal warp(缩放)成固定大小(原文采用227×227) 
b) 将归一化后的region proposal输入CNN网络,提取特征 
c) 对于每个region proposal提取到的CNN特征,再用SVM分类来做识别,用线性回归来微调边框位置与大小,其中每个类别单独训练一个边框回归(bounding-box regression)器。

总结:R-CNN框架仍存在如下问题: 
a) 重复计算:我们通过region proposal提取2000个左右的候选框,这些候选框都需要进行CNN操作,计算量依然很大,其中有不少其实是重复计算 
b) multi-stage pipeline,训练分为多个阶段,步骤繁琐:region proposal、CNN特征提取、SVM分类、边框回归, 
c) 训练耗时,占用磁盘空间大:卷积出来的特征数据还需要单独保存

SPP-net

这里写图片描述 
SPP-net的主要思想是去掉了原始图像上的crop/warp等操作,换成了在卷积特征上的空间金字塔池化层(Spatial Pyramid Pooling,SPP)。 
为何要引入SPP层 ?一部分原因是fast R-CNN里对图像进行不同程度的crop/warp会导致一些问题,比如上图中的crop会导致物体不全,warp导致物体被拉伸后形变严重。但更更更重要的原因是:fast R-CNN里我们对每一个region proposal都要进行一次CNN提取特征操作,这样带来了很多重复计算。试想假如我们只对整幅图像做一次CNN特征提取,那么原图一个region proposal可以对应到feature map(特征图)一个window区域,只需要将这些不同大小window的特征映射到同样的维度,将其作为全连接的输入,就能保证只对图像提取一次卷积层特征。 
这里写图片描述 
SPP就是为了解决这种问题的。SPP使用空间金字塔采样(spatial pyramid pooling)将每个window划分为4*4, 2*2, 1*1的块,然后每个块使用max-pooling下采样,这样对于每个window经过SPP层之后都得到了一个长度为(4*4+2*2+1)*256维度的特征向量,将这个作为全连接层的输入进行后续操作。

总结:使用SPP-NET大大加快了目标检测的速度,但是依然存在着很多问题: 
a) 训练分为多个阶段,依然步骤繁琐 
b) SPP-NET在微调网络时固定了卷积层,只对全连接层进行微调,而对于一个新的任务,有必要对卷积层也进行微调。(分类的模型提取的特征更注重高层语义,而目标检测任务除了语义信息还需要目标的位置信息)(这一点其实不是很懂啊)

Fast R-CNN

这里写图片描述
Fast R-CNN在R-CNN的基础上又做了一些改进: 
a) 与SPP类似,它只对整幅图像做一次CNN特征提取,在后面加了一个类似于SPP的ROI pooling layer,其实就是下采样。不过因为不是固定尺寸输入,因此每次的pooling网格大小需要动态调整。比如某个ROI区域坐标为 (x1,y1,x2,y2)(x1,y1,x2,y2),即输入size为 (y2−y1)∗(x2−x1)(y2−y1)∗(x2−x1)(y2−y1)∗(x2−x1)(y2−y1)∗(x2−x1) ,如果要求pooling的输出size统一为pooledheight∗pooledwidthpooledheight∗pooledwidth ,那么每个网格的size为 y2−y1pooledheight∗x2−x1pooledwidthy2−y1pooledheight∗x2−x1pooledwidth。 
b) 整个的训练过程是端到端的(除去region proposal提取阶段),梯度能够通过RoI Pooling层直接传播,直接使用softmax替代SVM分类,同时利用Multi-task Loss(多任务损失函数)将边框回归和分类一起进行。这里着重说一下Multi-task Loss函数: 

L(p,u,tu,v)=Lcls(p,u)+λ[u⩾1]Lloc(tu,v)Lcls(p,u)=−logpuLloc(tu,v)=∑i⊆x,y,w,hsmoothL1(tui−vi))smoothL1(x)={0.5x2|x|−0.5if|x|<1othersiseL(p,u,tu,v)=Lcls(p,u)+λ[u⩾1]Lloc(tu,v)Lcls(p,u)=−log⁡puLloc(tu,v)=∑i⊆x,y,w,hsmoothL1(tiu−vi))smoothL1(x)={0.5x2if|x|<1|x|−0.5othersise


简单解释一下,p=(p0,p1,⋯,pk)p=(p0,p1,⋯,pk),是针对每个ROI区域的分类概率预测; tk=(tkx,tky,tkw,tkh)tk=(txk,tyk,twk,thk),是针对每个ROI区域坐标的偏移(具体偏移怎么算看下位RPN处);uu为真实类别,vv为groundtruth坐标。 
这里写图片描述 
这里再说一下Fast R-CNN的主要步骤: 
a) 特征提取:以整张图片为输入利用CNN得到图片的特征层; 
b) region proposal:通过Selective Search等方法从原始图片提取区域候选框,并把这些候选框一一投影到最后的特征层; 
c) 区域归一化:针对特征层上的每个区域候选框进行RoI Pooling操作,得到固定大小的特征表示; 
d) 分类与回归:然后再通过两个全连接层,分别用softmax做多目标分类,用回归模型进行边框位置与大小微调。 
总结:Fast R-CNN确实做得很棒,其缺点在于:region proposal的提取使用selective search,目标检测时间大多消耗在这上面(提region proposal 2~3s,而提特征分类只需0.32s),无法满足实时应用。

Faster R-CNN

这里写图片描述 
Faster R-CNN最大的贡献就是RPN(Region Proposal Networks)网络。RPN的核心思想是使用卷积神经网络直接产生region proposal,使用的方法本质上是滑动窗口。假设我们得到的conv feature map维度是13∗13∗25613∗13∗256,sliding window的大小是3∗33∗3,即我们需要用一个3∗3∗256∗2563∗3∗256∗256的卷积核从而对每个位置得到一个256-d的向量;然后就是k=9,对每一个anchor box输出是物体和是背景的概率,所以cls layer就是18个输出节点了,那么在256-d和cls layer之间使用一个1∗1∗256∗181∗1∗256∗18的卷积核,就可以得到cls layer;同理,reg layer的输出是36个,所以对应的卷积核是1∗1∗256∗361∗1∗256∗36,这样就可以得到reg layer。 
这里有一点我刚开始没想通:怎么体现论文中所说的3种尺度(128,256,512),3种长宽比(1:1,1:2,2:1)这个先验知识?其实这个通过loss founction可以看出来。说白了,我们相当于是以anchor box为锚点来对其附近的ground-truth box做一个bounding-box回归,好饶,,, 
RPN的loss founcton: 
这里写图片描述 
这里写图片描述 
这里x,xa和x∗x,xa和x∗分别代表于此窗口、anchor box窗口和ground-truth窗口的值。 
在训练过程中,我们给每一个anchor对应的区域标注label。正标签:那些和任意一个ground truth box的重叠区域IOU最大的,对于那些和指定的ground truth的IOU超过0.7的。负标签:与所有的ground truth的IOU都小于0.3的。剩下的既不是正样本也不是负样本,不用于最终训练。 
这里写图片描述 
Faster R-CNN的主要步骤如下: 
a) 特征提取:同Fast R-CNN; 
b) region proposal:在最终的卷积特征层上利用k个不同的矩形框(Anchor Box)进行region proposal;即对每个Anchor Box对应的区域进行object/non-object二分类,并用k个回归模型(各自对应不同的Anchor Box)微调候选框位置与大小 
c) 区域归一化:同fast R-CNN; 
d) 分类与回归:进行目标分类,并做边框回归(感觉这一块再做一次边框回归是不是有点重复)。 
Faster R-CNN的训练:为了让RPN的网络和Fast R-CNN网络实现卷积层的权值共享,其训练方法比较复杂,简而言之就是迭代的Alternating training。具体可参考下面给出的链接。 
这篇论文非常优秀,其中介绍到的一些解决multiple scale或带有权值共享的联合训练的方式都很值得学习借鉴。

R-FCN

这一块没了解清楚,只知道一个概念:位置敏感得分地图。 
RCNN学习笔记(11):R-FCN: Object Detection via Region-based Fully Convolutional Networks 
深度学习论文笔记:R-FCN 
论文笔记 | R-FCN: Object Detection via Region-based Fully Convolutional Networks

基于回归方法的端到端(End-to-End)的深度学习目标检测算法

本小节介绍的为彻底端到端(End-to-End)的目标检测方法,这些方法无需region proposal。

YOLO

这里写图片描述 
从网路结构可以看出整个过程非常简单,不需要中间的region proposal在找目标,直接回归便完成了位置和类别的判定。 
那么如何才能做到直接在不同位置的网格上回归出目标的位置和类别信息呢?上面是YOLO的网络结构图,主要是最后两层的结构,卷积层之后接了一个4096维的全连接层,然后后边又全连接到一个7*7*30维的张量上。实际上这7*7就是划分的网格数,现在要在每个网格上预测目标两个可能的位置以及这个位置的目标置信度和类别,也就是每个网格预测两个目标,每个目标的信息有4维坐标信息(中心点坐标+长宽),1个是目标的置信度,还有类别数20(VOC上20个类别),总共就是(4+1)*2+20 = 30维的向量。这样可以利用前边4096维的全图特征直接在每个网格上回归出目标检测需要的信息(边框+类别信息)。 
这里写图片描述 
下面说一下loss函数: 
YOLO使用均方误差(mean squared error,均方误差是各数据偏离真实值的距离平方和的平均数)作为loss函数来优化模型参数,即网络输出的S∗S∗(B∗5+C)S∗S∗(B∗5+C)维向量与真实图像的对应S∗S∗(B∗5+C)S∗S∗(B∗5+C)维向量的均方误差。 
如下式所示。其中,coordError、iouError和classError分别代表预测数据与标定数据之间的坐标误差、IOU误差和分类误差。 
这里写图片描述 
YOLO对上式loss的计算进行了如下修正。 
a) 位置相关误差(坐标、IOU)与分类误差对网络loss的贡献值是不同的,因此YOLO在计算loss时,使用λcoord=5λcoord=5修正coordErrorcoordError。 
b) 在计算IOU误差时,包含物体的格子与不包含物体的格子,二者的IOU误差对网络loss的贡献值是不同的。若采用相同的权值,由于一幅图片中不包含物体的格子更多,自然他们对loss函数在计算网络参数梯度时的影响更大。为解决这个问题,YOLO 使用λnoobj=0.5λnoobj=0.5修正iouError。(注此处的‘包含’是指存在一个物体,它的中心坐标落入到格子内)。 
c) 对于相等的误差值,大物体误差对检测的影响应小于小物体误差对检测的影响。这是因为,相同的位置偏差占大物体的比例远小于同等偏差占小物体的比例。YOLO将物体大小的信息项(w和h)进行求平方根来改进这个问题。(注:这个方法并不能完全解决这个问题)。 
综上,YOLO在训练过程中Loss计算如下式所示: 
这里写图片描述 
其中,x,y,w,C,px,y,w,C,p为网络预测值,x,y,w,C,px,y,w,C,p帽 为标注值。ΠobjiΠiobj 表示物体落入格子i中,ΠobjijΠijobj 和ΠnoobjijΠijnoobj 分别表示物体落入与未落入格子i的第j个bounding box内。

总结:YOLO简化了整个目标检测流程,速度的提升也很大,但是YOLO还是有不少可以改进的地方,比如S×S的网格就是一个比较启发式的策略,如果两个小目标同时落入一个格子中,模型也只能预测一个。另一个问题是YOLO loss函数中,大物体IOU误差和小物体IOU误差对网络训练中loss贡献值接近(虽然采用求平方根方式,但没有根本解决问题);因此,对于小物体,小的IOU误差也会对网络优化过程造成很大的影响,从而降低了物体检测的定位准确性。并且,YOLO采用了多个下采样层,网络学到的物体特征并不精细,因此也会影响检测效果。 
与faster rcnn相比,YOLO有更加明显的优势,首先faster rcnn需要一个rpn网络代替selective search来找出候选区域,而yolo则直接将7x7这49个区域作为候选区域。

SSD

这里写图片描述 
SSD和YOLO的网络结构对比

对于SSD说两点: 
a) 上面分析了YOLO存在的问题,使用整图特征在7*7的粗糙网格内回归对目标的定位并不是很精准。那是不是可以结合region proposal的思想实现精准一些的定位?YOLO预测某个位置使用的是全图的特征,SSD预测某个位置使用的是这个位置周围的特征(感觉更合理一些)。那么如何建立某个位置和其特征的对应关系呢?可能你已经想到了,使用Faster R-CNN的anchor机制。如SSD的框架图所示,假如某一层特征图(图b)大小是8*8,那么就使用3*3的滑窗提取每个位置的特征,然后这个特征回归得到目标的坐标信息和类别信息(图c)。 
这里写图片描述 
b) 不同于Faster R-CNN,这个anchor是在多个feature map上,这样可以利用多层的特征并且自然的达到多尺度(不同层的feature map 3*3滑窗感受野不同)。

具体还没有搞清楚,参考: 
论文阅读:SSD: Single Shot MultiBox Detector 
目标检测方法简介:RPN(Region Proposal Network) and SSD(Single Shot MultiBox Detector)

YOLO v2

精度的改进(Better)

a) Batch Normalization(批规范化) 
使用Batch Normalization对网络进行优化,让网络提高了收敛性,同时还消除了对其他形式的正则化(regularization)的依赖。 
b) High Resolution Classifier 
在YOLOv2中,作者首先采用448×448分辨率的ImageNet数据finetune使网络适应高分辨率输入;然后将该网络用于目标检测任务finetune。 
c) Convolutional With Anchor Boxes 
之前的YOLO利用全连接层的数据完成边框的预测,导致丢失较多的空间信息,定位不准。作者在这一版本中借鉴了Faster R-CNN中的Anchor思想,回顾一下,anchor是RNP网络中的一个关键步骤。 
d) Dimension Clusters(维度聚类) 
之前Anchor Box的尺寸是手动选择的,所以尺寸还有优化的余地。 为了优化,在训练集(training set)Bounding Boxes上跑了一下k-means聚类,来找到一个比较好的值。 
如果我们用标准的欧式距离的k-means,尺寸大的框比小框产生更多的错误。因为我们的目的是提高IOU分数,这依赖于Box的大小,所以距离度量的使用: 
这里写图片描述 
e) Direct location prediction 
在YOLO模型上采用anchor boxes的第二个关键是模型不稳定性,特别是在前面几轮训练。大部分不稳定因素来源于预测boxes位置(x,y)。作者就没有采用预测直接的offset的方法,而使用了预测相对于grid cell的坐标位置的办法。 
f) Fine-Grained Features(细粒度特征) 
有别于faster rcnn和SSD采用多尺度的特征图进行预测,yolov2提出了一个全新的思路,作者引入了passthrough layer,这个层的作用就是将上一层特征图的相邻像素都切除一部分组成了另外一个通道。例如,将26*26*512的特征图变为13*13*2048的特征图(这里具体的实现过程需要看作者的源码,但是,为了解释这个变化过程,可以做这样的解释,就是将一个26*26的图的像素放到4个13*13的图中,水平每2个像素取1个,垂直也是每2个像素取一个,一共就可以得到2*2=4个,512*4=2048),使得特征图的数目提高了4倍,同时,相比于26*26的特征图,13*13的特征图更有利用小目标物的检测。 
g) Multi-Scale Training 
最初的YOLO输入尺寸为448×448,加入anchor boxes后,输入尺寸为416×416。模型只包含卷积层和pooling 层,因此可以随时改变输入尺寸。作者在训练时,每隔几轮便改变模型输入尺寸,以使模型对不同尺寸图像具有鲁棒性。

更加快速(faster)

a) Darknet-19 
b) Training for classification 
网络训练在 ImageNet 1000类分类数据集,训练了160epochs。 
c) Training for detection 
网络去掉了最后一个卷积层,而加上了三个3*3卷积层,每个卷积层有1024个Filters,每个卷积层紧接着一个1*1卷积层, with the number of outputs we need for detection。

多分类的改进(Stronger)

使用联合训练方法时,中间会出现一些问题:但是检测数据集只有粗粒度的标记信息,像“猫“、“ 狗”之类,而分类数据集的标签信息则更细粒度,更丰富。比如狗这一类就包括”哈士奇“”牛头梗“”金毛狗“等等。所以如果想同时在监测数据集与分类数据集上进行训练,那么就要用一种一致性的方法融合这些标签信息。 
作者结合词向量树(wordtree)等方法,使YOLOv2的检测种类扩充到了上千种。

作者大概说的是,之前的技术改进对检测任务很有帮助,在未来的工作中,可能会涉足弱监督方法用于图像分割。监督学习对于标记数据的要求很高,未来要考虑弱标记的技术,这将会极大扩充数据集,提升训练量。

后一半写的凌乱了,有时间再整理一下。

参考资料: 
每个方法的论文。 
基于深度学习的目标检测研究进展 
YOLO详解 
R-CNN,SPP-NET, Fast-R-CNN,Faster-R-CNN, YOLO, SSD系列深度学习检测方法梳理 
【Deep Learning回顾】之基于深度学习的目标检测 
原始图片中的ROI如何映射到到feature map? 
RCNN, Fast-RCNN, Faster-RCNN的一些事 
目标检测——从RCNN到Faster RCNN 串烧 
Object Detection

猜你喜欢

转载自blog.csdn.net/qq_34106574/article/details/82455537