我们从基于区域的物体探测器(更快的R-CNN,R-FCN,FPN)中学到了什么?

乔纳森惠以下
2018年3月28日
在本系列中,我们将全面介绍物体检测。在这里的第1部分中,我们介绍了基于区域的物体探测器,包括快速R-CNN,更快的R-CNN,R-FCN和FPN。在第2部分中,我们将研究单射击探测器。在第3部分中,我们将介绍性能和一些实现问题。通过在一个环境中研究它们,我们研究什么是有效的,什么是重要的,哪些可以改进。希望通过研究我们如何到达这里,它将为我们提供更多关于我们前进方向的见解。
第1部分:我们从基于区域的物体探测器(更快的R-CNN,R-FCN,FPN)中学到了什么?
第2部分:我们从单发物体探测器(SSD,YOLO),FPN和焦点损耗中学到了什么?
第3部分:设计选择,经验教训和对象检测趋势?

滑动窗口探测器

自AlexNet赢得2012年ILSVRC挑战以来,使用CNN进行分类已经占据了该领域的主导地位。用于物体检测的一种蛮力方法是从左侧和右侧以及从上到下滑动窗口以使用分类来识别物体。为了在不同的观察距离检测不同的物体类型,我们使用不同尺寸和纵横比的窗户。

滑动窗(从右到左,上下)
我们根据滑动窗口从图片中剪切出补丁。由于许多分类器仅采用固定大小的图像,因此修补程序会发生扭曲。然而,这不应该影响分类准确性,因为分类器被训练以处理变形图像。

将图像变形为固定大小的图像。
将扭曲的图像块馈送到CNN分类器中以提取4096个特征。然后我们应用SVM分类器来识别类和边界框的另一个线性回归量。

滑动窗检测器的系统流程。
下面是伪代码。我们创建了许多窗口来检测不同位置的不同对象形状。为了提高性能,一个明显的解决方案是减少窗口数量。 窗口中的窗口
patch = get_patch(图像,窗口)
结果=检测器(补丁)

选择性搜索

我们使用区域提议方法来创建用于对象检测的感兴趣区域(ROI),而不是强力方法。在选择性搜索SS)中,我们从每个单独的像素开始作为其自己的组。接下来,我们计算每个组的纹理,并组合两个最接近的组。但是为了避免单个区域吞噬其他区域,我们更喜欢先将较小的组分组。我们继续合并区域,直到所有内容组合在一起。在下面的第一行中,我们展示了如何增长区域,第二行中的蓝色矩形显示了我们在合并期间可能实现的ROI。

(图片来源:van de Sande等,ICCV’11)

R-CNN

R-CNN利用区域提议方法来创建大约2000个ROI感兴趣的区域)。区域被扭曲成固定大小的图像并单独馈送到CNN网络。然后是完全连接的层,以对对象进行分类并细化边界框。

使用区域提议,CNN,仿射层来定位对象。
这是系统流程。

R-CNN的系统流程
R-CNN的投资回报率低得多但质量更高,比滑动窗更快,更准确。 投资回报率=
ROI中投资回报率的区域提示(图像)
补丁= get_patch(图像,投资回报率)
结果=检测器(补丁)

边界框回归量

区域提案方法计算密集。为了加快这一过程,我们经常选择一种较便宜的区域建议方法来创建ROI,然后使用线性回归量(使用完全连接的层)进一步细化边界框。

使用回归将原始ROI从蓝色细化为红色。

快速R-CNN

R-CNN需要许多提议准确并且许多区域彼此重叠。R-CNN的训练和推理速度很慢。如果我们有2,000个提案,则每个提案都由CNN单独处理,即我们针对不同的投资回报率重复提取2000次特征。
我们不是从头开始为每个图像补丁提取特征,而是使用特征提取器(CNN)首先提取整个图像的特征。我们还使用外部区域提议方法(如选择性搜索)来创建ROI,后者与相应的要素图组合以形成用于对象检测的补丁。我们使用ROI池将贴片扭曲到固定大小,并将它们馈送到完全连接的层以进行分类和定位(检测对象的位置)。通过不重复特征提取,Fast R-CNN显着缩短了处理时间。

在要素图上应用区域建议,并使用ROI池形成固定大小的修补程序。
这是网络流程:

在下面的伪代码中,昂贵的特征提取正在逐渐退出for循环,这是因为它针对所有2000个ROI执行而显着提高了速度。快速R-CNN在训练中比R-CNN快10倍,在推理中快150倍。 feature_maps = process(image)
ROI =
ROI中ROI的region_proposal(image)
补丁= roi_pooling(feature_maps,ROI)
结果= detector2(补丁)Fast R-CNN的一个主要特点是整个网络(特征提取器,分类器和边界框回归器)可以通过多任务损失(分类丢失和本地化丢失)进行端到端训练。这提高了准确性。
投资回报率
由于Fast R-CNN使用完全连接的层,因此我们应用ROI池来将可变大小的ROI扭曲成预定义的大小形状。
让我们通过将8×8特征映射转换为预定义的2×2形状来简化讨论。

  • 左下方:我们的功能图。
  • 右上角:我们将ROI(蓝色)与要素图重叠。
  • 左下图:我们将ROI分成目标维度。例如,对于我们的2×2目标,我们将ROI分成4个具有相似或相同大小的部分。
  • 右下角:找到每个部分的最大值,结果是我们的变形特征映射。

输入要素图(左上),输出要素图(右下),蓝框是ROI(右上)。
因此,我们得到一个2×2特征补丁,我们可以将其输入分类器和盒子回归器。

更快的R-CNN

快速R-CNN依赖于外部区域提议方法,如选择性搜索。但是,这些算法在CPU上运行并且速度很慢。在测试中,快速R-CNN花费2.3秒进行预测,其中2秒用于生成2000个ROI。 feature_maps = process(image)
ROIs = region_proposal(image)#贵!
投资回报率中的ROI
补丁= roi_pooling(feature_maps,ROI)
结果= detector2(补丁)更快的R-CNN采用与快速R-CNN类似的设计,除了它用内部深度网络替换区域提议方法,而ROI则来自特征映射。新区域提案网络(RPN)更高效,并且在生成ROI时每个映像运行10毫秒。

网络流量与Fast R-CNN相同。
网络流程类似,但区域提案现在由卷积网络(RPN)取代。

外部区域提议由内部深层网络取代。
区域提案网络
区域提议网络(RPN)将来自第一个卷积网络的输出特征映射作为输入。它在特征映射上滑动3×3过滤器,以使用像ZF网络这样的卷积网络(下面)进行类别无关区域提议。其他深度网络如VGG或ResNet可用于以速度为代价进行更全面的特征提取。ZF网络输出256个值,这些值被馈送到2个单独的完全连接的层中以预测边界框和2个对象性得分。该对象性测量框是否包含对象。我们可以使用回归量来计算单个对象度得分但是为了简单起见,更快的R-CNN使用具有2个可能类的分类器:一个用于“具有对象”类别而一个用于没有(即背景类别)。

对于要素图中的每个位置,RPN进行k猜测。因此,RPN每个位置输出4×k坐标和2×k分数。下图显示了具有3×3滤波器的8×8特征图,并且它输出总共8×8×3个ROI(对于k = 3)。右侧图表显示了单个位置提出的3个提案。

在这里,我们得到3个猜测,我们稍后会改进我们的猜测。由于我们只需要一个正确的,如果我们的初步猜测有不同的形状和大小,我们会更好。因此,更快的R-CNN不会提出随机边界框提议。相反,它预测像δx,δy这样的偏移相对于一些称为锚点的参考框的左上角。我们限制了那些偏移的值,所以我们的猜测仍然类似于锚点。

为了对每个位置进行k个预测,我们需要以每个位置为中心的k个锚点。每个预测与特定锚相关联,但不同位置共享相同的锚形状。

这些锚是经过精心预先选择的,因此它们是多样的,能够很好地覆盖不同尺度和纵横比的真实物体。这可以通过更好的猜测指导初始训练,并允许每个预测专注于某种形状。这种策略使早期训练更加稳定和轻松。
更快的R-CNN使用更多的锚点。它配置了9个锚箱:3种不同的比例,3种不同的宽高比。每个位置使用9个锚点,每个位置生成2×9个对象度分数和4×9个坐标。

资源

在不同的论文中也称为> 先验或> 默认边界框

R-CNN方法的性能

如下图所示,更快的R-CNN甚至更快。

基于区域的完全卷积网络(R-FCN)

假设我们只有一个特征图检测到脸部的右眼。我们可以用它来定位一张脸吗?这应该。由于右眼应位于面部图片的左上角,我们可以使用它来定位面部。

如果我们有专门检测左眼,鼻子或嘴巴的其他特征图,我们可以将结果组合在一起以更好地定位脸部。
那么我们为什么要经历所有麻烦呢。在更快的R-CNN中,探测器应用多个完全连接的层来进行预测。拥有2,000个投资回报率,价格昂贵。 feature_maps =处理(图像)
的ROI = region_proposal(feature_maps)
用于在感兴趣区ROI
补丁= roi_pooling(feature_maps,ROI)
class_scores,盒=检测器(贴片)#昂贵!
class_probabilities = softmax(class_scores)R-FCN通过减少每个ROI所需的工作量来提高速度。上面的基于区域的特征图与ROI无关,并且可以在每个ROI之外计算。剩下的工作要简单得多,因此R-FCN比快速R-CNN更快。 feature_maps = process(image)
ROIs = region_proposal(feature_maps)
score_maps = compute_score_map(feature_maps)
ROI中的ROI
V = region_roi_pool(score_maps,ROI)
class_scores,box = average(V)#更简单!
class_probabilities = softmax(class_scores)让我们考虑一个5×5的特征映射M,里面有一个蓝色方形对象。我们将方形对象平均分成3×3个区域。现在,我们从M创建一个新的特征图,仅检测正方形的左上角(TL)。新功能图看起来像右下方的那个。仅激活黄色网格单元 [2,2]。

从左侧创建新的要素图以检测对象的左上角。
由于我们将正方形划分为9个部分,我们可以创建9个特征映射,每个特征映射检测对象的相应区域。这些特征图称为位置敏感分数图,因为每个图检测(分数)对象的子区域。

生成9个得分图
假设下面的虚线红色矩形是建议的ROI。我们将其划分为3×3个区域,并询问每个区域包含对象的相应部分的可能性。例如,左上角ROI区域包含左眼的可能性有多大。我们将结果存储在右图中的3×3投票数组中。例如,vote_array [0] [0]包含关于我们是否找到方形对象的左上角区域的分数。

将ROI应用于要素图以输出3 x 3阵列。
将得分图和ROI映射到投票数组的过程称为位置敏感的 ROI池。这个过程非常接近我们之前讨论过的ROI池。我们不会进一步介绍它,但您可以参考未来的阅读部分以获取更多信息。

将ROI的一部分叠加到相应的得分图上以计算V [i] [j]
计算位置敏感ROI池的所有值后,类别分数是其所有元素的平均值。

投资回报率池
假设我们有C类要检测。我们将它扩展为C + 1类,因此我们为背景(非对象)添加了一个新类。每个班级都有自己的3×3分数图,因此总共有(C + 1)×3×3分数图。使用自己的一组得分图,我们预测每个班级的班级得分。然后我们在这些分数上应用softmax来计算每个类的概率。
以下是数据流。对于我们的例子,我们下面有k = 3。

我们的旅程到目前为止

我们从基本的滑动窗口算法开始。 窗口中的窗口
patch = get_patch(图像,窗口)
结果=检测器(补丁)然后我们尝试减少窗口的数量,并在for循环之外移动尽可能多的工作。 投资回报率=
ROI中投资回报率的区域提示(图像)
补丁= get_patch(图像,投资回报率)
结果=检测器(补丁)在第2部分中,我们进一步完全删除了for循环。单发探测器可在单次射击中进行物体探测,无需单独的区域建议步骤。

进一步阅读FPN,R-FCN和Mask R-CNN

FPN和R-FCN都比我们在此描述的更复杂。如需进一步研究,请参阅: