文章结构

  • 1. 为什么会使用金字塔式的representation以及它存在的问题。
  • 2. 原理和特点。
  • 3. 如何基于resnet实现(思路)。
  • 4. 小总结

1. 为什么会使用金字塔式的representation以及它存在的问题。

论文中提到一些传统的使用深度学习来做物体检测的结构会倾向于避开使用金字塔性质的representation, 因为使用这样的representation会对算力和内存带来很大的压力。但是金字塔形式的representation对物体检测有着非常大的作用。因为它可以将一张图像在多个不同的尺寸上进行处理,会提高对图像中尺寸相对较小的物体检测的准确度。因为传统的物体检测的方法都是基于一张特征图,但是一张特征图能提供的信息非常的有限,若是物体在图像中所占的像素非常的少,是很有可能检测不到的。但是传统的特征金字塔也存在着诸多的问题。

传统的特征金字塔存在这些问题:

  • 为了得到图像在不同尺寸下的金字塔式的表示,使用图像金字塔去生成对应的特征金字塔在理论上虽然是可行,但是特征金子塔的推理时间相当的长,在追求高效和实时的需求下的劣势非常明显。除此之外,如果想要配合深度学习进行端对端的训练,是不现实的,因为计算量过于巨大。
  • 除了使用图像金字塔以外的方法,还可以使用卷积神经网络本身自带的金字塔属性(每一个卷积层输出的特征图的大小会逐渐变小,最后得到一些高语义的特征。)来构建一个 in-network feature hierarchy来产出不同大小的feature map.但是这样的作法也存在着问题,不同的深度会导致较大的semantic gap 从而影响到网络进行物体检测的表现。

在本文中,作者利用CNN模型固有的金字塔形式的属性,提出一个有着 bottom-up, top-down, lateral connection 3个模块的特征金字塔。它的目的之一是为了让特征图进行融合,是特征图拥有更丰富的语义信息。接下来就着重记录,这三个板块的结构和特点,以及实现和训练中要注意的问题。

下图是论文中 特征金字塔的示意图。

2. 原理和特点。

从Bottom-up pathway 开始,这一个小模块其实可以简答的理解成是 CNN的前向传播过程,每一个卷积层都会输出一个特征图。输出相同的大小的特征图的卷积层作者称之为是一个阶段。使用每个阶段中的最后一个输出作为当前阶段的输出。和传统的网络的不同之处在于,每一个阶段的所输出的特征图会被保存下来在后续的操作当中进行使用。Bottom-up 最后一层的输出是有着高语义的特征图。这里需要注意的一点是bottom-up pathway当中,每一个特征图是按照步长为2进行下采样的。这意味着,从第二个阶段开始的步长是 4, 第三个阶段是8,第4个阶段是16,然后第5个阶段是32。这是因为在这里的上采样过程使用的是 邻近值法。

随着bottom-up过程的结束,top-down也随之开始。Top-down过程可以先简单的理解成是一个上采样的过程。说的具体一些,Top-down过程的首先将 bottom-up最后一个阶段得到的特征图上采样到和bottom-up的第四阶段输出的特征图一样大的尺寸,然后在将通过横向连接(lateral connection)将他们进行 element-wise addition。换句话说就是,横相连接将bottom-up 和 top-down 尺寸相同的特征图进行融合。然后这个过程一直重复,直到整个过程结束。这里也有一些关于top-down和lateral connection的小细节需要注意。每一次 lateral connection都会有一个1 * 1 的卷积,这样做的目的是在调整特征图通道的数量。除此之外,每一个经过横向连接产生的特征图还会被一个3*3的卷积核进行卷积。论文中提到的原因是使用这样的技术去处理在上采样操作中出现的混叠效应。那所谓的混叠效应是什么呢? 这里的混叠效应指的是一种失真的现象,在这里可以简单的理解成两个特征图叠加,造成的特征失真或者混乱的现象。

从上面的记录中可以可以看出,对于这样一个网络,他的输入是一张任意大小的图像,然后输出多个,尺寸不一但是通道数一致的特征图。

3. 如何基于resnet实现(思路)。

那么应该如何将上述的FPN网络实现呢。这里使用resnet来举个例子。首先记录bottom-u的过程,这个过程就是Resnet的前向传播过程。ResNet的bottleNeck 可以用以下代码来实现。

class Bottleneck(nn.Module):expansion = 4def __init__(self, in_planes, planes, stride=1):super(Bottleneck, self).__init__()self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=1, bias=False)self.bn1 = nn.BatchNorm2d(planes)self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)self.bn2 = nn.BatchNorm2d(planes)self.conv3 = nn.Conv2d(planes, self.expansion*planes, kernel_size=1, bias=False)self.bn3 = nn.BatchNorm2d(self.expansion*planes)self.shortcut = nn.Sequential()if stride != 1 or in_planes != self.expansion*planes:self.shortcut = nn.Sequential(nn.Conv2d(in_planes, self.expansion * planes, kernel_size=1, stride=stride, bias=False),nn.BatchNorm2d(self.expansion*planes))def forward(self, x):out = F.relu(self.bn1(self.conv1(x)))out = F.relu(self.bn2(self.conv2(out)))out = self.bn3(self.conv3(out))out += self.shortcut(x)out = F.relu(out)return out

上述代码中的 self.expansion = 4 是什么意思? 因为resnet每一个residual module的输入通道数(in_channels)和输出通道数 (out_channels) 遵循 : out_channels = in_channels * 4 。有了上述的block 模块之后,就可以很容易的使用下面的代码完成resnet的前向传播:

     class FPN(nn.Module):def __init__(self, block, num_blocks):super(FPN, self).__init__()self.in_planes = 64self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)self.bn1 = nn.BatchNorm2d(64)# resnet forward propagation / Bottom-up pathwayself.layer1 = self._make_layer(block,  64, num_blocks[0], stride=1)self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)

上述的代码就是resnet 和 bottom-up pathway 需要经过的层。在bottom-up完成之后,我们需要使用一个layer,在top-down之前来调整layer4所输出的特征图的通道数量:

 self.top_layer = nn.Conv2d(2048, 256, kernel_size=1, stride=1, padding=0)

之后就是进行特征图的上采样和相加,这个方法可以直接使用pytorch的functional中提供的upsample的方法去实现。到这里我们每一层还需要一个3 * 3的卷积核来去除混叠效应和一个1*1的通道数来调整每一个特征图通道的大小。

         self.anti_alising_1 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)self.anti_alising_2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)self.anti_alising_3 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)

上面是每一层去除混叠效应的卷积核,因为文中提到了最后输出的每一张特征图的维度都是256,所以会看到上述定义的anti_alising_ 都有着相同的输入和输出的通道数。

     self.lateral_layer1 = nn.Conv2d(1024, 256, kernel_size=1, stride=1, padding=0)self.lateral_layer2 = nn.Conv2d( 512, 256, kernel_size=1, stride=1, padding=0)self.lateral_layer3 = nn.Conv2d( 256, 256, kernel_size=1, stride=1, padding=0)

上述代码是fpn的横向连接,仔细每一个观察横向连接中的输入channel 和 bottom-up中的正好相反。这个小的细节对我们在实现或者记忆FPN的结构上有一定的帮助。

到此,FPN的所有重要的板块都已经用代码实现,只需要重写nn.Module中的forward函数便可以完成FPN的前向传播。
我们假设输入一张尺寸为224 * 224的图像,那么基于Resnet101的FPN输出的特征图的形状应该如下所示:

torch.Size([1, 256, 56, 56])
torch.Size([1, 256, 28, 28])
torch.Size([1, 256, 14, 14])
torch.Size([1, 256, 7, 7])

4. 小总结

FPN利用了CNN自带的金子塔式的结构特点,使用了 bottom-up, top-down以及 lateral connection三个不同的路径,生成了具有高语义信息的特征图。这样技术可以被运用到了现在一些主流的物体检测和物体分割的网络中,比如mask rcnn。它有效的提高了网络的表现以及在一定的程度上解决了 pyramid representation的一些固有问题。

FPN (特征金字塔) 的原理和代码相关推荐

  1. 【深度学习】FPN(特征金字塔)简介:Feature Pyramid Networks for Object Detection

    [深度学习]FPN(特征金字塔):Feature Pyramid Networks for Object Detection 提示:博主取舍了很多大佬的博文并亲测有效,分享笔记邀大家共同学习讨论 博文 ...

  2. 计算机视觉FPN: 特征金字塔网络

    向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程   公众号:datayx FPN:feature pyramid networks for object detecti ...

  3. FPN 特征金字塔网络

    FPN(feature pyramid networks) 特征金字塔是多尺度目标检测系统中的一个基本组成部分.近年来深度学习目标检测却有意回避这一技巧,部分原因是特征金字塔在计算量和用时上很敏感(一 ...

  4. 特征金字塔:FPN(Feature Pyramid Networks)

    参考: [论文笔记]FPN -- 特征金字塔 神经网络学习小记录29--特征金字塔-Feature Pyramid Networks(FPN) 1.introduction 在目标检测中,对于小目标的 ...

  5. 图像金字塔和特征金字塔

    图像金字塔 图像金字塔是图像多尺度表达的一种,是一种以多分辨率来解释图像的有效但概念简单的结构.一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图像集合.其通过梯次向下 ...

  6. 深度学习阅读导航 | 04 FPN:基于特征金字塔网络的目标检测

    写在前面:大家好!我是[AI 菌],一枚爱弹吉他的程序员.我热爱AI.热爱分享.热爱开源! 这博客是我对学习的一点总结与记录.如果您也对 深度学习.机器视觉.算法.Python.C++ 感兴趣,可以关 ...

  7. 详解何恺明团队4篇大作 !(附代码)| 从特征金字塔网络、Mask R-CNN到学习分割一切

    来源:新智元 作者:krish 本文5000字,建议阅读10+分钟. 本文介绍FAIR何恺明.Tsung-Yi Lin等人的团队在计算机视觉领域最新的一些创新,包括特征金字塔网络.RetinaNet. ...

  8. 【CV】FPN:用于目标检测的特征金字塔网络

    论文名称:Feature Pyramid Networks for Object Detection 论文下载:https://arxiv.org/abs/1612.03144 论文年份:2016 论 ...

  9. 性能超FPN!北大、阿里等提多层特征金字塔网络

    作者 | Qijie Zhao等 编译 | 李杰 出品 | AI科技大本营(ID:rgznai100) 特征金字塔网络具有处理不同物体尺度变化的能力,因此被广泛应用到one-stage目标检测网络(如 ...

最新文章

  1. java 的继承_关于java中的继承
  2. redis-dump安装问题
  3. 华为宣布:免费培养2000名大数据开发者!
  4. C语言 数组内存溢出 - C语言零基础入门教程
  5. TCP/IP文档阅读笔记-TCP Receive Window
  6. Office Web Apps开放测试
  7. linux系统数据库导出语句,数据库应用-SQL语句导入导出大全
  8. matlab-高数 反、双曲、正、余弦、正切函数
  9. 高德地图api中的adcode城市编码
  10. 杰出人物的四大法宝——与成功学大师对话
  11. Spring Boot/Spring Cloud 集成Page Office支持word、excel、ppt在线浏览编辑
  12. Failed to decode response: zlib_decode(): data error Retrying with degraded mode, check
  13. Django使用supervisor管理celery和uwsgi实践记录 uwsgi BACKOFF Exited too quickly (process log may have details)
  14. 【蓝桥杯Python-无聊的逗】解题思路和参考代码
  15. 将qq目录下文件写如qq.txt
  16. css中的background属性
  17. 基于apollo实现配置灰度发布
  18. 【论文阅读】【3d目标检测】Behind the Curtain: Learning Occluded Shapes for 3D Object Detection
  19. 我奋斗18年,和你或者咖啡没有任何关系
  20. Zynq的启动过程及加密

热门文章

  1. 怎样下载谷歌最新版100.0.4896.127chromedriver
  2. Cannot determine value type from string ‘5ca68b45-78bc-4a68-b3a6-97b0ff73797‘
  3. 2018年电子设计大赛主要元器件、模块资料汇总
  4. 【特征工程】定性数据的编码
  5. 2019双十一大战:苏宁的“1小时场景生活圈”诱惑
  6. Java的4种XML解析
  7. ubuntu 20.04安装各类软件
  8. 官方Nexus软件下载教程
  9. SpringBoot统一返回处理出现cannot be cast to java.lang.String异常
  10. 如何将汉字写得又好又快