两个步骤:1)提取物体区域;2)对区域进行分类识别;
本章所有模型都基于这个思想。但是YOLO不是。
找到2000个可能出现物体的区域,然后对所有区域进行warped region标准化,变成正方形。第3步就是CNN卷积神经网络,提取特征。第4步是放入SVM进行分类+回归Bounding box regression。
如黄色小猫咪,通过无数个红色小方框,不断地将相似度高的框进行合并,最终形成的绿色框,就是需要进行识别的区域。
selective search只是将有物体的区域找出来,没有任何语义信息。
ground-truth 真实的,专家标注的。负样本就是没有被框住的。
数据量少时,只训练绿色层就可以了,数据量大,绿色层和上面的3层橘色的一起训练。
每一个类别,有一个自己的SVM。
P的IoU>0.6的意思是:只有P和G差不多,才做校正。差很多的都不考虑了。
PR曲线随着阈值的改变,曲线也会改变。因为它是Precision和Recall组成的。mAP是因为我们有20个类别,我们要把这20个AP加起来再取平均值,才是mAP。
R-CNN
R-CNN是首个将 CNN 引入目标检测领域的算法模型,但也因为是第一个吃螃蟹的,所以步子不能迈得太大,R-CNN 主要是在特征提取阶段使用CNN(AlexNet),其它阶段使用的还是传统目标检测的方法,R-CNN目标检测主要分为四个大的阶段:
产生候选区域:对于输入的图片,使用Selective Search方法(了解即可),选择出2000个候选区域(每个区域大小不一)。
特征提取:使用AlexNet对每一个候选区域提取特征,得到20004096维的特征向量。
注1:在进行特征提取之前,需要先对上一步生成的候选区域进行调整,使其变为227227,这是因为AlexNet输入是固定的,当然,其实卷积操作的输入可以不固定,全连接层的输入大小才是固定的,这也是后面几个模型会改进的。
注2:调整的方法比较暴力,不管输入是多大的图片,直接缩放到227*227
候选区域类别判断:将2000*4096维特征向量送入到21个(20个类别+1个背景)SVM分类器中,每一个SVM分类器包含4096个参数,所以可以看成两个矩阵相乘,即 ,这样就得到了每一个候选区域是某个类别的概率值。因为一张图片出现有上千个物品的可能性微乎其微,所以必定有大量的候选区域是重叠的,因此需要去除冗余的候选框。作者在此处使用非极大值抑制(NMS)方法来去除冗余候选框,对于每一个类别中IoU大于给定阈值的候选区域。这样就得到了每一个类别得分最高的一些候选区域。
使用回归器对候选框位置调整:对于上一步经过NMS筛选后的候选区域,其精度必定不够,所以需要进行进一步的调整,因为该部分在Faster RCNN中也有用到,所以具体的细节放在后文。
R-CNN 总结:
在文章中,作者认为 R-CNN 较之前的算法,能够取得30%的改进是基于以下两点:
R-CNN的不足:
速度慢,因为需要对selective search算法生成2K个候选区域分别提取特征,而又由于候选区域的重叠问题,所以这中间有着大量的重复计算(这也是后面的改进方向)。
训练步骤繁琐,需要先预训练CNN,然后微调CNN,再训练20个SVM,20个回归器,期间还要涉及用NMS去除候选冗余框。
smooth做x的判断,x>1的话,可能是异常值,所以这个时候就不用平方了,直接绝对值减去0.5.
Fast R-CNN 主要是在R-CNN和SPPNet的基础上进行改进的,有着以下几个优点:
Fast R-CNN与R-CNN相比主要有以下几点不同:
Fast RCNN总结:
在原文中,作者说Fast RCNN是R-CNN和SPPNet的一个快速更新,所以改进的内容并不是特别多,与后面的Faster RCNN提出了RPN相比,这只能算是一次打补丁的行为。
文中作者更多关心的是一些其它的问题,此处由于篇幅所限,仅简单列举一下作者研究的问题以及相关的结论,具体细节请自行看论文。
多任务训练是否有帮助?
结论:是的,多任务训练效果比分阶段训练更好。
尺度不变性:暴力方法还是巧妙技巧?
人话版:在统一图像特征尺度时,是使用SPPNet的空间金字塔池化还是本文中的ROI池化?
结论:两者效果差距微乎其微,甚至空间金字塔池化因为计算开销大,计算所需时间更长。
结论:将训练数据翻倍,可以将mAP提高2%~3%。
结论:网络直接输出各类概率(softmax),比SVM分类器性能略好
结论:否,候选区域从1K增加到10K的过程中,mAP先有所提升,然后略有下降,而且如果使用更多的候选区域,不仅没有帮助,反而会损害精度。
RPN(Region Proposal Network)区域建议网络取代SS。其他部分和Fast R-CNN一样。提供的建议区域变少了,300张。框的也更准了。它是训练出来的。
注意那里是Conv5的feature map。不是原始图片。
在这些anchor box的基础上,做RPN。
Faster RCNN
Faster RCNN是本文的主角,也是RCNN系列的集大成者。在具体讲解Faster RCNN之前,我们在这里先做一些提前的假设,方便讲解。本章节假定图片输入大小为800*600,且一次仅输入一张图片(也就是batch=1),即初始输入的维度为:(batch,图像通道数,图片高度,图像宽度)=(1, 3, 800, 600)。最后,因为有一些配置训练阶段和测试阶段是不一样的,为了讲解方便,我们假定本章节都处于测试阶段。
Faster RCNN 简介
Faster R-CNN算是RCNN系列算法的最杰出产物,也是two-stage中最为经典的物体检测算法。
Faster RCNN可以看作 RPN+Fast RCNN,其中RPN使用CNN来生成候选区域,并且RPN网络可以认为是一个使用了注意力机制的候选区域选择器,具体的网络结构如下图所示:
整个Faster RCNN网络可以分为三个部分,即backnone、RPN以及Roi pooling与分类网络,如下图所示:
如上图所示,Faster RCNN只使用了VGG16的前30层作为特征提取器,所以每一张图片在经过特征提取后,尺寸会变为原来的1/16,根据前文的假设,一张800600的图片变为5037的feature map,而且通道数从原来的3变为512。
RPN
RPN网络是Faster RCNN的精髓所在,将传统的候选区域生成方法使用卷积运算来代替,而且根据原文作者所说,使用卷积来生成候选区域使得RPN具有一定注意力机制,效果与前几代的RCNN相比,提升明显。
首先,RPN网络接受任意尺寸大小的feature map作为输入,然后会生成9K个(为什么是9K,而不是K个,下面会有说明)anchor,并且RPN有两个输出,一个是anchor的类别信息,也就是该anchor是背景还是前景(只要有要识别的物品就属于前景),还有一个输出是该anchor的位置偏移信息(如果该anchor是背景,则该输出不重要)。
如上图所示,就是文章作者给出的RPN网络结构,但这张图其实略去了许多细节,配合下面这张图进行讲解会好很多,如下图所示
如图所示,对于通过上一步特征提取器得到的feature map,根据最开始的输入假设,此时我们的feature map为(1, 512, 50, 37),接着这个特征图会经过一个33的卷积(用于对feature map进一步提取信息),该卷积不改变特征图的尺寸大小,然后会分别经过两个11的卷积,11卷积的主要作用就是降维,并且11的卷积也能看做一种全连接,所以此处图中上面的输出是anchor的类别信息(背景or前景),下面的输出是每一个anchor的位置偏移信息。
什么是Anchor
我们在这里多次提到了anchor,那什么是anchor,这其实是理解RPN的关键所在,我这里尽力进行解释一下。
事实上,每一个anchor都是一个矩形框,而要表示一个矩形框就需要四个参数,作者使用了两种表示方式:
好了,现在我想大家对于什么是anchor,以及如何生成的应该有了一个大致的理解,那么我接着往下讲。
或许此时大家有一个疑问,就是anchor的生成似乎与rpn没什么关系,其实现在生成的anchor还并不能进行使用,可以认为是比较粗糙的初成品,还需要进行进一步的精加工,这一步在R-CNN以及Fast RCNN也都有用到,也就是bounding box regression。
Bounding Box Regression原理
在上一小节中生成的anchors需要经过一系列的微调才能进行使用,微调的方法就是本节要介绍的bounding box regression(名字太长,我就简写成bbox reg了)。
在上文提到,作者在代码中表示一个anchor主要用了两种方式,其中第二种方式用的比较多,但在bbox reg中主要用第一种,也就是中心坐标+宽高的表示方式。
下面这张图我在前文也有,让我们重点关注图片的第二个输出,这一部分就是进行bbox reg的关键部分。需要注意的是,我在前文有提到,rpn有两个输出,一个是anchor的类别信息,另一个是该anchor的位置偏移信息,而此处就需要用到这个位置偏移信息来对之前生成的anchor进行修正。
判断anchor的类别
上一节中讲解了rpn如何对anchor的位置进行修正,这一节讲一下rpn如何识别每一个anchor的类别,注意这边进行的是二分类,即判断anchor的内容是背景还是前景,而不是具体的类别,具体的类别判断还在这之后。
下图就是rpn中对anchor类别进行判断的部分。
在feature map经过另一个1*1的卷积之后,维度变为了(1,18,50,37),其中通道数为18,又因为有9个anchor,所以每两个通道为一个anchor的类别,这两个通道分别代表了anchor是背景和前景的概率,这一部分需要特别注意特征维度的变化。
因为我们需要对类别进行softmax,但由于类别信息是在第1维(此处从0开始计数),所以需要进行reshape操作。
首先将类别信息放到第3维中,也就是变为(1,50,37,18)。
然后增加一个维度,变为(1,50,37,9,2),这样就可以对每一个anchor进行softmax分类。
完成softmax分类之后再去掉背景的概率,只保留anchor是前景的概率,此时维度变为(1,50,37,9,1)。
最后再进行一次reshape操作,去掉所有多余的维度,只保留两个维度,一个是batch,另一个是前景概率,即(1, 16650),这样就得到了每一anchor属于前景的概率。
对anchor的一些筛选工作
现在我们已经有一堆经过修正后的anchor,并且也知道了每一个anchor属于前景的概率,但我们细想一下,现在anchor的数量是不是太多了,我们只用了一张800*600的图像作为输入就生成了16650个anchor,如果全部作为RoI(Region of Intererst,也就是感兴趣区域或者说候选区域)输入到后续网络中,这计算量属实有点大,所以就需要进行一些筛选工作,这其实也就是RPN网络中Proposal层所做的工作。
首先,现在我们的anchor有许多因为是在边缘生成的,所以它们的坐标可能是负值,或者简单来说就是超出了图片的范围,那么就需要对这些anchor进行裁剪,把它们统一裁剪到图片范围内,也就是将anchor左上角坐标小于0的值用0代替,右下角坐标的X轴数值大于W就用W代替,Y轴数值大于H的用H代替。
经过上一步的裁剪工作,就会有许多anchor会变得很小,这里我们设定一个阈值,凡是小于16*16的anchor,我们都把它丢弃掉。
接着,因为我们已经有了每一个anchor属于前景的概率,那么很明显如果一个anchor属于前景的概率太小,那么也没有留着的必要性,所以对这些anchor的前景概率从大到小进行argsort,得到每一个anchor的排序索引,只取前6000个,到这一步anchor还是很多,但此时不能再鲁莽的去除anchor,因为有可能会有误判(毕竟这个前景概率只是rpn的预测,并不是真实的),此时需要用NMS方法把IoU大于0.7的进行合并,对于合并完的anchor再取前300个,这样就把输入到RoI网络的anchor的数量大大减少了。
注:需要注意的是,此处的6000以及300是测试阶段的配置,训练与此处不一样,后文会有介绍。
RPN小结
RPN部分内容比较多,第一次了解可能会被绕晕,此处我做一个简单的小结吧。
上图是我参照RPN部分的实现代码以及论文所绘制的,基本上把所有的细节点都囊括在了里面,大家配合上文的讲解以及此处的图应该能够理解了。
在作者代码中,主要把RPN主要分成了两部分,一个是RPN Head,另一个是Proposal,RPN Head主要负责anchor的生成、anchor位置偏移量预测以及anchor的类别判断;Proposal负责对生成的anchor进行进一步的筛选,将筛选后的anchor作为RoI输入到后续的网络中。
需要注意的是,因为不管是anchor的类别预测还是位置偏移量预测,这些都是在channel里面的,所以对这两个输出都需要使用pytorch的permute函数来将维度进行换位。
RoIHead
上文有提到,Faster RCNN就是RPN+Fast RCNN,上一小节已经对RPN讲解的比较详细了,只剩下一个RoIHead部分,这一部分与Fast RCNN很相像,所以此处只是简单介绍一下。
首先我们可以看到有两个输入,一个是黄色线的输入,这个是VGG16的输出,也就是feature map,另一个是紫色线的输入,也就是RPN的输出(每一个RoI的坐标信息)。
我们将上述两组数据输入到RoI Pooling中,得到每一个RoI对应位置的feature map,且每一个feature map的尺寸均为77(至于为什么都是77,在Fast RCNN中已有介绍),或许有人会有疑惑,输入的feature map与RoI是不匹配的,因为RoI的坐标都是从原始图像上生成的,很明显不能用于feature map上,但其实不用担心,在网络初始化的时候,已经把feature map与原始图像的缩放比值作为参数传入了,所以pytorch可以自动调整RoI的尺寸以适应feature map。
在经过RoI Pooling后,我们会得到300个77大小的feature map,每一个feature map的通道数是512(因为原始的feature map就是512维的),所以输出的shape就是(300, 512, 7, 7),然后经过一次reshape操作转为(300,5127*7),这样就可以输入到剩余的两层全连接层,这两个全连接层其实就是VGG16中最后去掉输出的分类器部分。
在经过两层全连接层后,会得到一个shape等于300的输出,可以认为是这300个RoI经过进一步特征提取后的深层特征,接着把这300个RoI分别进行类别预测以及边界框回归。上图中左边的FC 21(20个类别+1个背景)就是对RoI的类别进行预测,右边的FC 84是对每一个类别的边界框进行回归,特别要注意,是会对每一个RoI的每一个可能的类别都做边界框回归,这也是为什么输出维度是84的原因,即2*41(21个类别。每个类别4个坐标值)
Faster RCNN 小结
到这里算是把Faster RCNN除了训练部分的内容全部讲完了