FPN(特征图金字塔网络)理论基础与具体实现

FPN(特征图金字塔网络)理论基础与具体实现论文地址:FeaturePyramidNetworksforObjectDetection项目地址:FPN_pytorch0x00前言我们在做目标检测和超分辨率重建等问题的时候,我们一般是对同一个尺寸的图片进行网络训练。我们希望我们的网络能够适应更多尺寸的图片,我们传统的做法使用图像金字塔,但是这种做法从侧面提升了计算的复杂度,我们希望可以改善这个问题,所以本文就提出了…

大家好,又见面了,我是你们的朋友全栈君。

论文地址:Feature Pyramid Networks for Object Detection

项目地址:FPN_pytorch

0x00 前言

我们在做目标检测和超分辨率重建等问题的时候,我们一般是对同一个尺寸的图片进行网络训练。我们希望我们的网络能够适应更多尺寸的图片,我们传统的做法使用图像金字塔,但是这种做法从侧面提升了计算的复杂度,我们希望可以改善这个问题,所以本文就提出了一种在特征图金字塔的方法,我们称这种网络结构叫做FPN

0x01 论文分析


FPN(特征图金字塔网络)理论基础与具体实现

传统的图像金字塔任务是将不同尺度的图片进行特征提取(图a),主要使用人工提取特征,在人工提取特征的时代,大量使用特征化图像金字塔。它们非常重要,以至于像DPM这样的物体检测器需要密集的比例采样才能获得好的结果。但是这种做法变相的增加了训练数据,提高了运算耗时,所以这种做法已经很少被使用。

对于识别任务,工程特征已经被深度卷积网络(ConvNets)计算的特征大部分所取代。除了能够表示更高级别的语义,ConvNets不同层的特征图尺度也不同,从而有助于从单一输入尺度上计算的特征识别(图b)。但是这种做法的缺陷在于只使用了高分辨率特征,因为不同层之间的语义差别很大,最后一层主要都是高分辨率的特征,所以对于低分辨率的特征表现力不足。

接着为了改善上面的做法,一个很简洁的改进就是对不同尺度的特征图都进行利用,这也是SSD算法中使用的方法(图c)。理想情况下,SSD风格的金字塔将重复使用正向传递中计算的不同层次的多尺度特征图。但为了避免使用低层次特征,SSD会从偏后的conv4_3开始构建特征金字塔,这种做法没有对conv4_3之前的层进行利用,而这些层对于检测小目标很重要。


FPN(特征图金字塔网络)理论基础与具体实现

本文提出一种新的做法(图d),通过高层特征进行上采样和低层特征进行自顶向下的连接,而且每一层都会进行预测。

0x02 网络结构

作者这里做了一个有意思的比较。如果我们不是对不同尺寸的特征图进行预测,而是将不同尺寸的特征图融合后进行预测,会怎么样呢?


FPN(特征图金字塔网络)理论基础与具体实现

作者通过实验发现后者做法(也就是本文的做法)结果上会好很多。


FPN(特征图金字塔网络)理论基础与具体实现

上图中的(f only finest level)就上通过不同尺度特征图融合后,只采用最后一层预测的结果。(d bottom-up pyramid)表示没有采用自顶向下的过程得到的结果。

作者的主网络是使用的ResNet,而特征图金字塔分成三个部分,一个自底向上的路径(左边),一个自顶向下的路径(右边)和中间的连接部分。


FPN(特征图金字塔网络)理论基础与具体实现

自底向上的路径:自下而上的路径是卷积网络的前馈计算,该算法计算由不同比例的特征映射组成的特征层级,其缩放步长为2。通常有许多层产生相同大小的输出映射,并且我们说这些层 处于相同的网络阶段。 对于我们的特征图金字塔,为每个阶段定义一个金字塔等级, 然后选择每个阶段的最后一层的输出作为我们特征图的参考集。 这种选择是自然的,因为每个阶段的最深层应具有最强的特征。
具体而言,对于ResNets,我们使用每个阶段的最后一个residual block输出的特征激活输出。 对于conv2conv3conv4conv5输出,我们将这些最后residual block的输出表示为{C2,C3,C4,C5},并且它们相对于输入图像具有{4, 8, 16, 32} 的步长。 由于其庞大的内存占用,我们不会将conv1纳入金字塔中。

自顶向下的路径:自顶向下的路径通过对在空间上更抽象但语义更强高层特征图进行上采样来幻化高分辨率的特征。随后通过侧向连接从底向上的路径,使得高层特征得到增强。每个横向连接自底向上路径和自顶向下路径的特征图具有相同的尺寸。将低分辨率的特征图做2倍上采样(为了简单起见,使用最近邻上采样)。然后通过按元素相加,将上采样映射与相应的自底而上映射合并。这个过程是迭代的,直到生成最终的分辨率图。
为了开始迭代,我们只需在C5上附加一个1×1卷积层来生成低分辨率图P5。最后,我们在每个合并的图上附加一个3×3卷积来生成最终的特征映射,这是为了减少上采样的混叠效应。这个最终的特征映射集称为{P2,P3,P4,P5},分别对应于{C2,C3,C4,C5},它们具有相同的尺寸。
由于金字塔的所有层次都像传统的特征化图像金字塔一样使用共享分类器/回归器,因此我们在所有特征图中固定特征维度(通道数,记为d)。我们在本文中设置d = 256,因此所有额外的卷积层都有256个通道的输出。


FPN(特征图金字塔网络)理论基础与具体实现

中间连接:采用1×1的卷积核进行连接(减少特征图数量)。

0x03 网络的具体实现

我们这里参考了pytorchresnet的设计,关于resent的设计可以参看这篇ResNet理论基础与具体实现(详细教程)

class FPN(nn.Module):
def __init__(self, block, layers):
super(FPN, self).__init__()
self.inplanes = 64
self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, padding=3, bias=False)
self.bn1 = nn.BatchNorm2d(64)
self.relu = nn.ReLU(inplace=True)
self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
# Bottom-up layers
self.layer1 = self._make_layer(block,  64, layers[0])
self.layer2 = self._make_layer(block, 128, layers[1], stride=2)
self.layer3 = self._make_layer(block, 256, layers[2], stride=2)
self.layer4 = self._make_layer(block, 512, layers[3], stride=2)
# Top layer
self.toplayer = nn.Conv2d(2048, 256, kernel_size=1, stride=1, padding=0)  # Reduce channels
# Smooth layers
self.smooth1 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
self.smooth2 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
self.smooth3 = nn.Conv2d(256, 256, kernel_size=3, stride=1, padding=1)
# Lateral layers
self.latlayer1 = nn.Conv2d(1024, 256, kernel_size=1, stride=1, padding=0)
self.latlayer2 = nn.Conv2d( 512, 256, kernel_size=1, stride=1, padding=0)
self.latlayer3 = nn.Conv2d( 256, 256, kernel_size=1, stride=1, padding=0)
for m in self.modules():
if isinstance(m, nn.Conv2d):
n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
m.weight.data.normal_(0, math.sqrt(2. / n))
elif isinstance(m, nn.BatchNorm2d):
m.weight.data.fill_(1)
m.bias.data.zero_()
def _make_layer(self, block, planes, blocks, stride=1):
downsample  = None
if stride != 1 or self.inplanes != block.expansion * planes:
downsample  = nn.Sequential(
nn.Conv2d(self.inplanes, block.expansion * planes, kernel_size=1, stride=stride, bias=False),
nn.BatchNorm2d(block.expansion * planes)
)
layers = []
layers.append(block(self.inplanes, planes, stride, downsample))
self.inplanes = planes * block.expansion
for i in range(1, blocks):
layers.append(block(self.inplanes, planes))
return nn.Sequential(*layers)
def _upsample_add(self, x, y):
_,_,H,W = y.size()
return F.upsample(x, size=(H,W), mode='bilinear') + y
def forward(self, x):
# Bottom-up
x = self.conv1(x)
x = self.bn1(x)
x = self.relu(x)
c1 = self.maxpool(x)
c2 = self.layer1(c1)
c3 = self.layer2(c2)
c4 = self.layer3(c3)
c5 = self.layer4(c4)
# Top-down
p5 = self.toplayer(c5)
p4 = self._upsample_add(p5, self.latlayer1(c4))
p3 = self._upsample_add(p4, self.latlayer2(c3))
p2 = self._upsample_add(p3, self.latlayer3(c2))
# Smooth
p4 = self.smooth1(p4)
p3 = self.smooth2(p3)
p2 = self.smooth3(p2)
return p2, p3, p4, p5

关于FPN的全部代码在这里:FPN_pytorch

如有任何问题,希望大家指出!!!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/133380.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • PLSQLDeveloper14连接Oracle11g

    PLSQLDeveloper14连接Oracle11g提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录一、环境配置1.安装PLSQLDeveloper142.下载并解压Oracle客户端3.配置window操作系统环境变量二、工具配置1.Oracle客户端配置2.PLSQLDeveloper14配置3.重启PLSQLDeveloper14客户端结尾一、环境配置1.安装PLSQLDeveloper14官网自行下载,不详细阐述2.下载并解压Oracle客户端例如版本:instantclient-basic-nt-19.8.0

  • 四阶龙格库塔法的基本原理_隐式龙格库塔法

    四阶龙格库塔法的基本原理_隐式龙格库塔法龙格库塔法的基本原理该算法是构建在数学支持的基础之上的。对于一阶精度的拉格朗日中值定理有:对于微分方程:y’=f(x,y)y(i+1)=y(i)+h*K1K1=f(xi,yi)当用点xi处的斜率近似值K1与右端点xi+1处的斜率K2的算术平均值作为平均斜率K*的近似值,那么就会得到二阶精度的改进拉格朗日中值定理:y(i+1)=y(i)+[h*(K1+K2)/2]K1=f(xi,yi)K2=f(…

    2022年10月22日
  • 算法—时间复杂度[通俗易懂]

    算法—时间复杂度[通俗易懂]附录log对数:等差数列什么是等差数列?一般地,如果一个数列从第2项起,后一项与它的前一项的差等于同一个常数,那麽这个数列就叫做等差数列。这个常数叫做等差数列的公差,公差通常用字母d表示。例1:初识。-{1,3,5,7,9}公差为2-{5,15,25,35,45}公差为10-{2,68,134,200,266}公差为66-{5…

  • load average 计算「建议收藏」

    load average 计算「建议收藏」平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均活跃进程数。对于Ubuntu获取cpu数和cpu核数more/proc/cpuinfo|grep”physicalid”|uniq|wc-l#=>1more/proc/cpuinfo|grep”physicalid”|grep”0″|wc-l#=>16则1*…

  • 伯努利分布、二项式分布与多项式分布简介「建议收藏」

    伯努利分布、二项式分布与多项式分布简介「建议收藏」一,伯努利分布(bernoulidistribution)又叫做0-1分布,指一次随机试验,结果只有两种。也就是一个随机变量的取值只有0和1。记为:0-1分布或B(1,p),其中p表示一次伯努利实验中结果为正或为1的概率。 概率计算:P(X=0)=p0P(X=1)=p1期望计算:E(X)=0∗p0+1∗p1=p最简单的例子就是,抛一次硬币,预测…

    2022年10月11日
  • php curl_init函数用法

    php curl_init函数用法使用PHP的cURL库可以简单和有效地去抓网页。你只需要运行一个脚本,然后分析一下你所抓取的网页,然后就可以以程序的方式得到你想要的数据了。无论是你想从从一个链接上取部分数据,或是取一个XML文件并把其导入数据库,那怕就是简单的获取网页内容,cURL是一个功能强大的PHP库。PHP中的CURL函数库(ClientURLLibraryFunction)curl_close—关

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号