基于候选区域的目标检测器(二阶检测和一阶检测)

转自:基于候选区域的目标检测器(两阶段)和单次目标检测器(一阶段)


https://www.cnblogs.com/cloud-ken/p/9470992.html

https://www.cnblogs.com/cloud-ken/tag/DeeplearningAI/default.html?page=3

https://www.cnblogs.com/guoyaohua/p/8994246.html

https://blog.csdn.net/jiongnima/article/details/79094159 (这个非常好,对比看看)
( 联合RPN和Fast R-CNN的训练。没看懂。)

一、基于候选区域的目标检测器(两阶段)

    主要是RCNN系列。

1.1  滑动窗口检测器

基于候选区域的目标检测器(二阶检测和一阶检测)

 

伪代码。我们创建很多窗口来检测不同位置的不同目标。要提升性能,一个显而易见的办法就是减少窗口数量。

 
  1. for window in windows

  2. patch = get_patch(image, window)

  3.   results = detector(patch)

1.2  选择性搜索(SS)

  我们不使用暴力方法,而是用候选区域方法(region proposal method)创建目标检测的感兴趣区域(ROI)。在选择性搜索(selective search,SS)中,我们首先将每个像素作为一组,计算每一组的纹理,并将两个最接近的组结合起来。但是为了避免单个区域吞噬其他区域,我们首先对较小的组进行分组。我们继续合并区域,直到所有区域都结合在一起。下图第一行展示了如何使区域增长,第二行中的蓝色矩形代表合并过程中所有可能的 ROI

1.3  R-CNN

基于候选区域的目标检测器(二阶检测和一阶检测)

通过使用更少且更高质量的 ROI,R-CNN 要比滑动窗口方法更快速、更准确。

如果我们有 2000 个候选区域,且每一个都需要独立地馈送到 CNN 中,那么对于不同的 ROI,我们需要重复提取 2000 次特征。(R-CNN很多卷积运算是重复的

 
  1. ROIs = region_proposal(image)

  2. for ROI in ROIs:

  3. patch = get_patch(image, ROI)

  4. results = detector(pach)

  • 边界框回归器(refinement)

  候选区域方法有非常高的计算复杂度。为了加速这个过程,我们通常会使用计算量较少的候选区域选择方法构建 ROI,并在后面使用线性回归器(使用全连接层)进一步提炼边界框。

1.4  Fast R-CNN

CNN 中的特征图以一种密集的方式表征空间特征,那么我们能直接使用特征图代替原图来检测目标吗?(能)

 Fast R-CNN 使用特征提取器(CNN)先提取整个图像的特征,而不是从头开始对每个图像块提取多次。然后,我们可以将创建候选区域的方法直接应用到提取到的特征图上。例如,Fast R-CNN 选择了 VGG16 中的卷积层 conv5 输出的 Feture Map 来生成 ROI,这些关注区域随后会结合对应的特征图以裁剪为特征图块,并用于目标检测任务中。我们使用 ROI 池化将特征图块转换为固定的大小,并馈送到全连接层进行分类和定位。因为 Fast-RCNN 不会重复提取特征,因此它能显著地减少处理时间。

基于候选区域的目标检测器(二阶检测和一阶检测)

基于候选区域的目标检测器(二阶检测和一阶检测)

将候选区域直接应用于特征图,并使用 ROI 池化将其转化为固定大小的特征图块(将 ROI(蓝色区域)与特征图重叠。

基于候选区域的目标检测器(二阶检测和一阶检测)

在下面的伪代码中,计算量巨大的特征提取过程从 For 循环中移出来了,因此速度得到显著提升。Fast R-CNN 的训练速度是 R-CNN 的 10 倍,推断速度是后者的 150 倍。

 
  1. feature_maps = process(image)

  2. ROIs = region_proposal(feature_maps)

  3. for ROI in ROIs:

  4. patch = roi_pooling(feature_maps, ROI)

  5. results = detector2(patch)

  Fast R-CNN 最重要的一点就是包含特征提取器、分类器和边界框回归器在内的整个网络能通过多任务损失函数进行端到端的训练,这种多任务损失即结合了分类损失和定位损失的方法,大大提升了模型准确度。

  • ROI 池化(????)

  因为 Fast R-CNN 使用全连接层,所以我们应用 ROI 池化将不同大小的 ROI 转换为固定大小。

1.5  Faster R-CNN

          Faster R-CNN 采用与 Fast R-CNN 相同的设计,只是它用内部深层网络代替了候选区域方法两个卷积网络,分布用于提取特征和生成ROIs(是否有目标,其位置及目标得分(不是类别得分))。新的候选区域网络(RPN)在生成 ROI 时效率更高,并且以每幅图像 10 毫秒的速度运行。

基于候选区域的目标检测器(二阶检测和一阶检测)

Faster R-CNN 的流程图与 Fast R-CNN 相同

基于候选区域的目标检测器(二阶检测和一阶检测)

 
  1. feature_maps = process(image)

  2. ROIs = region_proposal(feature_maps)

  3. for ROI in ROIs

  4. patch = roi_pooling(feature_maps, ROI)

  5. class_scores, box = detector(patch) # Expensive!

  6. class_probabilities = softmax(class_scores)

  • 候选区域网络(RPN)

  候选区域网络(RPN)第一个卷积网络的输出特征图作为输入。它在特征图上滑动一个 3×3 的卷积核,以使用卷积网络构建与类别无关的候选区域。如ZF 网络最后会输出 256 个值,它们将馈送到两个独立的全连接层,以预测边界框和两个 objectness 分数(边界框是否包含目标)。我们其实可以使用回归器计算单个 objectness 分数,但为简洁起见,Faster R-CNN 使用只有两个类别的分类器:即带有目标的类别不带有目标的类别

基于候选区域的目标检测器(二阶检测和一阶检测)

Faster R-CNN 不会创建随机边界框。相反,它会预测一些与左上角名为「锚点」(这是由经验固定比例的,yolo是聚类得到固定大小的)的参考框相关的偏移量(如x、y):

基于候选区域的目标检测器(二阶检测和一阶检测)基于候选区域的目标检测器(二阶检测和一阶检测)基于候选区域的目标检测器(二阶检测和一阶检测)

首先第一个问题是为什么需要RoI Pooling?答案是在Fast R-CNN中,特征被共享卷积层一次性提取。因此,对于每个RoI而言,需要从共享卷积层上摘取对应的特征,并且送入全连接层进行分类。因此,RoI Pooling主要做了两件事,第一件是为每个RoI选取对应的特征,第二件事是为了满足全连接层的输入需求,将每个RoI对应的特征的维度转化成某个定值(对于每一个RoI,RoI Pooling Layer将其对应的特征从共享卷积层上拿出来,并转化成一样的大小(6×6),类似对应roi坐标位置的分割?)。RoI Pooling示意图如

基于候选区域的目标检测器(二阶检测和一阶检测)

1.6  基于区域的全卷积神经网络(R-FCN)(没接触过,多看看)

R-FCN 通过减少每个 ROI 所需的工作量实现加速(去掉了全连接层)。上面基于区域的特征图与 ROI 是独立的,可以在每个 ROI 之外单独计算。剩下的工作就比较简单了,因此 R-FCN 的速度比 Faster R-CNN 快。

假设我们只有一个特征图用来检测右眼。那么我们可以使用它定位人脸吗?应该可以。因为右眼应该在人脸图像的左上角,所以我们可以利用这一点定位整个人脸。如果我们还有其他用来检测左眼、鼻子或嘴巴的特征图,那么我们可以将检测结果结合起来,更好地定位人脸。

基于候选区域的目标检测器(二阶检测和一阶检测)

 

 
  1. feature_maps = process(image)

  2. ROIs = region_proposal(feature_maps)

  3. score_maps = compute_score_map(feature_maps)

  4. for ROI in ROIs

  5. V = region_roi_pool(score_maps, ROI)

  6. class_scores, box = average(V) # Much simpler!

  7. class_probabilities = softmax(class_scores)

基于候选区域的目标检测器(二阶检测和一阶检测)

      (假设k=3)现在我们来看一下 5 × 5 的特征图 M,内部包含一个蓝色方块。我们将方块平均分成 3 × 3 个区域。现在,我们在 M 中创建了一个新的特征图,来检测方块的左上角(TL)。这个新的特征图如下图(右)所示。只有黄色的网格单元 [2, 2] 处于**状态。

基于候选区域的目标检测器(二阶检测和一阶检测)

在左侧创建一个新的特征图,用于检测目标的左上角

  我们将方块分成 9 个部分,由此创建了 9 个特征图,每个用来检测对应的目标区域。这些特征图叫作位置敏感得分图(position-sensitive score map),因为每个图检测目标的子区域(计算其得分)。

基于候选区域的目标检测器(二阶检测和一阶检测)

生成 9 个得分图

  下图中红色虚线矩形是建议的 ROI。我们将其分割成 3 × 3 个区域,并询问每个区域包含目标对应部分的概率是多少。例如,左上角 ROI 区域包含左眼的概率。我们将结果存储成 3 × 3 vote 数组,如下图(右)所示。例如,vote_array[0][0] 包含左上角区域是否包含目标对应部分的得分。

基于候选区域的目标检测器(二阶检测和一阶检测)

将 ROI 应用到特征图上,输出一个 3 x 3 数组

  将得分图(Feature Map)和 ROI 映射到 vote 数组的过程叫作位置敏感 ROI 池化(position-sensitive ROI-pool)。该过程与前面讨论过的 ROI 池化非常接近。

基于候选区域的目标检测器(二阶检测和一阶检测)

将 ROI 的一部分叠加到对应的得分图上,计算 V[i][j]

  在计算出位置敏感 ROI 池化的所有值后,类别得分是其所有元素得分的平均值。

基于候选区域的目标检测器(二阶检测和一阶检测)

ROI 池化

  假如我们有 C 个类别要检测。我们将其扩展为 C + 1 个类别,这样就为背景(非目标)增加了一个新的类别。每个类别有 3 × 3 个得分图,因此一共有 (C+1) × 3 × 3 个得分图。使用每个类别的得分图可以预测出该类别的类别得分。然后我们对这些得分应用 softmax 函数,计算出每个类别的概率。

二、单次目标检测器

  单次目标检测器(SSD、YOLO、YOLOv2、YOLOv3)。1)分析FPN多尺度特征图如何提高准确率,特别是小目标的检测,其在单次检测器中的检测效果通常很差。2)分析 Focal loss 和 RetinaNet,是如何解决训练过程中的类别不平衡问题的。

      单次检测器通常需要在准确率和实时处理速度之间进行权衡。它们在检测太近距离或太小的目标时容易出现问题

      作为替代,我们是否需要一个像RCNN系列 分离的候选区域步骤?我们可以直接在一个步骤内得到边界框和类别吗?

 
  1. feature_maps = process(image)

  2. ROIs = region_proposal(feature_maps)

  3. for ROI in ROIs

  4. patch = roi_align(feature_maps, ROI)

  5. results = detector2(patch) # Reduce the amount of work here!

  转化为:

 
  1. feature_maps = process(image)

  2. results = detector3(feature_maps) # No more separate step for ROIs

           让我们再看一下滑动窗口检测器。我们可以通过在特征图上滑动窗口来检测目标。对于不同的目标类型,我们使用不同的窗口类型。以前的滑动窗口方法的致命错误在于使用窗口作为最终的边界框,这就需要非常多的形状来覆盖大部分目标。更有效的方法是将窗口当做初始猜想,这样我们就得到了从当前滑动窗口同时预测类别和边界框的检测器。

基于候选区域的目标检测器(二阶检测和一阶检测)

基于滑动窗口进行预测

 

特征图每个位置,我们有 k 个anchors(锚(先验框)是固定的初始边界框猜想),一个先验框对应一个特定位置(锚点)。我们使用相同的先验框形状仔细地选择锚点和每个位置。

  以下是一个锚点的 4 个先验框(绿色)和 4 个对应预测(蓝色),每个预测对应一个特定先验框。(YOLOv3每个尺度特征图的每个锚点3个先验框,3个尺度,应用到这里就是一个锚点有3*3个预测框)

基于候选区域的目标检测器(二阶检测和一阶检测)

4 个预测,每个预测对应一个先验框

基于候选区域的目标检测器(二阶检测和一阶检测)

2.2  SSD (Single Shot MultiBox Detector)

  SSD 是使用 VGG19 网络作为特征提取器(和 Faster R-CNN 中使用的 CNN 一样)的单次检测器。我们在该网络之后添加自定义卷积层(蓝色),并使用卷积核(绿色)执行预测。

基于候选区域的目标检测器(二阶检测和一阶检测)

同时对类别和位置执行单次预测

  然而,卷积层降低了空间维度和分辨率。因此上述模型仅可以检测较大的目标为了解决该问题,我们从多个特征图上执行独立的目标检测。采用多尺度特征图独立检测。

基于候选区域的目标检测器(二阶检测和一阶检测)

使用多尺度特征图用于检测

  以下是特征图图示。

基于候选区域的目标检测器(二阶检测和一阶检测)

  SSD 使用卷积网络中较深的层来检测目标。如果我们按接近真实的比例重绘上图,我们会发现图像的空间分辨率已经被显著降低,且可能已无法定位在低分辨率中难以检测的小目标。如果出现了这样的问题,我们需要增加输入图像的分辨率。

基于候选区域的目标检测器(二阶检测和一阶检测)

2.3  YOLO系列

      YOLO  在卷积层之后使用了 DarkNet 来做特征检测。

基于候选区域的目标检测器(二阶检测和一阶检测)

  然而,它并没有使用多尺度特征图来做独立的检测。相反,它将特征图部分平滑化,并将其和另一个较低分辨率的特征图拼接。例如,YOLO 将一个 28 × 28 × 512 的层重塑为 14 × 14 × 2048,然后将它和 14 × 14 ×1024 的特征图拼接。之后,YOLO 在新的 14 × 14 × 3072 层上应用卷积核进行预测。

    YOLOv2(YOLO9000)做出了很多实现上的改进, 可以检测 9000 种不同类别的目标。

    YOLOv3 使用了更加复杂的骨干网络来提取特征。DarkNet-53 主要由 3 × 3 和 1× 1 的卷积核以及类似 ResNet 中的跳过连接构成。相比 ResNet-152,DarkNet 有更低的 BFLOP(十亿次浮点数运算),但能以 2 倍的速度得到相同的分类准确率。YOLOv3 还添加了特征金字塔,以更好地检测小目标。

    FPN 提供了一条自上而下的路径,从语义丰富的层构建高分辨率的层。

基于候选区域的目标检测器(二阶检测和一阶检测)

自上而下重建空间分辨率

  虽然该重建层的语义较强,但在经过所有的上采样和下采样之后,目标的位置不精确。在重建层和相应的特征图之间添加横向连接可以使位置侦测更加准确。

基于候选区域的目标检测器(二阶检测和一阶检测)

增加跳过连接

 

FPN 结合 Fast R-CNN 或 Faster R-CNN

  在 FPN 中,我们生成了一个特征图的金字塔。用 RPN(详见上文)来生成 ROI。基于 ROI 的大小,我们选择最合适尺寸的特征图层来提取特征块。

基于候选区域的目标检测器(二阶检测和一阶检测)