本文的截图和内容摘要参考了CS231n和某位大佬的优秀博客,主要结合了其它资料和自己的理解,进行了修改和补充,内容更详细易懂,在此特别感谢。
首先来一张截止到前一段时间为止,在目标检测和图像分割领域,各大期刊会议上所提出来的一些表现和应用价值比较好的算法,如下:
本文主要分享一下R-CNN系列(包括R-CNN、Fast R-CNN、Faster R-CNN)的目标检测技术,本文主要是从宏观角度介绍R-CNN系列的目标检测算法的技术演进过程,对于每一种单独的算法不会去过于详细的介绍,如果想要了解算法的详细过程,欢迎阅读我的其他博客。
在2012年ImageNet的比赛中,深度学习首次应用到了图像分类领域,并于当年一举以巨大优势碾压传统方法获得2012年的ImageNet的冠军,在此之后,利用深度学习来解决关于图像分类/识别/检测/分割的任务已经成为人们的默认方式。本文将主要介绍“基于深度学习的目标检测技术的演进过程”,在此过程中,同时也会对一些其它相关的技术进行介绍。
首先,目标检测(object detection)所要解决的任务是:给定一整张图片,在图片中精确找到物体所在位置,并标注出物体的类别。object detection要解决的问题就是物体在哪里,是什么这整个流程的问题。然而,这个问题可不是那么容易解决的,物体的尺寸变化范围很大,摆放物体的角度,姿态不定,而且可以出现在图片的任何地方,更何况物体还可以是多个类别。
本文所讲的object detection技术的演进过程为:
首先,我们从图像识别的任务说起,顾名思义,图像识别(分类)就是给定一张图片,需要把图中的物体是什么给识别出来,见下图:
上图的最左侧即为图像识别的任务。上面的第二幅图像为“识别+定位”任务,即不仅要把图中的物体是什么给识别出来,又要用方框框出它的位置。这里要注意一点,“图像识别”和“图像识别+定位”任务通常都是针对单物体来说的,也就是所给的图片中仅有一个物体/目标。而物体/目标检测通常指的是多物体的“图像识别+定位”任务,即如上面的第三张图所示。上图第四张图所示为“图像分割”,即不仅仅满足于用矩形框把物体定位出来,图像分割要求把不同物体的轮廓给识别出来。
“图像识别+定位”的流程大致如下:
图像识别(classification):
输入:图片
输出:物体的类别(猫/狗/……)
评估方法:准确率
定位(localization):
输入:图片
输出:方框在图片中的位置(x,y,w,h)
评估方法:检测评价函数 intersection-over-union ( IOU ) ,即交并准则。
即我们需要做的是“识别主体+定位”的任务。卷积神经网络CNN已经帮我们完成了图像识别(判定是猫还是狗)的任务了,我们只需要添加一些额外的功能来完成定位任务即可。
那么,定位任务的主要思路有哪些呢?
看做回归问题,我们需要预测出(x,y,w,h)四个参数的值,从而得出方框的位置。(四个数字,用L2 loss,欧氏距离损失)
按照此思路,完成“图像识别+定位”的步骤如下:
步骤1:
• 先解决简单问题, 搭一个识别图像的神经网络(即先做识别/分类部分)
• 在AlexNet/VGG/GoogLeNet上fine-tuning一下(得到针对自己场景的图像分类器)
步骤2:
• 在上述神经网络的尾部展开(也就说CNN前面保持不变,我们对CNN的结尾处作出改进:加了两个头:“分类头”和“回归头”)
• 成为classification + regression模式
步骤3:
• Regression(回归)那个部分用欧氏距离损失
• 使用SGD训练
步骤4:
• 预测阶段把2个头部拼上
• 完成不同的功能
这里需要进行两次fine-tuning
第一次在ALexNet上做,第二次将头部改成regression head,前面不变,做一次fine-tuning
Regression的部分加在哪?
有两种处理方法:(无绝对好坏)
• 加在最后一个卷积层后面(如VGG)
• 加在最后一个全连接层后面(如R-CNN)
regression太难做了,应想方设法转换为classification问题。
regression的训练参数收敛的时间要长得多,所以上面的网络采取了用classification的网络来计算出网络共同部分的连接权值。
CV领域不同任务之间一般都有一定的重合度,比如上述目标检测的任务中用到的技术就可以扩展到人体姿态识别中来。在传统的物体检测任务中,我们只需要检测和定位一整个物体,那么我们能否对主体有更加细致的识别呢?
即可以选定人的n个关节,对每个关节点做回归预测,然后将不同的关节点连接起来(连成线段),完成姿态识别。
• 还是刚才的classification + regression思路
• 咱们取不同的大小的“框”(候选框 => 滑动)
• 让框出现在不同的位置(滑动),得出这个框的判定得分
• 取得分最高的那个框
举例如下:
在上面的图中,假设最左边的黑框是我们的候选框的大小( 3 ∗ 221 ∗ 221 3*221*221 3∗221∗221),这个候选框在图像上滑动,假设共有四个位置(左上、右上、左下、右下),这四个位置的得分分别为:0.5、0.75、0.6、0.8。根据得分的高低,我们选择了右下角的黑框作为目标位置的预测(注:有的时候也会选择得分最高的两个框,然后取两框的交集作为最终的位置预测)。
疑惑:框要取多大?
取不同的框,依次从左上角扫到右下角。非常粗暴啊。
总结一下思路:
对一张图片,用各种大小的框(遍历整张图片)将图片截取出来(可能有几千张子图),输入到CNN,然后CNN会输出这个框的得分(classification)以及这个框图片对应的x,y,h,w(regression)——运行算量巨大。
注:这里要强调一点,这里用到了候选框在原图上滑动截取子图的办法来定位目标,但这样很可能会导致候选框的大小和真实目标的大小无法完美匹配的问题,为解决这个问题,还要对每一个截取出来的子图进行一个回归预测(x,y,h,w),这四个值即代表预测的box如何才能变为ground true。(在大小和尺度上要做何种变化)
即:
这方法实在太耗时间了,且原来的网络中有全连接层,参数量很大,这里做个优化。
原来网络是这样的:
想办法克服一下过程中的“参数多”与“计算慢”的问题
全卷积网络的好处:
物体检测通常指的是多物体的“识别+定位”,那么我们首先试着把这个问题看做一个回归问题。
如上图,若看做回归问题,则上面的图片最少就要回归 K ∗ 4 = 4 ∗ 4 = 16 K*4=4*4=16 K∗4=4∗4=16个数(这里假定图片中有四个物体,即K=4),但现在有一个问题,因为我们对一张新的图片,我们并不确定图片上有几个物体的位置需要我们回归,而神经网络的结构是固定的,所以无法把物体检测问题看作是一个单纯的回归问题。
那么当图像有很多物体怎么办的?难度可是一下暴增啊,首先明确我们的任务是:多物体识别+定位多个物体。现在我们试着将其看做分类问题。
看做分类问题,难点是?
那么,看做分类问题,有没有办法优化下? 我可不想试那么多框那么多位置啊!
有人想到一个好方法:
找出可能含有物体的框(也就是候选框,比如选1000个候选框),这些框之间是可以互相重叠互相包含的,这样我们就可以避免暴力枚举的所有框了。
大牛们发明好多选定候选框的方法,比如EdgeBoxes和Selective Search。
以下是各种选定候选框的方法的性能对比。
有一个很大的疑惑,提取候选框用到的算法“选择性搜索”到底怎么选出这些候选框的呢?这里仅简单介绍一下。
Selective Search主要有以下两步:
基于以上的思路,RCNN的出现了。(终于。。。。。写到泪奔)
步骤一:训练(或者下载)一个分类模型(比如AlexNet,VGG),针对自己的场景做fine-tune
步骤二:对该模型做fine-tuning
• 去掉最后一个全连接层
• 将分类数从1000改为21(假设有20个物体类别+1个背景)
步骤三:特征提取
• 提取图像的所有候选框(选择性搜索)
• 对于每一个区域:修正区域大小以适合CNN的输入,做一次前向运算,将第五个池化层的输出(就是对候选框提取到的特征)存到硬盘
步骤四:训练一个SVM分类器来判断这个候选框里物体是或者不是某个类别(二分类)
每个类别对应一个SVM,判断是不是属于这个类别,是就是positive,反之nagative,如下:
猫的SVM分类器:
狗的SVM分类器:
步骤五:使用回归器精细修正候选框位置:对于每一个类,训练一个线性回归模型去判定这个框是否框得完美。(bbox regression:微调图窗区域)
注:bbox regression即为 bounding box regression,即对得到的候选框进行微调。
RCNN的进化中SPP Net的思想对其贡献很大,这里也简单介绍一下SPP Net。
SPP:Spatial Pyramid Pooling(空间金字塔池化)
它的特点有两个:
1.结合空间金字塔方法实现CNNs的对尺度输入。
一般CNN后接全连接层或者分类器,他们都需要固定的输入尺寸,因此不得不对输入数据进行crop或者warp,这些预处理会造成数据的丢失或几何的失真。SPP Net的第一个贡献就是将金字塔思想加入到CNN,实现了数据的多尺度输入。
如下图所示,在卷积层和全连接层之间加入了SPP layer。此时网络的输入可以是任意尺度的,在SPP layer中每一个pooling的filter会根据输入调整大小,而SPP的输出尺度始终是固定的。
2.只对原图提取一次卷积特征
在R-CNN中,每个候选框先resize到统一大小,然后分别作为CNN的输入,这样是很低效的。
所以SPP Net根据这个缺点做了优化:只对原图进行一次卷积得到整张图的feature map,然后找到每个候选框(选择性搜索得到的)在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到SPP layer和之后的层。节省了大量的计算时间,比R-CNN有一百倍左右的提速。
SPP Net真是个好方法,R-CNN的进阶版Fast R-CNN就是在RCNN的基础上采纳了SPP Net方法(在Fast R-CNN中叫ROI Pooling),对RCNN作了改进,使得性能进一步提高。
R-CNN与Fast RCNN的区别有哪些呢?
先说RCNN的缺点:即使使用了selective search等预处理步骤来提取潜在的bounding box作为输入,但是RCNN仍会有严重的速度瓶颈,原因也很明显,就是计算机对所有region进行特征提取时会有重复计算(全部候选图都过一遍CNN),Fast-RCNN正是为了解决这个问题诞生的
即在这里我们不在需要把Selective Search得到的近千个候选框分别进行resize,然后送到CNN中提取特征。在Fast-RCNN中,我们只需要对原图进行一次卷积得到整张图的feature map,然后找到每个候选框在feature map上的映射patch(卷积网络不同层之间的像素有映射关系),将此patch作为每个候选框的卷积特征输入到ROI Pooling(因为后面有全连接层,要求尺寸固定,所以需要ROI Pooling)和之后的层。节省了大量的计算时间,比R-CNN有一百倍左右的提速。
所以在这里,从R-CNN => Fast-RCNN还有一个关键的技术,即ROI Pooling。首先介绍几个名词:
关于RIP:Region of Interest Pooling
维度不匹配怎么办:划分格子grid => 下采样
RIP的映射关系显然是可以还原回去的
总结一下:大牛提出了一个可以看做单层SPP Net的网络层,叫做ROI Pooling,这个网络层可以把不同大小的输入映射到一个固定尺度的特征向量,而我们知道,conv、pooling、relu等操作都不需要固定size的输入,因此,在原始图片上执行这些操作后,虽然输入图片size不同导致得到的feature map尺寸也不同,不能直接接到一个全连接层进行分类,但是可以加入这个神奇的ROI Pooling层,对每个region都提取一个固定维度的特征表示,再通过正常的softmax进行类型识别。另外,之前RCNN的处理流程是先提proposal,然后CNN提取特征,之后用SVM分类器,最后再做bbox regression,而在Fast-RCNN中,作者巧妙的把bbox regression放进了神经网络内部,与region分类和并成为了一个multi-task模型,实际实验也证明,这两个任务能够共享卷积特征,并相互促进。Fast-RCNN很重要的一个贡献是成功的让人们看到了Region Proposal+CNN这一框架实时检测的希望,原来多类检测真的可以在保证准确率的同时提升处理速度,也为后来的Faster-RCNN做下了铺垫。
画一画重点:
R-CNN有一些相当大的缺点(把这些缺点都改掉了,就成了Fast R-CNN)。
大缺点:由于每一个候选框都要独自经过CNN,这使得花费的时间非常多。
解决:共享卷积层,现在不是每一个候选框都当做输入进入CNN了,而是输入一张完整的图片,在第五个卷积层再得到每个候选框的特征
原来的方法:许多候选框(比如两千个)–>CNN–>得到每个候选框的特征–>分类+回归
现在的方法:一张完整图片–>CNN–>得到每张候选框的特征–>分类+回归
所以容易看见,Fast RCNN相对于RCNN的提速原因就在于:不过不像RCNN把每个候选区域给深度网络提特征,而是整张图提一次特征,再把候选框映射到conv5上,而SPP只需要计算一次特征,剩下的只需要在conv5层上操作就可以了。
在性能上提升也是相当明显的:
Fast R-CNN存在的问题:存在瓶颈:选择性搜索,找出所有的候选框,这个也非常耗时。那我们能不能找出一个更加高效的方法来求出这些候选框呢?
解决:加入一个提取Proposal的神经网络,也就说提取候选框的工作也交给神经网络来做了。
做这样的任务的神经网络叫做Region Proposal Network(RPN网络)。
具体做法:
• 将RPN放在最后一个卷积层的后面
• RPN直接训练得到候选区域(不再需要“选择性搜索”得到候选框了)
RPN简介:
• 在feature map上滑动窗口(取不同的anchor)
• 建一个神经网络用于物体分类+框位置的回归
• 滑动窗口的位置提供了物体的大体位置信息
• 框的回归提供了框更精确的位置
一种网络,四个损失函数;
• RPN calssification(anchor good.bad)
• RPN regression(anchor->propoasal)
• Fast R-CNN classification(over classes)
• Fast R-CNN regression(proposal ->box)
速度对比
Faster R-CNN的主要贡献是设计了提取候选区域的网络RPN,代替了费时的选择性搜索,使得检测速度大幅提高。
最后总结一下各大算法的步骤:
RCNN
1. 在图像中确定约1000-2000个候选框 (使用选择性搜索)
2. 每个候选框内图像块缩放至相同大小,并输入到CNN内进行特征提取
3. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类
4. 对于属于某一特征的候选框,用回归器进一步调整其位置
Fast RCNN
1. 在图像中确定约1000-2000个候选框 (使用选择性搜索)
2. 对整张图片输进CNN,得到feature map
3. 找到每个候选框在feature map上的映射patch,将此patch作为每个候选框的卷积特征输入到SPP layer(ROI Pooling)和之后的层
4. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类
5. 对于属于某一特征的候选框,用回归器进一步调整其位置
Faster RCNN
1. 对整张图片输进CNN,得到feature map
2. 卷积特征输入到RPN,得到候选框的特征信息
3. 对候选框中提取出的特征,使用分类器判别是否属于一个特定类
4. 对于属于某一特征的候选框,用回归器进一步调整其位置
总的来说,从R-CNN, SPP-NET, Fast R-CNN, Faster R-CNN一路走来,基于深度学习目标检测的流程变得越来越精简,精度越来越高,速度也越来越快。可以说基于region proposal的R-CNN系列目标检测方法是当前目标检测技术领域最主要的一个分支。