(五)比赛中的CV算法(下1)目标检测算法:R-CNN家族

了解了基本概念,开始上手目标检测吧。在接下来这三个经典网络的介绍中,我们尽量忽略细节上的推导如卷积的通道数和维度,特征图的大小等,而专注于介绍网络实现的思想和总体方法。因此笔者默认你已经了解卷积神经网络的原理和目标检测的基本概念。如果要深入了解并运用obj detection还是要仔细阅读这些经典网络的论文,精读它们的源码实现!

  • R-CNN

    R-CNN为了减少候选区域的数量,在原图上根据不同的比例、颜色、纹理和形状划分出许多区域(例如使用k-means等聚类算法),随后再根据区域之间的相似性对这些区域进行合并,这一步被称作selective search,会得到大约2000个候选区域即ROI(2000是人为确定的让合并算法终止的值,也可以选择其他值,过大的值会导致很大的运算开销;太小的值又容易将小目标区域被合并而使得漏识别或定位不准);然后对这些区域通过取外接矩形的方法得到一个个可能存在目标的候选框,把这些候选框全部拉伸成正方形(保证cnn的输入相同方便投入相同的网络中);接着在这些区域上运行CNN得到特征图,将特征依次投入到多个的二分类SVM(为每个类训练一个SVM,输出只有是和不是)和角点回归网络中(一幅图像到4个坐标/8个点的映射,看作一个回归问题),得到每个区域的分类与目标框角点的坐标;最后再运行NMS(non-maximum suppression)后处理(Postprocessor)去除一些重叠的目标框,得到分类结果与预测框。

    通过selective search得到的区域图示,对这些连续的色块求出外接矩形即可得到预测框

    整个算法的pipeline如下:

     R-CNN相比最原始的滑动窗口法,采用selective search的方法大大缩小了搜索空间,只在那些有可能有目标的地方运行CNN,使得基于神经网络的目标检测算法变得可用(原来的算法复杂度根本不是多项式时间内可以解出结果的),虽然处理一帧图像的时间为50s量级(怎么还是那么长啊喂),不过相对之前的滑窗方法已经有了极大的提升,R-CNN的成果也让很多目标检测研究人员把目光从传统特征匹配转向了深度学习。

    R-CNN也是首个提出用训练好的图像分类网络(R-CNN使用的是pre-trained的ImageNet)作为检测网络的Backbone再在之后的训练中进行微调(fine-tuning)方法的paper。预训练+微调的方法也一直沿用至今。

虽然R-CNN已经大大降低了目标检测的工作量,但是其动辄百秒的检测时间还是令人难以接受。其痛点不仅在与速度,在特征获取和复用上也有很大的问题:

  1. 没有复用特征,直接在原图上裁切子图,会出现大量的区域重叠,而R-CNN又对每一个ROI都运行了一次CNN,从而造成了非常多的重复计算,还是过于暴力了。

  2. 直接对ROI生成的外接矩形进行拉伸使其变成正方形,目标的特征可能会有损失、变形。


既然已经有人开了先河我们也分析了优缺点,那么,有请下一位选手Fast R-CNN登场(名字也够直接的哈,我R-CNN不要面子的吗)!

  • Fast R-CNN

    废话不多说,直接上pipeline:

    既然还是叫R-CNN,那么我们就对比着R-CNN来看看这个Fast到底有什么能耐吧。它仍然使用了selective search的方法来生成候选区域,不过它不再把每个ROI区域都投入相同的CNN中,而是先直接对图片运行CNN,得到整张图片的feature map,然后把由原图经过selective search得到的ROI根据映射关系(图像在经过ConvNet后会按一定比例缩小)对应到feature map上,也就是上图的ROIs from a proposal method。以上的操作便改进了R-CNN的第一个缺点,避免了大量重复的卷积运算,让所有可能存在目标的预测框共享了很多特征。

    紧接着使用对这些ROI使用ROI Pooling的技术,把所有的ROI通过这种特殊的Pooling缩放成相同大小以便投入之后的全连接层,这种技术也尽量避免了强行缩放带来的特征变形、损失(虽然还是在一定程度上有影响,之后版本的Mask R-CNN所采用的ROI Align通过双线性插值进一步改善了这一步特征提取)。

  • 此处mark,我们会发现进行检测的时候只使用了对应ROI的feature,feature map的其他部分不会被检测头使用,因此Fast R-CNN和之后的Faster R-CNN只提取了前景信息而忽略了和目标一同出现的背景,在之后的 yolo 算法的误差分析和优缺点整理中我们会对这个mark进行分析。

    ROI Pooling图示,例如这里想要采集2x2的特征,就把对应区域的特征图(这里是5x7)尽量平均地分为四个区域(3+2=5,4+3=7,如果需要得到特征的长宽刚好是feature map的长宽的公约数就能平均分了)

    最后就是对FC后得到的特征进行分类和bbox回归了,Fast R-CNN使用线性回归+softmax的方法替代了原来的多个二分类SVM进行目标分类,这样能引入类间的训练竞争;bbox回归还是和原来保持一致(毕竟当时没啥可以优化的),这两部分工作是并行的。

    经过这一通操作,不仅提升了识别的准确率,还直接把平均单帧处理时间干到了2s!几十倍的速度提升已经非常可观了 。但是还是达不到实时性的要求,怎么办呢,我们仔细分析一波Fast R-CNN存在的问题:

    1. 仍然使用selective search,这部分工作在整个算法中占了大概七八成的时间,对上千个的区域进行运算、合并的开销还是挺大的。

    2. ROI pooling这部分会损失精度,还有提升空间。


    因为我们的精神是更高更快更强(卷就完事了!),所以请出下一位选手Faster R-CNN

  • Faster R-CNN

    这个网络相对于Fast R-CNN的改动就比较大了,最重要的贡献是提出了RPN(region proposal network)替代selective search,用于提出候选区域,大大降低了时间开销并且提高了识别精度。同时由于不再使用selective search,为了保证对不同尺度(大小)的目标的检测效果,加入了anchor作为目标尺度的先验信息。听不懂?先看看pipeline:

     和Fast R-CNN一样,先通过ConvNet得到整张图片的特征图,随后将此特征图投入RPN中,而RPN的输出是可能存在目标的候选区域,既然是网络那么还一是一种映射:特征图到候选区域的映射。这里得到的候选区域数量就是可能存在目标概率最大的k个区域,至于如何得到请看之后的讲解。得到候选区域后,还是对这些ROI进行特征提取(ROI pooling),之后的流程就和Fast R-CNN一模一样了,我们重点说说RPN。

    为了理解RPN的工作原理,就必须先了解anchor。前文中的滑动窗口检测我们提到用大小不同的滑窗来遍历整个图像,分别投入CNN进行检测。使用大小不同的滑窗就是为了对应不同尺度的目标,而遍历图像则是在搜索空间中寻找可能的目标。Selective Search是通过合并相似的区域来进行区域提议(生成候选的ROI)。显然在这个过程中我们都加入了先验的知识来确定目标,seletive search就认为属于一个目标的区域的纹理和颜色等特征应该是相似的,由此减少搜索空间的大小,即使是滑动窗口法也加入了一些假设如目标的大小。这些先验信息都以超参数的形式加入检测网络(也就是“炼丹”中需要认为修改的参数)。那么RPN就是利用anchor引入先验信息从而缩小搜索空间。首先我们把图像划分为一定数量的格点,然后以每个格点为中心,生成一组比例和长宽各不相同的候选目标框(有同学会想,这还不是在抓瞎吗,这要怎么知道候选框里有没有目标?让我们先保留这个问题)下图是anchor的形象解释。​

 anchor就是在图像上预置的一堆大小长宽形状不同的候选框,图源知乎-emiya-目标检测算法设计思想

 在Faster R-CNN的RPN中,我们使用9种anchor,在每个格点上生成这样一组anchor

在进入RPN前,由ConvNet得到的feature map为50x38,于是我们对此feature map的每一个点都设置一组9个anchor(注意要映射回原图,既然是ROI提议,那么anchor肯定是设置在原图上的,因此要进行一个比例缩放)

​上图中右边密密麻麻的就是生成的anchor了,好家伙算一下总共有17100个ROI!到这里为止,采取的方法看起来仍然是“瞎猜”并且候选位置还是太多;而且即使是使用了这么多的anchor,有些物体还是没办法被很好的框住,有可能没完全框住,也有可能是框太大。下面就进入筛选anchor和修正anchor环节。以下给出RPN的结构:

 RPN网络的结构,图源知乎-白裳-https://zhuanlan.zhihu.com/p/31426458

​​进入红色框之前的是ConvNet得到的feature map

​首先从再对ConvNet得到的特征图进行一次3x3卷积降低参数量,然后分别投入到两个并行的网络分支。上面的分支通过一个1x1卷积再经过softmax函数,判断每个anchor存在物体的概率(不管是哪一种目标,只要有目标在里面就行)。那么的一个问题解决了,我们可以通过物体存在的概率来对anchor进行初步筛选。但是你可能还会想,为什么就得到了每个anchor区域存在物体的概率了?关键就在于3x3卷积和1x1卷积构成的这个小网络,我们会通过训练,让这个网络成为一个回归器,之后再通过softmax函数得到每一个anchor包含物体的概率。(映射!还是映射!网络结构中的reshape暂时不用管他,这个是代码实现的时候需要关心的问题,reshape后可以方便softmax函数的计算,算完后再reshape回去罢了)

接下来看第二条分支是怎么解决anchor对物体的贴合度不够的问题的。这个分支会习得一个修复anchor使得anchor能够更接近物体边框的映射。以下面这架飞机的检测为例,绿色的框是训练标记,红色框是RPN生成的anchor中最接近标记的那一个,显然此anchor还是只能覆盖飞机的主体步部分,机翼没有被包含进来。

 如果要通过变换来使得生成的红色预测框贴近绿色框(GT),最简单的办法是什么?那肯定是先平移到合适的位置,然后再进行一定比例的缩放。如果anchor和gt差距不大,那么这种变换很显然是可以被近似成线性变换的,因此我们假设生成的anchor中最接近gt的那个已经和gt框很相似了,只需要用一个平移+缩放来进一步贴近它。所以我们会通过第二个分支中的1x1卷积来学习这种变换关系,即对bbox中心的平移(dx,dy)和横向纵向的拉伸比例(kx,ky)。那么经过训练,这部分网络就会学习到一个对anchor进行修正的映射关系了。网络会为每个anchor都输出一个[dx,dy,kx,ky]数组(属于是量身定制了)。

ok,两步分支结束,接下来我们就要把对anchor的筛选和对anchor的修正给综合起来,为下一步的bbox四角点位置回归和分类提供候选区域。请看RPN结构中的Proposal层,它大概有如下几个步骤:

  1. 根据所有anchor包含物体的概率,对anchor进行筛选,得到概率最大的n个候选框(n还是一个自选数)。

  2. 利用第二个分支得到的[dx,dy,kx,ky]对这些筛选得到的anchor box进行修正。

  3. 对超出图像边界的anchor进行裁切使得它其中一条或两条边变成图像的边界(在生成anchor阶段,处在边缘的格点生成的较大的anchor必然会超出图像边界;同时在进行anchor box的修正时,也有一部分anchor会因为变换而出界)。

  4. 去除特别小、比例异常的anchor(经过变换后可能会出现这样的问题)。

  5. 对剩下的anchor进行非极大值抑制。

  6. 从剩余的anchor中随机选取128个作为正样本,再在被筛选调的anchor中选128个作为负样本,把这些anchor作为候选区域,交给Faster R-CNN的下一个部分。至此,RPN网络即候选区域提议的工作结束。

下一步就是和Fast R-CNN一样,通过ROI Pooling提取候选区域对应的feature map上的特征,把特征连接到FC层,再分别投入bbox角点回归网络和分类网络,得到更精确的目标框和目标类别。可以看到,相比于Fast R-CNN变动最大的就是利用RPN替代Selective Search这一步,利用网络来提取深度特征(用于生成候选框的特征),大大提高了提议区域的精确度;同时也避免了逐像素、逐区域的合并工作,提高了速度,平均单帧处理速度来到了0.2~0.4S! 

Faster R-CNN也首次完成了目标检测任务的“深度化”,即整个检测流程都使用神经网络连接完成;在高速的同时成为了当时的state of the art(检测任务竞赛的第一名);这项工作基本奠定了区域提议+ROI-CNN(区域分类网络)的two-stage检测网络结构,从此全面开启了基于CNN的目标检测。两阶段的网络也让监督信息(设计的loss function和训练数学)能够在不同层次更有针对性地对网络参数的学习进行“指导”。

Faster R-CNN的成果在当时是振奋人心的,终于让大伙儿看到了基于网络方法的实时检测的希望!不过一秒3、4帧的速度在实时场景还是难堪大用,并且Faster R-CNN也存在一些问题:

  1. 和Fast R-CNN一样使用ROI Pooling丢失了一些特征。

  2. 属于two-stage,分为区域提议和分类+回归两个阶段而不是端到端(end-to-end)的方法。RPN的速度还是不够快。

  3. 只从ConvNet的最后一个特征图上提取特征,分辨率较小因此对于多尺度小目标的检测问题没办法很好地解决。

  4. 筛选候选框使用NMS而分类时使用softmax,这样可能会把有部分重叠的目标或是大目标框内的小目标给筛除。


我们在介绍算法的时候都是从直观的角度帮助大家理解相关的概念和整个pipeline,显然这距离自己编写算法是有一定的差距的。因此,想要更好地理解相关知识,一定要去阅读paper原文,查看paper提供的开源代码或是Github上其他开发者的复现版本。这也要求读者掌握至少一个网络框架,这里推荐使用Caffe,上手相对容易并且编写网络也是最简单的。(显然需要先学python)

之后笔者也会专门开一个专栏,和大家一起复现cv领域的经典算法和前沿算法!包括传统的特征匹配算法,之后也会在专栏中一起介绍,欢迎各位前来围观,希望大佬多多指导!

如果觉得我写的还不错,请点赞关注收藏三联哦~

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值