【目标检测】FPN 论文详解



FPN 属于思想简洁但十分有效的模型.

注意, FPN 并不是一个独立的目标检测算法, 而只是一个 Backbone.


FPN 的主要贡献是:

  • 借鉴了 ResNet 的跳接, 结合了浅层特征和深层特征. (深层高等语义, 低分辨率; 浅层低等语义, 高分辨率)
  • 借鉴了 SSD 的检测策略, 在不同分辨率的特征图上分别做预测.

彩蛋:很多人可能没注意,这上图代表特征图的蓝色边框粗细不一,越粗表示特征语义更强


引言 Introduction

目标检测任务中, 一个反复被提起, 至今仍然很棘手的问题, 就是图片中的物体有大有小, 而往往当目标物体过小时, 识别会极其困难.


在物体检测里面,有限计算量情况下,网络的深度(对应到感受野)与 stride 通常是一对矛盾的东西,常用的网络结构对应的 stride 一般会比较大),而图像中的小物体甚至会小于 stride 的大小,造成的结果就是小物体的检测性能急剧下降。

传统解决这个问题的思路包括:

  • (1)多尺度训练和测试,又称图像金字塔,如图 1(a) 所示。目前几乎所有在 ImageNet 和 COCO 检测任务上取得好成绩的方法都使用了图像金字塔方法。然而这样的方法由于很高的时间及计算量消耗,难以在实际中应用。
  • (2)特征分层,即每层分别预测对应的 scale 分辨率的检测结果。如图 1(c) 所示。SSD 检测框架采用了类似的思想。这样的方法问题在于直接强行让不同层学习同样的语义信息。而对于卷积神经网络而言,不同深度对应着不同层次的语义特征,浅层网络分辨率高,学的更多是细节特征,深层网络分辨率低,学的更多是语义特征


图1

因而, 目前多尺度的物体检测主要面临的挑战为:

  • 如何学习具有强语义信息的多尺度特征表示?
  • 如何设计通用的特征表示来解决物体检测中的多个子问题? 如 object proposal, box localization. instance segmentation.
  • 如何高效率计算多尺度的特征表示?

本文针对这些问题, 提出了特征金字塔网络 FPN, 如图 1(d) 所示, 网络直接在原来的单网络上做修改, 每个分辨率的 feature map 引入后一分辨率缩放两倍的 feature map 做 element-wise 相加的操作. 通过这样的连接, 每一层预测所用的 feature map 都融合了不同的分辨率、不同语义强度的特征, 融合的不同分辨率的 feature map 分别做对应分辨率大小的物体检测. 这样保证了每一层都有合适的分辨率以及强语义特征. 同时, 由于此方法只是在原网络基础上加上了额外的跨层连接, 在实际应用中几乎不增加额外的时间和计算量. 




另外, 这里拿 Yolo 举个例子,Yolo(v1)把输入图片分成不同的网格,每个网格负责检测“中心落在”网格内部的物体,但每个网格只能预测一个物体,因此遇到如下图所示的情况时……

识别小物体是目标检测算法的老大难问题, 而特征金字塔网络 (Feature Pyramid Network, FPN) 就是用来解决不同尺寸目标预测的.

也正因为老大难,之前很多论文都给出了自己的做法,在介绍 FPN 之前先梳理一下。


在图像金字塔提特征 Featurized Image Pyramid


十分想当然的思路,既然你图片太小我预测不出来,那就把图片缩放到不同的大小,分别预测。

这是最直观的办法,自然也是最蠢的办法。


想象一下它的过程:

把一张图片提取特征预测 → 放大 → 提取特征预测 → 放大 → 提取特征预测……
这个过程中,每个特征提取 / 预测都是独立进行的!即使同一张图片的不同分辨率,模型之间也很难共享它们中间提取的特征。这让模型预测的过程费时费力,比如本来一个图片预测需要五秒,一个五级的图像金字塔耗时绝对不会少于 25 秒。


这还只是预测,训练模型更加耗时,因此出于这种考虑,图像金字塔通常只能在预测时使用

这又导致了新的问题,即此时模型本质上只是为了某种分辨率训练的,只是强行被拿去检测别的分辨率,这样的效果自然不可能好。


原始 CNN (Naïve CNN)

现在我们都知道,若以表征学习(representation learning)的角度思考 CNN,那么 CNN 实际上是有层次地学习图片的特征,即深度越深,则特征的语义越高级(从线到面,再到物体特征).

由于后续存在池化和降采样,浅层网络的特征图可以保留更多的分辨率,但是特征语义较为低级。

因此,CNN 只能寄希望于小物体的特征够在最后一层“存活下来”,但由于分辨率的损失,这显然是不切实际的。

但 CNN 这种层级计算特征如此高效,fast(er) R-CNN 也是靠这种层级结构达到加速效果的。因为此时至少特征计算是“共享的”,不用像图像金字塔那样傻乎乎一个个算。

那么问题来了,层级计算的时候,有辣么多分辨率的特征,那我们何不全用上?


金字塔型特征层级 Pyramidal feature hierarchy

实际上 SSD 就是 “把不同分辨率特征” 全用上的先驱之一。SSD 会在不同分辨率的特征上直接预测,那么不就大物体小物体都能预测到了吗?


这想法很不错,但还没有那么好。SSD 这么做有两个问题:

  • 底层特征语义不够
  • 最高分辨率并不高


正如之前分析的,实际上,底层特征的语义较低,携带信息的“有效性”略少,导致预测结果不佳。

SSD 缓解上述问题的方法是,太底层的语义干脆不用不就好了?


所以,你以为 SSD 是这样的:

实际上是这样的:

实际上,太浅层的特征 SSD 也根本没用上。这也不能怪 SSD,因为技术的发展永远是循序渐进的,它能意识到可以在不同分辨率特征上检测已是不易。

分析到这,一个很自然的想法就出现了 “我们是否可以结合深浅特征,兼顾分辨率与特征语义?” 原来大家都会说不可能,直到一个叫 ResNet 的模型告诉我们什么叫跳接。

现在,正文终于可以开始了 233



特征金字塔网络


FPN 是一种自顶向下路径和横向连接将低分辨率、语义强的特性与高分辨率、语义弱的特性结合起来的体系结构。


FPN 通过将浅层的特征跳接到深层的特征,兼顾了分辨率与特征语义。但实际上,这也不是 FPN 的首创,在对分辨率要求更高的语义分割问题中早有涉猎(如医学图像常用的 U-Net)。


但 FPN 的独到之处在于将深/浅层特征融合与多分辨率预测结合了起来。

有了初步认识,接下来就是模型的细节了。


模型细节 Details


从图上可以看出,FPN 可以分为三部分:

  • 自底向上的部分
  • 自顶向下的部分
  • 连接两部分的跳接

注意,实际上这个网络掰直了更像一个漏斗,可以理解为这里的底=高分辨率,顶=低分辨率。

自底向上

前馈 Backbone 的一部分,每一级往上用 step=2 的降采样。

输出 size 相同的网络部分叫一级 (Stage),举个例子: 下图是 fasterRCNN 的网络结构,左列 ResNet 用每级最后一个 Residual Block 的输出,记为 {C1,C2,C3,C4,C5}。

FPN 用 2~5 级参与预测(因为第一级的语义还是太低了),而 {C1,C2,C3,C4,C5} 这几级等效于在图片上以 {4,8,16,32} 为步长提取特征。



自顶向下&跳接

对底向上的特征图一级级上采样,再加上底向上跳接来的高分辨低语义特征用于预测。

上采样的方法是简单的最近邻插值

一个最近邻插值的例子

其中跳接时前后维度不一致问题的解决方法采用了1*1conv,对跳接不了解的请看我的ResNet的跳接笔记。

通过跳接融合特征之后,还要进行一个 3*3conv,以减轻最近邻插值带来的影响(因为周围的数字都比较相近,会出现重叠现象)

最后再看一眼网络图,一个完整的 FPN 架构就完成啦~




Reference

论文地址:Feature Pyramid Networks for Object Detection

Githubhttps://github.com/BigcowPeking/FPN

https://blog.csdn.net/wfei101/article/details/79301881

https://zhuanlan.zhihu.com/p/78160468

https://www.jiqizhixin.com/articles/2017-07-25-2