前言
在目标检测领域,通常将网络的输出转为直观的检测框信息这一过程称为decode,就是根据网络的输出获取直观的检测框信息。那么encode就是将检测框信息(通常为ground-truth bounding box的坐标、宽高信息)转化为形为网络输出的信息,便于网络损失函数的求解。
两阶段检测的框架就是先通过启发式方法(selective search)或者CNN网络(RPN)产生一系列稀疏的候选框,然后再逐一对这些候选框进行分类和回归位置。二阶段的正负样本不均衡只局限在RPN,但是后续RCNN阶段的分类和定位在训练时就不存在这种问题,因为它是对得到的候选框进行正负样本的分配来确定训练样本,正样本数量会多很多。
单阶段方法,如Yolo和SSD,其主要思路是均匀地在图片的不同位置进行密集抽样,采样时可以采用不同尺度和长宽比,然后利用CNN提取特征后直接进行分类与回归,整个过程只需要一步,所以其优势是速度快,但是均匀的密集采样的一个重要缺点是训练比较困难,这主要是因为正样本与负样本(背景)极其不均衡(其实就是每个样本的损失项不平衡,导致网络倾向于优化损失项大的样本,因为他们对损失影响更大,参见Focal Loss),导致模型准确度稍低。
在文章开始之前想提下anchor的本质:anchor的本质其实就是预测框的先验, 基于anchor-based方法的原理其实就是在图片上暴力枚举各种不同大小,宽高比例的框使得“这种先验的预测框”遍布整个图,然后对每个框去做一个分类和回归。
2D目标检测(二阶段流派)流程图
- 将图像输入(RCNN中要求图像尺寸输入必须是227×227大小的,但是Fast RCNN和Faster RCNN因为有了ROI pooling所以不对输入图像尺寸进行限制了)网络得到对应特征图,VGG是对输入图像下采样16倍。
- 使用RPN结构生成候选框,RPN的输入是特征图H×W×256,有两个并联输出分别是H×W×2k和H×W×4k,k代表anchor个数,2代表预测框是前景还是背景的两个概率,4代表预测框的回归参数xywh。将RPN生成的候选框投影到特征图上获得相应的特征矩阵。注意:送往ROI pooling的这些候选框都是经过筛选了的,过滤了小于cls得分(RPN阶段对于每个框的class只有前景/背景)阈值的候选框,这些过滤后的候选框还经过了NMS。
- 将每个特征矩阵通过ROI pooling层缩放到7×7大小的特征图,接着将特征图展平通过一系列全连接层得到结果,具体来说就是在每一个特征矩阵的基础上并联两个全连接层,其中一个用于目标类别概率的预测,对于每一个候选框输出N+1个类别(1为背景)的softmax概率分数,即这N+1个类别概率分数的求和为1,最大的那个概率分数对应的类别作为这个预测框的类别;另外一个全连接层用于边界框回归参数的预测,对于每一个候选框输出(N+1)×4个参数,4表示xywh。在推理过程中,在拿到网络的输出后,首先丢掉类别为背景的框,然后需要设定一个阈值为Pc,例如Pc=0.6,我们删除掉所有概率小于0.6的预测边界框。对剩下的进行的NMS处理(每个类别对应单独的NMS),处理完后就对剩下的结果进行目标框解码操作即还原到原图并画框。
一、RCNN:
通过Selective Search算法对一张图像进行操作,根据像素的纹理,颜色等的相似性,将图像中相似的区域进行合并,最终得到很多个合并区域,每个合并区域就相当于一个边界框即ROI(感兴趣的地方)。然后从原图中把边界框切出来,但得到的这些边界框大小可能不一样,所以需要resize后(缩放成227*227的正方形),再把每一个正方形逐一喂到同一个CNN网络(ConvNet)提取出一个4096维度的特征(比如有2000个候选框就要跑2000次卷积神经网络的前向传播运算,fast rcnn就改进了这一个点,直接把原图先用卷积神经网络进行一次处理,所有的候选框共享这一次处理的feature map,这样就不用在跑2000次前向传播了,这个改进叫做共享卷积运算),获得这个特征后,用SVM进行分类,去预测每个框属于什么类别,比如PASCAL VOC有20个类别,那么就有20个支持向量机(一个SVM是二分类)来对这个4096维度的特征向量进行分类。这个4096维度的向量既用于线性支持向量机的分类,也用于boundding box的回归,回归也是用的20个回归器对上述20个类别的建议框(selective search算法选出来的候选框)精细修正候选框位置。
需要注意一点就是RCNN除了做分类任务外,还需要做位置的回归,就是bounding box的回归,因为通过Selective Search得到的ROI并不是很准,那么回归是怎么做的呢?这里的回归思想特别重要,包括yolov3都是用的这个思想。假设我们通过Selective Search得到了一个Proposal(就是上文说的ROI),就是下图的蓝色框,可以看出蓝色框不是很准,真正的ground truth应该是红色的框,所以可以看到他们是存在一个偏移的。假设蓝色框的坐标是Px,Py,Pw,Ph(这里坐标是指关于原图的像素坐标)这四个值,这个P就是代表Proposal的意思。真正想得到的结果是Gx,Gy,Gw,Gh,G代表Ground Truth(这里坐标是指关于原图的像素坐标)。而网络要学习的就是这两个框之间的偏移,即是一个变换Mapping,网络吐出来的就是蓝色框Proposal相对于红色框ground truth这个偏移量,但注意并不是直接吐出偏移量,这一点我在下面马上会讲到。 变换的公式就如同下图中Mapping部分的公式一样,拿第一行举例,Selective Search得到的框的中心点x坐标是Px,真正的Ground Truth的中心点x坐标是Gx,我们可以对这个Px进行一个偏移得到Gx,其中网络的输出是dx( P ),但是为什么网络不直接输出偏移呢?为什么还要在网络的输出后乘以一个框的宽Pw呢?这是因为比如对于不同大小的目标,可能IOU(重合的程度)都差不多,但是要偏移的像素可就差太多了,比如大目标可能要偏移10个像素,小目标偏移一个像素就可以了,这样的话偏移量变换范围太大,使得网络学习起来困难,所以如果网络输出的这个变换量与目标的大小解耦掉的话,这样会使得网络学习起来更加容易,所以最后网络需要学习的变换就是真正的偏移量除以Selective Search得到的目标的宽度。所以网络的学习目标就是下图中的target部分!
RCNN存在的问题:
二、Fast RCNN(仍然用的Selective Search算法来生成候选框)
RCNN检测速度太慢不能做到实时性,有两点,第一点因为要做Selective Search这个操作,一般会产生2000个ROI,存2000个ROI是非常耗时的。第二个点是因为2000个ROI是批量喂到CNN(VGG网络)中去做前向传播计算的,会逐一做2000次前向传播。
Fast RCNN解决的问题1:所以Fast RCNN就说能不能解决2000个ROI都要在CNN中分别进行前向传播(2000次)非常耗时的问题呢?能不能把这部分计算给共享呢?答案是可以的。此外还需要注意的是Fast RCNN的训练过程中(Fast RCNN的训练只有对候选框进行微调的训练)并不是直接使用SS算法提供的所有候选框,只是从这2000个候选框中随机采样了一小部分进行训练而已(论文中说,对于每张图片,从2000个候选框中采集64个候选框进行训练),采样的数据也分正样本和负样本,由候选框和GT的iou决定。正样本就是候选框确实存在所需检测目标的样本,负样本就是候选框里没有我们想要检测的目标。有个非常重要的关键点就是,经过CNN得到的特征图上的激活是和原图是有关系的,即原图某一个区域是有人的,那么在对应的特征图上那个区域的激活值会比较大,也就是说特征图上的激活值的位置关系是和原图对应到一起的。基于这个理论的话,就不需要每次单独把ROI喂到CNN中,实际上是可以在特征图上把ROI切出来,再进行后续的计算,但注意的是Selective Search得到的ROI是基于原图的ROI,所以在特征图上切ROI的时候要把原图对应位置等比例映射到特征图上。Fast RCNN解决的问题2:但这里又有一个问题就是切出来的ROI大小是不一样的,那怎么办呢?所以就将用于训练样本的候选框(ROI)通过ROI Pooling的方法得到大小一样的7×7的feature map。为什么要大小一样的呢?这是因为后续的全连接层进行分类和回归时都需要固定大小的输入。
ROI Pooling的操作流程如下图,十分好理解,Maxpooling out就是取每块的最大值。(说明:在此案例中region proposals 是57大小的,在pooling之后需要得到22的,所以在57的特征图划分成22的时候不是等分的,行是5/2,第一行得到2,剩下的那一行是3,列是7/2,第一列得到3,剩下那一列是4):
拿到了ROI feature向量后,注意这段说的都是指一个预测边界框输出!!!并联两个全连接层,其中一个全连接层(N+1个节点)用于目标概率的预测(分类器输出N+1个类别概率,1为背景),另一个全连接层作为边界框回归器,共输出(N+1)*4个节点个数。节点数中的4代表边界框的4个参数xywh,用于边界框回归参数的预测。
和YOLO不一样,Fast RCNN没有置信度损失。Fast RCNN的损失:
Fast RCNN损失中的分类损失(u对应目标真实的类别标签,u的取值为N+1,u=0时代表背景)
以下几张图是为了解释为什么Fast RCNN的多分类损失为-logpu的:
Fast RCNN损失中的边界框回归损失(参见前面分类损失的那张图上的文字,下图中的u代表目标的真实标签,当u大于等于1就代表我们的候选区域确实属于正样本(前景),这时候我们才计算边界框回归损失。当不满足艾弗森括号这个条件时,艾弗森括号这个值就为0,否则为1。)
三、Faster RCNN(丢弃SS算法引入RPN,首次引入anchor的概念,FPN+RPN+Fast RCNN=Faster RCNN)
解决的问题:Fast RCNN仍然用到了Selective Search(SS)这个操作,要选出2000个左右的ROI,是非常耗时的。所以Faster RCNN在想能不能用一个网络取代选ROI的这个过程,这个网络就是Faster RCNN提出的RPN。Faster RCNN的总体框架就是使用RPN结构生成候选框,将RPN生成的候选框投影到特征图上获得相应的特征矩阵,然后这些特征矩阵就通过ROI pooling层缩放到7×7大小的特征图(注意:ROI pooling层只接受用于训练样本的那些候选框(由固定采样个数得到的)作为输入,并不是RPN输出的所有候选框),接着将这些特征图展平通过一系列全连接层得到预测结果!这样相对于之前单独使用SS算法来说,现在Faster RCNN是一个整体,训练和预测全部融合到CNN网络中,速度能得到很大提升! Faster RCNN的做法就是将一张原图喂到CNN中后得到一张特征图,将这个特征图喂到region proposal network(RPN),切出一些我们想要的一些ROI,但由于Faster RCNN经过CNN得到的特征图有多个尺度的,所以ROI要去哪个尺度的特征图去切呢?有一个公式,可以通过ROI的尺寸大小得到要去哪个特征图切的索引。比如宽高更大的ROI,就会去更高级的特征图上去切,因为更高级的特征图感受野越大,更抽象即语义特征越丰富。ROI选出来后,就还是像Fast RCNN一样经过ROI Pooling,然后经过全连接网络做ROI的分类和位置回归。综上Faster RCNN就是多了一个RPN网络,还有把以前Fast RCNN的CNN(VGG网络)加了FPN会输出多个不同尺度的特征图,而VGG网络的话只会输出一个单尺度的特征图。
那RPN网络是如何工作的呢?如下图所示, 这里引入了一个anchor的概念(即自己预先设置的框), 假设说原图经过CNN输出得到的特征图大小是8×8,那么特征图上的每个点都会进行预测,每个点对应9个anchor(这是Faster RCNN这样设置的,当然你也可以设置更多),这9个anchor有不同的大小和长宽比(尺寸是在原图上来说的)。每个anchor会去负责跟自己最匹配的那个物体(匹配是指根据anchor和目标Ground Truth的IOU,如果这个anchor和某个目标的Ground Truth的IOU重叠度是最大的,那么这个anchor的label就是这个目标的Ground Truth,那么anchor就是负责这个目标),负责的意思就是指这个anchor会预测它自己和Ground Truth目标框之间的位置偏移以及自己这个anchor的类别(前景or背景),这里的操作和前面讲的RCNN的位置回归阶段是一样的,所以请对照着去理解!只不过RCNN当时回归的是Selective Search得到的ROI和Ground Truth之间的偏移,但这里对于RPN网络来说,anchor就当做Selective Search得到的ROI,所以RPN吐出来的就是anchor和ground truth的偏移,但还包括类别(前景or背景)。因为我们在训练阶段是根据IOU给anchor安排的label,所以在测试的时候,特定的anchor就会预测特定大小的物体。Faster RCNN对特征图上的每个点都会进行9个预测,所以是一个非常稠密的预测!
RPN具体是怎么预测出候选框的呢?
参见下图,下图的中右下角部分,是在conv feature map上做了3x3卷积且num_output=256,但输出尺寸和conv feature map一样,相当于每个点又融合了周围3x3的空间信息。如果我们每个点设置k个anchors,那么特征图上的每个点就会生成2k个类别scores(具体实现就是卷积核大小为1×1,卷积核个数为2k的卷积层来进行处理,需要注意的是如果实现用的是多分类交叉熵损失的话,卷积核个数就是原来的2k,但如果实现用的是二分类交叉熵损失,那么其实卷积核个数应该是1k) 和 4k个边界框回归参数(具体实现就是卷积核大小为1×1,卷积核个数为4k的卷积层来进行处理),对于分类来说,2个为一组(因为每两个对应一个anchor的,只有前景和背景这两个类别)。对于回归来说,4个为一组(因为每四个对应一个anchor的)。
还需要注意的是,在训练RPN时,是从所有anchors中采样256个anchor拿来训练RPN网络,不然全部anchors拿来训练就太多了!这256个anchor是由正样本和负样本两部分组成,比例为1:1,定义正负样本的方式也是由anchor和GT的IoU决定。
对于一张1000×600×3的图像,大约有60×40×9(20k)个anchor,9为anchor的数量,忽略掉跨越边界的anchor和对softmax scores由大到小排序anchors以后,剩下约6000个anchor。对于RPN生成的候选框之间存在大量重叠,基于候选框的cls得分,采用NMS,IoU设置为0.7,这样每张图片最后只剩2000个候选框,正好就和SS算法提供的候选框个数差不多了。后续Faster RCNN第二阶段的微调训练也是从这2000个候选框中采样部分候选框进行训练,并不是全部拿来进行训练,采样的法则也是先找出正例和负例(按照和GT的IoU来区分正负例),然后按照正负例的比例留下固定采样个数的候选框(比如200个)送进RCNN做训练。
接下来看看Faster RCNN中的FPN:
FPN的原理就是如下图所示,通过横向连接,将底层的强位置信息的特征和高层语义特征的信息进行融合,因为向上插值(上采样)时强语义信息仍然是强语义信息,这样融合后得到的特征图既包含强的语义信息(对分类有好处),又包含了强位置信息(对位置定位有好处)。
下图是Faster RCNN的backbone:ResNet-FPN,这个backbone就是参照FPN的思想,输出多个不同尺度的特征图,通过横向连接,使得输出的特征图既包含强的语义信息(对分类有好处),又包含了强位置信息(对位置定位有好处)!这里在融合后又做了一个3×3的卷积是因为融合时两特征图相加后有个混叠效应,为了去除这个效应所以做了一个3×3的卷积。然后从下图右下角处可以看到,Faster RCNN中的RPN的输入不是一张特征图,而是多个尺度的特征图!
四、Mask RCNN
FPN+RPN+Faster RCNN+Mask Prediction = Mask RCNN
下图是Mask Prediction分支是一个全卷积的,最后输出的通道数是80,代表80个类别,要注意的是不管你的物体大小是怎么样的,最终预测得到的mask都是28×28的大小的,所以要返回原图尺寸的话,就要根据proposal的大小去返回到原图,所以不同大小的物体才有不同mask的大小:
线性插值:
y等于y1和y0的组合,y1和y0前面的系数就看做权重!
双线性插值
双线性插值就是进行多次的线性插值,比如我们有Q12,Q22,Q11,Q21这四个点,我们想知道P这个点是多少该怎么做呢?首先我们先去做两次的线性插值,然后再在y方向再做一次线性插值。不要看着很复杂,按照权重的思想去理解就很简单了。
ROI Align
如下图所示,存在的问题就是Faster RCNN输出的ROI坐标可能存在小数,然后在ROI Pooling中应用Maxpooling时还不均等划分格子!所以Mask RCNN提出了ROI Align就是替代了ROI Pooling,要和原图进行对齐。
ROI Align基本思想就是保留了两次的小数,小数的位置就用双线性插值得到对应位置的值。
Mask RCNN的mask loss设计也比较特别,允许每个类都生成独立的掩膜,避免类间竞争。这样做解耦了掩膜和种类预测。不像FCN的做法,在每个像素点上应用softmax函数,整体采用的多任务交叉熵,这样会导致类间竞争,最终导致分割效果差。
最后再梳理下Mask RCNN的整体流程(结合我上面写的Faster RCNN的那些内容来看应该很容易理解):
1.首先根据FPN不同Level特征图的尺寸, 结合固定的长宽比和面积得到固定的Anchors (特征图有N个点,每个点如果有5种面积大小和3种长宽比假设, 则共有N*15个Anchors), 每个Anchors通过与GT计算IoU判断属于前景还是背景.
2.RPN通过1*1卷积会在每个位置点生成 每个点潜在Anchor数x4 Channel的相对偏移和 每个点潜在Anchor数x1 Channel的目标得分. 把输出结果在每个点分别和Anchors合并可以得到Proposals. 并根据前景置信度objectness_logits和NMS筛选出TopK Proposals (可以设置前景后景数量比例).
3.Detection Head和Mask Head分别根据proposals大小选择对应Level的特征图并得到每个Proposal对应的特征, 通过ROI Align后得到各自尺寸的特征图比如(Box 7x7, Mask 14x14). 然后分别通过各自的Head, 其中Box Head得到Proposals在原图的绝对坐标, Mask Head得到目标的ClassNumx28x28的Mask(有一个反卷积).
4.Mask分支会根据预测的类别抽出对应Channel的28x28Mask, 并通过sigmoid转换为概率. 然后Mask会经过后处理, 结合Proposal坐标和图像尺寸进行resize和背景填充得到原图尺寸的Mask, resize部分参考detectron2-> _do_paste_mask -> F.grid_sample, 并结合阈值0.5实现前后景分离得到最终结果.
Mask后处理参考
5.这个原图尺寸的Mask会结合Box通过对应数据集的Evaluator进行评估.
评价指标:
目标检测中的AP,mAP
Refer:
计算机视觉面试题-经典目标检测网络总结,强烈推荐!
一文读懂Faster RCNN
Faster RCNN理论合集