学习笔记:暂存两篇比较好的文章

感谢这位作者,以下记录是来自于https://www.cnblogs.com/guoyaohua/p/8940871.html的,我看到比较好,就转记录到自己的博客了,如果有侵权,立马删掉

文章一:

SCNN车道线检测--(SCNN)Spatial As Deep: Spatial CNN for Traffic Scene Understanding(论文解读)

Spatial As Deep: Spatial CNN for Traffic Scene Understanding

收录:AAAI2018 (AAAI Conference on Artificial Intelligence)

原文地址:SCNN

论文提出了一个新颖网络Spatial CNN,在图片的行和列上做信息传递。可以有效的识别强先验结构的目标。论文提出了一个大型的车道检测数据集,用于进一步推动自动驾驶发展。

代码:


Abstract

  现今的CNN模型通常是由卷积块堆叠构建,虽然CNN有强大的特征提取能力,但现存CNN架构没有足够充分探索图像行和列上的空间关系能力。这些关系对于学习强先验形状的对象很重要,尤其是外观(图像像素)连贯性很弱。例如交通线,车道经常会被遮挡,或者压根就没在路上画车道线。如下图所示:

  本文提出了Spatial CNN(CNN),它将传统的卷积层接层(layer-by-layer)的连接形式的转为feature map中片连片卷积(slice-by-slice)的形式,使得图中像素行和列之间能够传递信息。这特别适用于检测长距离连续形状的目标或大型目标,有着极强的空间关系但是外观线索较差的目标,例如交通线,电线杆和墙。论文在车道检测挑战和CityScapes上评估了SCNN的表现,同时SCNN在TuSimple Benchmark lane Detection challenge获得了第一名,准确率为96.53%。


Introduction

  自动驾驶中最具挑战的任务之一是交通场景理解,包括计算机视觉任务下的车道检测和语义分割。车道检测帮助指导车辆,语义分割提供更多关于周围环境目标的细节位置。但在实际情况下,因为有许多恶劣条件,这些任务可能非常具有挑战性。对于交通场景理解的另一个挑战是,在许多情况下需要在有强结构先验知识下处理外形线索不多的目标,例如交通线,杆状物等,这些具有长距离连续的形状,常常有很大部分被遮挡。

  得益于强大的学习表示能力,CNN将视觉理解推向了一个新的高度。但是这依然不能很好地处理外形线索不多的有强结构先验的目标,而人类可以推断它们的位置并填充遮挡的部分。

  为了解决这个问题,论文提出了SCNN,将深度卷积神经网络推广到丰富空间层次。

  传统的CNN,任意层接收上层的数据作输入,再作卷积并加激活传给下一层,这个过程是顺序执行的。与之类似的是,SCNN将feature map的行或列也看成layer,也使用卷积加非线性激活,从而实现空间上的深度神经网络。这使得空间信息能够在同层的神经元上传播,增强空间信息进而对于识别结构化对象特别有效。

相关工作:

  对于车道检测任务,大多数现有的算法都是依赖于低级手工特征,这让模型难以在恶劣条件下工作。2015年有工作尝试使用深度学习方案用于车道检测,但苦于没有大的广泛的数据集(说这个的原因是论文建立了一个大的数据集~)。对于语义分割,基于CNN的方案的已经成为主流并取得了巨大的成功。

  对于在深度神经网络中使用空间信息:有工作使用RNN按每列和行传递信息,但每个像素只能接收同一行或列的信息。也有工作使用LSTM变体探索语义分割的上下文信息,但计算消耗较大。也有工作尝试结合CNN和图模型(例如MRF或CRF),通过大卷积核传递信息。

与上述方案相比,SCNN有如下几个优势:

  • 消息传递比传统的MRF/CRF更有计算效率
  • 消息传递使用的是残差,这更易训练
  • SCNN很灵活,适用于多种深度神经网络

Spatial Convolutional Neural Network

Lane Detection Dataset

  本文提出了一个关于交通车道检测的大规模数据集。以前的车道检测数据集(KITTI,CamVid)要不就是太简单,要不就是数据太小。最近的(Caltech,TuSimple)数据集是在交通受限状态下建立的,这样的数据车流量少且路标较为清晰。这些数据集没有包括一些车道线模糊,条件恶劣的情况,而这些情况人类可以推断出来,且这具有很高的实用价值。

  论文提出的数据集是由六辆车在北京不同时间录制的,超过55个小时共收集了133,235 张图片,这超过TuSimple 数据集20倍了。论文分成88880张作为训练集, 9675作为验证集,34680做测试集。图像的大小为1640×590。下图是示例和简介:

  数据集内包括城市、农村和高速公路等场景,北京作为世界上最大和最拥挤的城市之一,对应的车道检测数据提供了很多具有挑战性的交通场景。论文将测试集分为正常和8个具有挑战性的类别,这对应上图 (a)的9个示例情况。图(b)显示的是挑战性的场景站数据集的比例(共72.3%)。

  对于每一张图片,使用三条线注释车道,如前面所述,许多情况下车道是被遮挡的或看不见的。而这在实际情况下是很重要的,车道检测算法需要能够在这种情况下工作。对此,标注工作根据上下文也做了标注,如图(2)(4)所示。对于图(1)的情况我们不对障碍的另一边做标注,将精力集中于最受关注的部分。

Spatial CNN

  传统的关于空间关系的建模方法是基于概率图模型的,例如马尔科夫随机场(MRF)或条件随机场(CRF)。最近有工作将概率图与CNN相结合,如图 3(a)所示:

CRF可化为平均场,算法可以用神经网络来实现,具体来说,过程分为:

  • 标准化:CNN的输出作为一元势函数,并通过Softmax操作标准化
  • 信息传递:可通过大内核的逐通道卷积实现(对于DenseCRF,内核大小将覆盖整张图片,内核权重取决于图片)
  • 兼容性转换:使用1×1的卷积实现
  • 添加一元势:整个过程迭代N次得到最终输出

  可以看到传统方法在传递信息时,每个像素点接受来自全图其他像素的信息,这在计算上是非常昂贵的,难以应用于实时系统。且对于MRF的大卷积核权重很难学。这些方法是应用在CNN的输出上的,论文认为CNN的隐藏层,包含了丰富的空间关系,可更好的用于处理空间关系。

  论文提出了Spatial CNN,这里的Spatial不是指Spatial Convolution,而是CNN通过特征的设计架构传递空间信息。SCNN更有效的学习空间关系,能平滑的找出连续的有强先验的结构目标。SCNN的整体架构如下:

(图中SCNN的下标有D,U,R,L,这在结构上是类似的,方向上分别表示为向下,向上,向右,向左)

先以SCNN_D分析:

  考虑到SCNN应用在三维张量C×H×W上,C,H,W分别代表通道数,长和宽。为了实现空间信息传递,将张量切分成H片(slice),先将第一片送到尺寸为C×w的卷积层(w为卷积核的宽度)。传统的CNN是将这层的输出传递给下一层,而这里是将这片输出相加到下一片作为新的一片。接着下一片继续应用卷积(这里卷积核共享),直到处理完所有片。

  具体来讲,假设我们有一个三维的张量K,其中Ki,j,k记为最后一片中通道i的元素和当前片中通道j的元素之间的权重,这两个元素之间偏移为k列。同样的将Xi,j,k记录为张量X的元素,其中i,j,k分别指代通道,行,列. 
  则SCNN的前向计算为: 

  其中f是非线性激活函数ReLUX′表示更新后的值,注意所有的片享一组卷积核,SCNN是一种RNN。

Analysis

SCNN相比于传统方法,有三个优势:

计算效率

  SCNN与传统的Dense MRF/CRF相比,在信息传递方向不同,示意图如下所示:

  • 图(a):MRF/CRF中每个像素点会直接接收其他所有像素点的信息(大卷积核实现),这其中有许多冗余计算。
  • 图(b):在SCNN中,信息是顺序传递的。

  假设张量有H行W列,对于密集的MRF/CRF来讲,在每两个HW像素之间都存在信息传递,对于niter次迭代,传递了niterW2H2次信息。在SCNN中,每个像素只接受来自w个像素的信息,共传递了nderWH次,其中der指代传递信息的方向的数量w为卷积核宽度。

niter范围在10到100之间,在本文中ndir设置为4,对应着四个方向。w设置通常不超过10(图中设置为3)。对于一张有上千行和列的图片来说,SCNN可大幅度减少计算量,而每个像素点依旧能够接收来所有其他像素传递的信息(4个方向的信息传递)。

将传递信息作残差

  密集的MRF/CRF内是通过所有加权像素相加,这样的计算花费很大。而RNN是通过梯度来优化的, 考虑到这么多层和列,依据残差网络的经验,论文也采用残差的方式来学习(计算公式描述的残差学习)。这种残差可认为是对原始神经元的修正。实验证明这样的消息传递比基于LSTM的要好。

灵活性

  归功于SCNN的计算效率,它可以很方便的集成到CNN的任何部分。通常 top hidden layer 包含了丰富的语义信息,这是应用SCNN的理想位置。在完整的SCNN模型中我们在顶层的 feature map上用了四个方向的SCNN引入空间信息传递。


Experiment

  论文在自发布的lane detection dataset 和 CityScapes数据集做了评估。 
  采用标准的SGD训练器,学习率采用”poly”策略,初始学习率为0.01,power为0.9。batchsize设置为12,动量为0.9,权重衰减为0.0001。迭代次数为60K。模型架构在LargeFOV(DeepLabv2)基础上修改,初始的13层采用的是在ImageNet上预训练的VGG16层。所有的实验使用的工作是Torch7.

Lane Detection

  普通的目标识别只要划分边界,而车道检测需要精准的预测曲线,一个自然的想法是模型输出曲线的概率图,以像素级目标来训练网络,这类似于语义分割任务。我们希望网络能够直接区分不同车道标记,这样鲁棒性更好。共有4中类型的车道线。输出的概率图经过一个小网络预测车道标记是否存在。

  在测试期间,同样需要从概率图转为曲线,模型大致示意如下图(b)所示:

  对于存在值大于0.5的车道标记,在对应的概率图每20行搜索以获得最高的响应位置,然后通过三次样条函数连接这些点(cubic splines)。这就是最终的预测。

上图(a)显示了baseline和LargeFOV之间的差异:

  • fc7输出通道为128
  • fc6扩张卷积的扩张率为4
  • 每个ReLU层前加了BN层
  • 添加了一个小型网络用于预测是否存在车道线

 训练时,输入和输出的图片分辨率设置为800×288(约为原图的二分之一)。目标线的宽度设置为16.考虑背景和车道标记之间的不平衡标签,背景损失乘以0.4。

评估

  为了判断车道标记是否正确的检测到,论文将车道标记视为宽度为30像素的线,计算ground truth和预测值之间的IoU.如果预测的IoU大于某个阈值,则认为是true positives (TP). 如下图6所示,这里设置了0.3和0.5作为阈值,分别对应松散和严格的评估。

然后使用

Fmeasur

最为最终评价指标,其中Precision=TPTP+FPRecall=TPTP+FN。设置β=1表示调和平均值。

Ablation Study

Effectiveness of multidirectional SCNN

首先探究了SCNN里信息传递方向的有效性。对比实验如下表:

  SCNN的核宽度w=5,可以看到随着方向的增加,性能也逐渐增加。 为了证明性能是来源于多方向,而不是参数的增加,在baseline的基础上添加了一个额外的5×5的卷积层,可以看到性能只有微弱的提升。

Effects of kernel width w

  论文在SCNN_DURL的基础上测试了不同核宽度对性能的影响,核宽度表示像素可以接收其他像素的信息数量,结果如下:

  可以看到较大的w表现出的性能较好(计算量也一直上升)

Spatial CNN on different positions

  SCNN可以添加到模型的任何地方,在图3中,将SCNN_DURL应用于output上或top hidden layer:

  可以看到放置在top hidden layer后效果要出色,这是因为top hidden layer包含更丰富的信息。

Effectiveness of sequential propagation

  在SCNN中,信息时连续方式传递的,SCNN的一片不会传递信息给下一片,知道它接收到别的片传来的信息。与此做对比的时,使用平行策略(parallel),即每个片在更新前将信息传递给一下片,一起更新,结果如下:

  可以看到顺序传递的优势较大,这表明在SCNN中,像素不仅受到邻近像素的影响,也受到更远距离的像素影响。

Comparison with state-of-the-art methods

论文将SCNN与几个先进模型对比结果如下:

  • 基于LSTM的Renet:使用两个ReNet层替换Figure 3中SCNN层
  • DenseCRF:采用了10个平均场迭代
  • MRFNet:使用Figure 3(a),迭代10次,内核大小为20
  • ResNet:基于与DeepLabv2相同,除了不使用ASPP模块

可以看到SCNN的效果很出色~

可视化结果如下:

  可以看到SCNN要比大型的ResNet101要好,虽然ResNet101参数多,但是在这种具有挑战性的情况下会产生杂乱或不连续的输出,SCNN相比能够保持平滑性。这表明SCNN相比于传统CNN能够更好的捕捉强先验结构的目标。

Computational efficiency over other methods

同时论文给出了与其他模型时间效率上的对比。注意计算时间没有包括网络主干。都是在CPU上跑的。

可以看到SCNN比CRF要快很多,这是因为传递信息策略的改变。

Semantic Segmentation on CityScapes

论文同时也在CityScapes上做了测试,使用DeepLabv2的LargeFOV和ResNet101作为baseline,在LargeFOV上添加BN层,对于两个模型,top hidden layer的通道数改为128.

配置SCNN的是SCNN_DURL在w=9w=9,结果如下:

可以看到配置了SCNN的模型,在墙、杆等类别有着显著的提升,这是因为SCNN能够捕捉这些长距离连续物体。

可视化结果如下:

有一个有意思的地方,汽车的底部在训练期间是不做标记的,在LargeFOV上是缺失的,因为SCNN的信息传递,被分类成道路。

论文也将SCNN方法与其他方法做了对比,也使用了VGG16为网络主干,结果如下:

可以看到SCNN效果还是可以的


Conclusion

  论文提出了Spatial CNN,在空间层上实现信息的有效传递。SCNN易于融入到其他深度神经网络中做end-2-end训练。论文在车道检测和语义分割上测试了SCNN,结果表现SCNN可以有效的保持长距离连续结构,在语义分割其扩散效应对识别大型物体有利。

  此外,论文提出了一个车道检测的数据集,希望能够推动自动驾驶进一步发展。


文章二:

【深度学习】目标检测算法总结(R-CNN、Fast R-CNN、Faster R-CNN、FPN、YOLO、SSD、RetinaNet)

目标检测是很多计算机视觉任务的基础,不论我们需要实现图像与文字的交互还是需要识别精细类别,它都提供了可靠的信息。本文对目标检测进行了整体回顾,第一部分从RCNN开始介绍基于候选区域的目标检测器,包括Fast R-CNN、Faster R-CNN 和 FPN等。第二部分则重点讨论了包括YOLO、SSD和RetinaNet等在内的单次检测器,它们都是目前最为优秀的方法。

一、基于候选区域的目标检测器

1.1  滑动窗口检测器

  自从 AlexNet 获得 ILSVRC 2012 挑战赛冠军后,用 CNN 进行分类成为主流。一种用于目标检测的暴力方法是从左到右、从上到下滑动窗口,利用分类识别目标。为了在不同观察距离处检测不同的目标类型,我们使用不同大小和宽高比的窗口。

滑动窗口(从右到左,从上到下)

  我们根据滑动窗口从图像中剪切图像块。由于很多分类器只取固定大小的图像,因此这些图像块是经过变形转换的。但是,这不影响分类准确率,因为分类器可以处理变形后的图像。

将图像变形转换成固定大小的图像

  变形图像块被输入 CNN 分类器中,提取出 4096 个特征。之后,我们使用 SVM 分类器识别类别和该边界框的另一个线性回归器

滑动窗口检测器的系统工作流程图

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

for window in windows 
    patch = get_patch(image, window) 
  results = detector(patch)

1.2  选择性搜索

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

图源:van de Sande et al. ICCV'11

1.3  R-CNN

  R-CNN 利用候选区域方法创建了约 2000 个 ROI。这些区域被转换为固定大小的图像,并分别馈送到卷积神经网络中(将原始图像根据ROI切割、reshape再送进NN学习)。该网络架构后面会跟几个全连接层,以实现目标分类并提炼边界框。

  使用候选区域、CNN、仿射层来定位目标。以下是 R-CNN 整个系统的流程图:

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

ROIs = region_proposal(image)
for ROI in ROIs:
    patch = get_patch(image, ROI) 
    results = detector(pach)
  • 边界框回归器

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

从RCNN到SSD,这应该是最全的一份目标检测算法盘点

使用回归方法将蓝色的原始边界框提炼为红色的

1.4  Fast R-CNN

  R-CNN 需要非常多的候选区域以提升准确度,但其实有很多区域是彼此重叠的,因此 R-CNN 的训练和推断速度非常慢。如果我们有 2000 个候选区域,且每一个都需要独立地馈送到 CNN 中,那么对于不同的 ROI,我们需要重复提取 2000 次特征。(R-CNN很多卷积运算是重复的

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

直接利用特征图计算 ROI

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

将候选区域直接应用于特征图,并使用 ROI 池化将其转化为固定大小的特征图块

  以下是 Fast R-CNN 的流程图:

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

feature_maps = process(image)
ROIs = region_proposal(feature_maps)
for ROI in ROIs:
    patch = roi_pooling(feature_maps, ROI) 
    results = detector2(patch)

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

  • ROI 池化

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

  为简洁起见,我们先将 8×8 特征图转换为预定义的 2×2 大小。

  • 下图左上角:特征图。

  • 右上角:将 ROI(蓝色区域)与特征图重叠。

  • 左下角:将 ROI 拆分为目标维度。例如,对于 2×2 目标,我们将 ROI 分割为 4 个大小相似或相等的部分。

  • 右下角:找到每个部分的最大值,得到变换后的特征图。

输入特征图(左上),输出特征图(右下),ROI (右上,蓝色框)

  按上述步骤得到一个 2×2 的特征图块,可以馈送至分类器和边界框回归器中。

1.5  Faster R-CNN

  Fast R-CNN 依赖于外部候选区域方法,如选择性搜索。但这些算法在 CPU 上运行且速度很慢。在测试中,Fast R-CNN 需要 2.3 秒来进行预测,其中 2 秒用于生成 2000 个 ROI。

feature_maps = process(image)
ROIs = region_proposal(feature_maps)  # Expensive!
for ROI in ROIs
    patch = roi_pooling(feature_maps, ROI) 
    results = detector2(patch)

  Faster R-CNN 采用与 Fast R-CNN 相同的设计,只是它用内部深层网络代替了候选区域方法。新的候选区域网络(RPN)在生成 ROI 时效率更高,并且以每幅图像 10 毫秒的速度运行。

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

外部候选区域方法代替了内部深层网络

  • 候选区域网络(RPN)

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

  对于特征图中的每一个位置,RPN 会做 k 次预测。因此,RPN 将输出 4×k 个坐标和每个位置上 2×k 个得分。下图展示了 8×8 的特征图,且有一个 3×3 的卷积核执行运算,它最后输出 8×8×3 个 ROI(其中 k=3)。下图(右)展示了单个位置的 3 个候选区域。

  此处有 3 种猜想,稍后我们将予以完善。由于只需要一个正确猜想,因此我们最初的猜想最好涵盖不同的形状和大小。因此,Faster R-CNN 不会创建随机边界框。相反,它会预测一些与左上角名为「锚点」的参考框相关的偏移量(如x、y)。我们限制这些偏移量的值,因此我们的猜想仍然类似于锚点。

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

  这些锚点是精心挑选的,因此它们是多样的,且覆盖具有不同比例和宽高比的现实目标。这使得我们可以以更好的猜想来指导初始训练,并允许每个预测专门用于特定的形状。该策略使早期训练更加稳定和简便。

图源:https://arxiv.org/pdf/1506.01497.pdf

  Faster R-CNN 使用更多的锚点。它部署 9 个锚点框:3 个不同宽高比的 3 个不同大小的锚点框。每一个位置使用 9 个锚点,每个位置会生成 2×9 个 objectness 分数和 4×9 个坐标。

  • R-CNN 方法的性能

  如下图所示,Faster R-CNN 的速度要快得多。

1.6  基于区域的全卷积神经网络(R-FCN)

  假设我们只有一个特征图用来检测右眼。那么我们可以使用它定位人脸吗?应该可以。因为右眼应该在人脸图像的左上角,所以我们可以利用这一点定位整个人脸。

  如果我们还有其他用来检测左眼、鼻子或嘴巴的特征图,那么我们可以将检测结果结合起来,更好地定位人脸。

  现在我们回顾一下所有问题。在 Faster R-CNN 中,检测器使用了多个全连接层进行预测。如果有 2000 个 ROI,那么成本非常高。

复制代码
feature_maps = process(image)
ROIs = region_proposal(feature_maps)
for ROI in ROIs
    patch = roi_pooling(feature_maps, ROI)
    class_scores, box = detector(patch)         # Expensive!
    class_probabilities = softmax(class_scores)
复制代码

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

复制代码
feature_maps = process(image)
ROIs = region_proposal(feature_maps)         
score_maps = compute_score_map(feature_maps)
for ROI in ROIs
    V = region_roi_pool(score_maps, ROI)     
    class_scores, box = average(V)                   # Much simpler!
    class_probabilities = softmax(class_scores)
复制代码

  现在我们来看一下 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 函数,计算出每个类别的概率。

  以下是数据流图,在我们的案例中,k=3。

1.7  R-CNN系列总结

  我们首先了解了基础的滑动窗口算法:

for window in windows
    patch = get_patch(image, window)
    results = detector(patch)

  然后尝试减少窗口数量,尽可能减少 for 循环中的工作量。

ROIs = region_proposal(image)
for ROI in ROIs
    patch = get_patch(image, ROI)
    results = detector(patch)

二、单次目标检测器

  第二部分,我们将对单次目标检测器(包括 SSD、YOLO、YOLOv2、YOLOv3)进行综述。我们将分析 FPN 以理解多尺度特征图如何提高准确率,特别是小目标的检测,其在单次检测器中的检测效果通常很差。然后我们将分析 Focal loss 和 RetinaNet,看看它们是如何解决训练过程中的类别不平衡问题的。

2.1  单次检测器

  Faster R-CNN 中,在分类器之后有一个专用的候选区域网络。

Faster R-CNN 工作流

  基于区域的检测器是很准确的,但需要付出代价。Faster R-CNN 在 PASCAL VOC 2007 测试集上每秒处理 7 帧的图像(7 FPS)。和 R-FCN 类似,研究者通过减少每个 ROI 的工作量来精简流程。

feature_maps = process(image)
ROIs = region_proposal(feature_maps)
for ROI in ROIs
    patch = roi_align(feature_maps, ROI)
    results = detector2(patch)    # Reduce the amount of work here!

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

feature_maps = process(image)
results = detector3(feature_maps) # No more separate step for ROIs

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

基于滑动窗口进行预测

  这个概念和 Faster R-CNN 中的锚点很相似。然而,单次检测器会同时预测边界框和类别。例如,我们有一个 8 × 8 特征图,并在每个位置做出 k 个预测,即总共有 8 × 8 × k 个预测结果。

64 个位置

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

使用 4 个锚点在每个位置做出 4 个预测

  以下是 4 个锚点(绿色)和 4 个对应预测(蓝色),每个预测对应一个特定锚点。

4 个预测,每个预测对应一个锚点

   Faster R-CNN 中,我们使用卷积核来做 5 个参数的预测:4 个参数对应某个锚点的预测边框,1 个参数对应 objectness 置信度得分。因此 3× 3× D × 5 卷积核将特征图从 8 × 8 × D 转换为 8 × 8 × 5。

使用 3x3 卷积核计算预测

  在单次检测器中,卷积核还预测 C 个类别概率以执行分类(每个概率对应一个类别)。因此我们应用一个 3× 3× D × 25 卷积核将特征图从 8 × 8 × D 转换为 8 × 8 × 25(C=20)。

每个位置做出 k 个预测,每个预测有 25 个参数

  单次检测器通常需要在准确率和实时处理速度之间进行权衡。它们在检测太近距离或太小的目标时容易出现问题。在下图中,左下角有 9 个圣诞老人,但某个单次检测器只检测出了 5 个。

2.2  SSD (Single Shot MultiBox Detector)

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

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

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

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

  以下是特征图图示。

图源:https://arxiv.org/pdf/1512.02325.pdf

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

2.3  YOLO

YOLO 是另一种单次目标检测器。

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

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

  YOLO(v2)做出了很多实现上的改进,将 mAP 值从第一次发布时的 63.4 提高到了 78.6。YOLO9000 可以检测 9000 种不同类别的目标。

图源:https://arxiv.org/pdf/1612.08242.pdf

  以下是 YOLO 论文中不同检测器的 mAP 和 FPS 对比。YOLOv2 可以处理不同分辨率的输入图像。低分辨率的图像可以得到更高的 FPS,但 mAP 值更低。

图源:https://arxiv.org/pdf/1612.08242.pdf

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

图源:https://pjreddie.com/media/files/papers/YOLOv3.pdf

  YOLOv3 还添加了特征金字塔,以更好地检测小目标。以下是不同检测器的准确率和速度的权衡。

图源:https://pjreddie.com/media/files/papers/YOLOv3.pdf

特征金字塔网络(FPN)

  检测不同尺度的目标很有挑战性,尤其是小目标的检测。特征金字塔网络(FPN)是一种旨在提高准确率和速度的特征提取器。它取代了检测器(如 Faster R-CNN)中的特征提取器,并生成更高质量的特征图金字塔。

数据流

FPN(图源:https://arxiv.org/pdf/1612.03144.pdf)

  FPN 由自下而上和自上而下路径组成。其中自下而上的路径是用于特征提取的常用卷积网络。空间分辨率自下而上地下降。当检测到更高层的结构,每层的语义值增加。

FPN 中的特征提取(编辑自原论文)

  SSD 通过多个特征图完成检测。但是,最底层不会被选择执行目标检测。它们的分辨率高但是语义值不够,导致速度显著下降而不能被使用。SSD 只使用较上层执行目标检测,因此对于小的物体的检测性能较差。

图像修改自论文 https://arxiv.org/pdf/1612.03144.pdf

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

自上而下重建空间分辨率(编辑自原论文)

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

增加跳过连接(引自原论文)

  下图详细说明了自下而上和自上而下的路径。其中 P2、P3、P4 和 P5 是用于目标检测的特征图金字塔。

FPN 结合 RPN

  FPN 不单纯是目标检测器,还是一个目标检测器和协同工作的特征检测器。分别传递到各个特征图(P2 到 P5)来完成目标检测。

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

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

困难案例

  对于如 SSD 和 YOLO 的大多数检测算法来说,我们做了比实际的目标数量要多得多的预测。所以错误的预测比正确的预测要更多。这产生了一个对训练不利的类别不平衡。训练更多的是在学习背景,而不是检测目标。但是,我们需要负采样来学习什么是较差的预测。所以,我们计算置信度损失来把训练样本分类。选取最好的那些来确保负样本和正样本的比例最多不超过 3:1。这使训练更加快速和稳定。

推断过程中的非极大值抑制

  检测器对于同一个目标会做出重复的检测。我们利用非极大值抑制来移除置信度低的重复检测。将预测按照置信度从高到低排列。如果任何预测和当前预测的类别相同并且两者 IoU 大于 0.5,我们就把它从这个序列中剔除。

Focal Loss(RetinaNet)

  类别不平衡会损害性能。SSD 在训练期间重新采样目标类和背景类的比率,这样它就不会被图像背景淹没。Focal loss(FL)采用另一种方法来减少训练良好的类的损失。因此,只要该模型能够很好地检测背景,就可以减少其损失并重新增强对目标类的训练。我们从交叉熵损失 CE 开始,并添加一个权重来降低高可信度类的 CE。

  例如,令 γ = 0.5, 经良好分类的样本的 Focal loss 趋近于 0。

编辑自原论文

  这是基于 FPN、ResNet 以及利用 Focal loss 构建的 RetianNet

RetinaNet

 

原文链接:https://medium.com/@jonathan_hui/what-do-we-learn-from-region-based-object-detectors-faster-r-cnn-r-fcn-fpn-7e354377a7c9
https://medium.com/@jonathan_hui/what-do-we-learn-from-single-shot-object-detectors-ssd-yolo-fpn-focal-loss-3888677c5f4d


猜你喜欢

转载自blog.csdn.net/zr940326/article/details/80870567