Faster R-CNN:详解目标检测的实现过程

本文详细解释了 Faster R-CNN 的网络架构和工做流,一步步带领读者理解目标检测的工做原理,做者本人也提供了 Luminoth 实现,供你们参考。git

 

  • Luminoth 实现:https://github.com/tryolabs/luminoth/tree/master/luminoth/models/fasterrcnngithub

 

  去年,咱们决定深刻了解 Faster R-CNN,阅读原始论文以及其中引用到的其余论文,如今咱们对其工做方式和实现方法有了清晰的理解。算法

  咱们最终在 Luminoth 中实现了 Faster R-CNN,Luminoth 是基于 TensorFlow 的计算机视觉工具包,易于训练和监控,支持多种不一样的模型。到目前为止,Luminoth 已经吸引了很大的关注,咱们在 ODSC Europe 和 ODSC West 的论坛中也介绍过这个项目。(ODSC,Open Data Science Conference,专一于开源数据科学的会议)。网络

  基于开发 Luminoth 的工做和过去的报告,咱们认为把全部实现 Faster RCNN 的细节和相关连接整合到一篇博客中是一个不错的点子,这对将来其余对此领域感兴趣的人会颇有意义。架构

背景

  Faster R-CNN 最先在 2015 年的 NIPS 发布。其在发布后经历了几回修改,这在以后博文中会有讨论。Faster-RCNN 是 RCNN 系列论文的第三次迭代,这一系列论文的一做和联合做者是 Ross Girshick。框架

  这一切始于 2014 年的一篇论文「Rich feature hierarchies for accurate object detection and semantic segmentation」(R-CNN),其使用了称为 Selective Search 的算法用来提取感兴趣候选区域,并用一个标准的卷积神经网络 (CNN) 去分类和调整这些区域。Fast R-CNN 从 R-CNN 演变优化而来,Fast R-CNN 发布于 2015 年上半年,其中一种称为感兴趣区域池化的技术,使得网络能够共享计算结果,从而让模型提速。这一系列算法最终被优化为 Faster R-CNN,这是第一个彻底可微分的模型。机器学习

框架

  Faster R-CNN 的框架由几个模块部件组成,因此其框架有些复杂。咱们将从高层次的概述开始,以后会介绍不一样组成部分的具体细节。函数

  从一张图片开始,咱们将会获得:工具

    • 一个边框列表性能

    • 每一个边框会被分配一个标签

    • 每对标签和边框所对应的几率

完整的 Faster R-CNN 框架

  输入的图片以(长×宽×高)的张量形式表征,以后会被馈送入预训练好的卷积神经网络,在中间层获得特征图。使用该特征图做为特征提取器并用于下一流程。

  上述方法在迁移学习中常用,尤为在为小数据集训练分类器时,其一般取用了在另外一个较大数据集训练好的权重。咱们在下一章节会深刻了解这个部分。接着,咱们会使用到区域建议网络(Region Proposal Network,RPN)。使用 CNN 计算获得的特征,去寻找到预设好数量的可能包含目标的区域 (边框)。

  使用深度学习进行目标检测最大的困难多是生成一个长度可变的边框列表。使用深度神经网络建模时,模型最后一部分一般是一个固定尺寸的张量输出(除了循环神经网络)。例如,在图片分类中,输出是 (N,) 形状的张量,N 是类别的数量,其中在第 i 个位置标量含有该图片属于类别 i 的几率。

  RPN 中长度可变列表的问题可使用锚点解决:使用固定尺寸的参考边框在原始图片上一致地定位。不是直接探测目标在哪,而是把问题分两个方面建模,对每一个锚点,咱们考虑:

    • 这个锚点包含相关目标吗?

    • 如何调整锚点以更好的拟合到相关目标?

  可能会有点困扰,可是不要紧,下面会深刻了解。

  在取得一系列的相关目标和其在原始图片上的位置后,目标探测问题就能够相对直观地解决了。使用 CNN 提取到的特征和相关目标的边框,咱们在相关目标的特征图上使用感兴趣区域池化 (RoI Pooling),并将与目标相关的特征信息存入一个新的张量。以后的流程与 R-CNN 模型一致,利用这些信息:

    • 对边框内的内容分类(或者舍弃它,并用「背景」标记边框内容)

    • 调整边框的坐标(使之更好地包含目标)

  显然,这样作会遗失掉部分信息,但这正是 Faster-RCNN 如何进行目标探测的基本思想。下一步,咱们会仔细讨论框架、损失函数以及训练过程当中各个组件的具体细节。

基础网络

  以前提到过,Faster R-CNN 第一步要使用在图片分类任务 (例如,ImageNet) 上预训练好的卷积神经网络,使用该网络获得的中间层特征的输出。这对有深度学习背景的人来讲很简单,可是理解如何使用和为何这样作才是关键,同时,可视化中间层的特征输出也很重要。没有一致的意见代表哪一个网络框架是最好的。原始的 Faster R-CNN 使用的是在 ImageNet 上预训练的 ZF 和 VGG,但以后出现了不少不一样的网络,且不一样网络的参数数量变化很大。例如,MobileNet,以速度优先的一个小型的高效框架,大约有 330 万个参数,而 ResNet-152(152 层),曾经的 ImageNet 图片分类竞赛优胜者,大约有 6000 万个参数。最新的网络结构如 DenseNet,能够在提升准确度的同时缩减参数数量。

VGG

  在讨论网络结构孰优孰劣以前,让咱们先以 VGG-16 为例来尝试理解 Faster-RCNN 是如何工做的。

VGG 网络结构

  VGG,其名字来自于在 ImageNet ILSVRC 2014 竞赛中使用此网络的小组组名,首次发布于论文「Very Deep Convolutional Networks for Large-Scale Image Recognition」, 做者是 Karen Simonyan 和 Andrew Zisserman。以今天的标准来看这个网络谈不上深度,可是在发布之际 VGG16 比当时经常使用的网络要多一倍的层数,其推进了「深度 → 更强大性能 → 更好结果」的浪潮(只要训练是可行的)。

  当使用 VGG 进行分类任务时,其输入是 224×224×3 的张量 (表示一个 224×224 像素大小的 RGB 图片)。在分类任务中输入图片的尺寸是固定的,由于网络最后一部分的全链接层须要固定长度的输入。在接入全链接层前,一般要将最后一层卷积的输出展开成一维张量。

  由于要使用卷积网络中间层的输出,因此输入图片的尺寸再也不有限制。至少,在这个模块中再也不是问题,由于只有卷积层参与计算。让咱们深刻了解一下底层的细节,看看具体要使用哪一层卷积网络的输出。Faster R-CNN 论文中没有具体指定使用哪一层;可是在官方的实现中能够观察到,做者使用的是 conv5/conv5_1 这一层 (caffe 代码)。

  每一层卷积网络都在前一层的信息基础上提取更加抽象的特征。第一层一般学习到简单的边缘,第二层寻找目标边缘的模式,以激活后续卷积网络中更加复杂的形状。最终,咱们获得一个在空间维度上比原始图片小不少,但表征更深的卷积特征图。特征图的长和宽会随着卷积层间的池化而缩小,深度会随着卷积层滤波器的数量而增长。

从图片到卷积特征图

  卷积特征图将图片的全部信息编码到深度的维度上,同时保留着原始图片上目标物体的相对位置信息。例如,若是图片左上角有一个红色矩形,通过卷积层的激活,那么红色矩形的位置信息仍然保留在卷积特征图的左上角。

VGG vs ResNet

  现在,ResNet 已经取代大多数 VGG 网络做为提取特征的基础框架。Faster-RCNN 的三位联合做者 (Kaiming He, Shaoqing Ren 和 Jian Sun) 也是论文「Deep Residual Learning for Image Recognition」的做者,这篇论文最初介绍了 ResNets 这一框架。

  ResNet 对比 VGG 的优点在于它是一个更深层、大型的网络,所以有更大的容量去学习所须要的信息。这些结论在图片分类任务中可行,在目标探测的问题中也应该一样有效。

  ResNet 在使用残差链接和批归一化的方法后更加易于训练,这些方法在 VGG 发布的时候尚未出现。

锚点

  如今,咱们将使用处理事后的特征图并建议目标区域,也就是用于分类任务的感兴趣区域。以前提到过锚点是解决长度可变问题的一种方法,如今将详细介绍。

  咱们的目标是寻找图片中的边框。这些边框是不一样尺寸、不一样比例的矩形。设想咱们在解决问题前已知图片中有两个目标。那么首先想到的应该是训练一个网络,这个网络能够返回 8 个值:包含(xmin, ymin, xmax, ymax)的两个元组,每一个元组都用于定义一个目标的边框坐标。这个方法有着根本问题,例如,图片多是不一样尺寸和比例的,所以训练一个能够直接准确预测原始坐标的模型是很复杂的。另外一个问题是无效预测:当预测(xmin,xmax)和(ymin,ymax)时,应该强制设定 xmin 要小于 xmax,ymin 要小于 ymax。

  另外一种更加简单的方法是去预测参考边框的偏移量。使用参考边框(xcenter, ycenter, width, height),学习预测偏移量(Δxcenter,Δycenter,Δwidth,Δheight),所以咱们只获得一些小数值的预测结果并挪动参考变量就能够达到更好的拟合结果。

  锚点是用固定的边框置于不一样尺寸和比例的图片上,而且在以后目标位置的预测中用做参考边框。

  咱们在处理的卷积特征图的尺寸分别是 conv_width×conv_height×conv_depth,所以在卷积图的 conv_width×conv_height 上每个点都生成一组锚点。很重要的一点是即便咱们是在特征图上生成的锚点,这些锚点最终是要映射回原始图片的尺寸。

  由于咱们只用到了卷积和池化层,因此特征图的最终维度与原始图片是呈比例的。数学上,若是图片的尺寸是 w×h,那么特征图最终会缩小到尺寸为 w/r 和 h/r,其中 r 是次级采样率。若是咱们在特征图上每一个空间位置上都定义一个锚点,那么最终图片的锚点会相隔 r 个像素,在 VGG 中,r=16。

原始图片的锚点中心

  为了选择一组合适锚点,咱们一般定义一组固定尺寸 (例如,64px、128px、256px,此处为边框大小) 和比例 (例如,0.五、一、1.5,此处为边框长宽比) 的边框,使用这些变量的全部可能组合获得候选边框 (这个例子中有 1 个锚点和 9 个边框)。

左侧:锚点、中心:特征图空间单一锚点在原图中的表达,右侧:全部锚点在原图中的表达

区域建议网络

RPN 采用卷积特征图并在图像上生成建议

  像咱们以前提到的那样,RPN 接受全部的参考框(锚点)并为目标输出一套好的建议。它经过为每一个锚点提供两个不一样的输出来完成。

  第一个输出是锚点做为目标的几率。若是你愿意,能够叫作「目标性得分」。注意,RPN 不关心目标的类别,只在乎它其实是不是一个目标(而不是背景)。咱们将用这个目标性得分来过滤掉很差的预测,为第二阶段作准备。第二个输出是边框回归,用于调整锚点以更好的拟合其预测的目标。

  RPN 是用彻底卷积的方式高效实现的,用基础网络返回的卷积特征图做为输入。首先,咱们使用一个有 512 个通道和 3x3 卷积核大小的卷积层,而后咱们有两个使用 1x1 卷积核的并行卷积层,其通道数量取决于每一个点的锚点数量。

RPN 架构的卷积实现,其中 k 是锚点的数量

  对于分类层,咱们对每一个锚点输出两个预测值:它是背景(不是目标)的分数,和它是前景(实际的目标)的分数。

  对于回归或边框调整层,咱们输出四个预测值:Δxcenter、Δycenter、Δwidth、Δheight,咱们将会把这些值用到锚点中来获得最终的建议。

  使用最终的建议坐标和它们的目标性得分,而后能够获得一套很好的对于目标的建议。

训练、目标和损失函数

  RPN 执行两种不一样类型的预测:二进制分类边框回归调整。为了训练,咱们把全部的锚 anchor box 分红两类。一类是「前景」,它与真实目标重叠而且其 IoU(Intersection of Union)值大于 0.5;另外一类是「背景」,它不与任何真实目标重叠或与真实目标的 IoU 值 小于 0.1。

  而后,咱们对这些锚点随机采样,构成大小为 256 的 mini batch (维持前景锚点和背景锚点之间的平衡比例)。

  RPN 用全部以 mini batch 筛选出来的 anchor box 和二进制交叉熵(binary cross entropy)来计算分类损失。而后它只用那些标记为前景的 mini batch 锚点来计算回归损失。为了计算回归的目标,咱们使用前景 anchor box 和最接近的真实目标,并计算将 anchor box 转化为目标所需的正确 Δ。(由于不须要考虑其类别)

  论文中建议使用 Smooth L1 loss 来计算回归偏差,而不是用简单的 L1 或 L2 loss。Smooth L1 基本上就是 L1,可是当 L1 的偏差足够小,由肯定的 σ 定义时,能够认为偏差几乎是正确的且损失以更快的速率减少。

  使用 dynamic batches 是具备挑战性的,这里的缘由不少。即便咱们试图维持前景锚点和背景锚点之间的平衡比例,但这并不老是可能的。根据图像上的真实目标以及锚点的大小和比例,可能会获得零前景锚点。在这种状况下,咱们转而使用对于真实框具备最大 IoU 值的锚点。这远非理想状况,可是为了老是有前景样本和目标能够学习,这仍是挺实用的。

后处理

  非极大抑制(Non-maximum suppression):因为锚点常常重叠,所以建议最终也会在同一个目标上重叠。为了解决重复建议的问题,咱们使用一个简单的算法,称为非极大抑制(NMS)。NMS 获取按照分数排序的建议列表并对已排序的列表进行迭代,丢弃那些 IoU 值大于某个预约义阈值的建议,并提出一个具备更高分数的建议。

  虽然这看起来很简单,但对 IoU 的阈值设定必定要很是当心。过低,你可能会丢失对目标的建议;过高,你可能会获得对同一个目标的不少建议。经常使用值是 0.6

  建议选择:应用 NMS 后,咱们保留评分最高的 N 个建议。论文中使用 N=2000,可是将这个数字下降到 50 仍然能够获得至关好的结果。

独立应用程序

  RPN 能够独立使用,而不须要第二阶段的模型。在只有一类对象的问题中,目标性几率能够用做最终的类别几率。这是由于在这种状况下,「前景」=「目标类别」以及「背景」=「不是目标类别」。

  一些从独立使用 RPN 中受益的机器学习问题的例子包括流行的(但仍然是具备挑战性的)人脸检测和文本检测。

  仅使用 RPN 的优势之一是训练和预测的速度都有所提升。因为 RPN 是一个很是简单的仅使用卷积层的网络,因此预测时间比使用分类基础网络更快。

兴趣区域池化

  在 RPN 步骤以后,咱们有不少没有分配类别的目标建议。咱们接下来要解决的问题就是如何将这些边框分类到咱们想要的类别中。

最简单的方法是采用每一个建议,裁剪出来,而后让它经过预训练的基础网络。而后,咱们能够用提取的特征做为基础图像分类器的输入。这种方法的主要问题是运行全部 2000 个建议的计算效率和速度都是很是低的。

  Faster R-CNN 试图经过复用现有的卷积特征图来解决或至少缓解这个问题。这是经过用兴趣区域池化为每一个建议提取固定大小的特征图实现的。R-CNN 须要固定大小的特征图,以便将它们分类到固定数量的类别中。

兴趣区域池化

  一种更简单的方法(被包括 Luminoth 版本的 Faster R-CNN 在内的目标检测实现方法所普遍使用),是用每一个建议来裁剪卷积特征图,而后用插值(一般是双线性的)将每一个裁剪调整为固定大小(14×14×convdepth)。裁剪以后,用 2x2 核大小的最大池化来得到每一个建议最终的 7×7×convdepth 特征图。

  选择这些确切形状的缘由与下一模块(R-CNN)如何使用它有关,这些设定是根据第二阶段的用途获得的。

基于区域的卷积神经网络

  基于区域的卷积神经网络(R-CNN)是 Faster R-CNN 工做流的最后一步。从图像上得到卷积特征图以后,用它经过 RPN 来得到目标建议并最终为每一个建议提取特征(经过 RoI Pooling),最后咱们须要使用这些特征进行分类。R-CNN 试图模仿分类 CNNs 的最后阶段,在这个阶段用一个全链接层为每一个可能的目标类输出一个分数。

  R-CNN 有两个不一样的目标:

    1. 将建议分到一个类中,加上一个背景类(用于删除很差的建议)。

    2. 根据预测的类别更好地调整建议的边框。

  在最初的 Faster R-CNN 论文中,R-CNN 对每一个建议采用特征图,将它平坦化并使用两个大小为 4096 的有 ReLU 激活函数的全链接层。

  而后,它对每一个不一样的目标使用两种不一样的全链接层:

    • 一个有 N+1 个单元的全链接层,其中 N 是类的总数,另一个是背景类。

    • 一个有 4N 个单元的全链接层。咱们但愿有一个回归预测,所以对 N 个类别中的每个可能的类别,咱们都须要 Δcenterx、Δcentery、Δwidth、Δheight。

R-CNN 架构

训练和目标

  R-CNN 的目标与 RPN 的目标的计算方法几乎相同,可是考虑的是不一样的可能类别。咱们采用建议和真实边框,并计算它们之间的 IoU。

  那些有任何真实边框的建议,只要其 IoU 大于 0.5,都被分配给那个真实数据。那些 IoU 在 0.1 和 0.5 之间的被标记为背景。与咱们在为 RPN 分配目标时相反的是,咱们忽略了没有任何交集的建议。这是由于在这个阶段,咱们假设已经有好的建议而且咱们对解决更困难的状况更有兴趣。固然,这些全部的值都是能够为了更好的拟合你想找的目标类型而作调整的超参数。

  边框回归的目标是计算建议和与其对应的真实框之间的偏移量,仅针对那些基于 IoU 阈值分配了类别的建议。

  咱们随机抽样了一个尺寸为 64 的 balanced mini batch,其中咱们有高达 25% 的前景建议(有类别)和 75% 的背景。

  按照咱们对 RPN 损失所作的相同处理方式,如今的分类损失是一个多类别的交叉熵损失,使用全部选定的建议和用于与真实框匹配的 25% 建议的 Smooth L1 loss。因为 R-CNN 边框回归的全链接网络的输出对于每一个类都有一个预测,因此当咱们获得这种损失时必须当心。在计算损失时,咱们只须要考虑正确的类。

后处理

  与 RPN 类似,咱们最终获得了不少已经分配了类别的目标,在返回它们以前须要进一步处理。

  为了实施边框调整,咱们必须考虑哪一个类别具备对该建议的最高几率。咱们也须要忽略具备最高几率的背景类的建议。

  在获得最终目标和忽略被预测为背景的目标以后,咱们应用基于类的 NMS。这经过按类进行分组完成,经过几率对其排序,而后将 NMS 应用于每一个独立的组。

  对于咱们最后的目标列表,咱们也能够设置一个几率阈值而且对每一个类限制目标的数量。

训练

  在最初的论文中,Faster R-CNN 是用多步法训练的,独立地训练各部分而且在应用最终的全面训练方法以前合并训练的权重。以后,人们发现进行端到端的联合训练会带来更好的结果。

  把完整的模型放在一块儿后,咱们获得 4 个不一样的损失,两个用于 RPN,另外两个用于 R-CNN。咱们在 RPN 和 R-CNN 中有可训练的层,咱们也有能够训练(微调)或不能训练的基础网络。

  是否训练基础网络的决定取决于咱们想要学习的目标特性和可用的计算能力。若是咱们想检测与在原始数据集(用于训练基础网络)上的数据类似的目标,那么除了尝试压缩咱们能得到的全部可能的性能外,其余作法都是没有必要的。另外一方面,为了拟合完整的梯度,训练基础网络在时间和必要的硬件上都是昂贵的。

  用加权和将四种不一样的损失组合起来。这是由于相对于回归损失,咱们可能但愿给分类损失更大的权重,或者相比于 RPN 可能给 R-CNN 损失更大的权重。

  除了常规的损失以外,咱们也有正则化损失,为了简洁起见,咱们能够跳过这部分,可是它们在 RPN 和 R-CNN 中均可以定义。咱们用 L2 正则化一些层。根据正在使用哪一个基础网络,以及若是它通过训练,也有可能进行正则化。

  咱们用随机梯度降低的动量算法训练,将动量值设置为 0.9。你能够轻松的用其余任何优化方法训练 Faster R-CNN,而不会遇到任何大问题。

  学习率从 0.001 开始,而后在 50K 步后降低到 0.0001。这是一般最重要的超参数之一。当用 Luminoth 训练时,咱们常常从默认值开始,并以此开始作调整。

评估

  在一些特定的 IoU 阈值下,使用标准平均精度均值(mAP)来完成评估(例如,mAP@0.5)。mAP 是源于信息检索的度量标准,而且经常使用于计算排序问题中的偏差和评估目标检测问题。

  咱们不会深刻讨论细节,由于这些类型的度量标准值得用一篇完整博客来总结,但重要的是,当你错过了你应该检测到的框,以及当你发现一些不存在的东西或屡次检测到相同的东西时,mAP 会对此进行惩罚。

结论

  到目前为止,你应该清楚 Faster R-CNN 的工做方式、设计目的以及如何针对特定的状况进行调整。若是你想更深刻的了解它的工做原理,你应该看看 Luminoth 的实现。

  Faster R-CNN 是被证实能够用相同的原理解决复杂的计算机视觉问题的模型之一,在这个新的深度学习革命刚开始的时候,它就展示出如此惊人的结果。

  目前正在创建的新模型不只用于目标检测,还用于基于这种原始模型的语义分割、3D 目标检测等等。有的借用 RPN,有的借用 R-CNN,还有的创建在二者之上。所以,充分了解底层架构很是重要,从而能够解决更加普遍的和复杂的问题。

 


 

原文地址: https://tryolabs.com/blog/2018/01/18/faster-r-cnn-down-the-rabbit-hole-of-modern-object-detection/

相关文章
相关标签/搜索