FPN细节剖析以及pytorch代码实现

article/2025/9/22 7:08:49

目录

FPN(feature pyramid network)

网络结构

bottleneck

pytorch代码实现

公式:卷积层输入输出大小的计算公式

细节一:代码中blocks参数的含义

细节二:c1 c2 c3 c4 c5层尺寸分别为原图的1/2 1/4 1/8 1/16 1/32        

细节三:bottleneck实现过程中,原始特征进行下采样


FPN(feature pyramid network)

        FPN是目标检测中用于多尺度物体检测的重要工具。高层特征,语义信息丰富,但目标位置模糊;低层特征,语义信息较少,但目标位置清晰。FPN通过融入特征金字塔,将高层特征与低层特征进行融合,将高语义信息传递给低层特征,提高了目标检测的准确率,尤其是小物体的检测上。

网络结构

        采用自底向上横向连接以及自底向下三种结构。其中自底向上时采用ResNet的bottleneck,每一层特征图的尺寸均为上一层的1/2;横向连接时采用1*1卷积来降低维度,输出通道数均为256;自底向下时将高层特征2倍上采样,此时特征图大小与低层特征相同,因此与低层特征融合。

        特征融合完之后,进行一个3*3的卷积,最终得到本层的特征输出p2-p5。使用这个3*3卷积的目的是为了消除上采样产生的混叠效。混叠效应,指经过上采样插值后生成的图像灰度不连续,在灰度变化的地方可能出现明显的锯齿状。金字塔所有层的输出特征都共享 分类cls/回归reg,所以3*3卷积输出的维度都被统一为256。

bottleneck

采用ResNet的bottleneck

         使用右侧的bottleneck(ResNet50 101 152中采用的backbone):对输入特征进行1*1卷积 bn relu -> 3*3卷积 bn relu -> 1*1卷积 bn(输出通道数为输入通道数的4倍,即通道扩增数=4)后,与输入特征相加,经过relu激活函数输出。

pytorch代码实现

import torch.nn as nn
import torch.nn.functional as F# ResNet基本的Bottleneck类(Resnet50/101/152)
class Bottleneck(nn.Module):expansion = 4  # 通道扩增倍数(Resnet网络的结构)def __init__(self,in_planes,planes,stride=1,downsample=None):super(Bottleneck, self).__init__()self.bottleneck=nn.Sequential(nn.Conv2d(in_planes,planes,kernel_size=1,bias=False),nn.BatchNorm2d(planes),nn.ReLU(inplace=True),nn.Conv2d(planes, planes, kernel_size=3,stride=stride, padding=1,bias=False),nn.BatchNorm2d(planes),nn.ReLU(inplace=True),nn.Conv2d(planes, self.expansion*planes, kernel_size=1, bias=False),nn.BatchNorm2d(self.expansion*planes),)self.relu=nn.ReLU(inplace=True)self.downsample=downsampledef forward(self, x):identity = x    # 初始的xout = self.bottleneck(x)# 残差融合前需保证out与identity的通道数以及图像尺寸均相同if self.downsample is not None:identity = self.downsample(x)  # 初始的x采取下采样out += identity  out = self.relu(out)return outclass FPN(nn.Module):'''FPN需要初始化一个list,代表ResNet每一个阶段的Bottleneck的数量'''def __init__(self, layers):super(FPN, self).__init__()# 构建C1self.inplanes = 64self.conv1 = nn.Conv2d(in_channels=3, out_channels=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)# 自下而上搭建C2、C3、C4、C5self.layer1 = self._make_layer(64, layers[0])self.layer2 = self._make_layer(128, layers[1], 2) # c2->c3第一个bottleneck的stride=2self.layer3 = self._make_layer(256, layers[2], 2) # c3->c4第一个bottleneck的stride=2self.layer4 = self._make_layer(512, layers[3], 2) # c4->c5第一个bottleneck的stride=2# 对C5减少通道,得到P5self.toplayer = nn.Conv2d(2048, 256, 1, 1, 0)  # 1*1卷积# 横向连接,保证每一层通道数一致self.latlayer1 = nn.Conv2d(1024, 256, 1, 1, 0)self.latlayer2 = nn.Conv2d(512, 256, 1, 1, 0)self.latlayer3 = nn.Conv2d(256, 256, 1, 1, 0)# 平滑处理 3*3卷积self.smooth = nn.Conv2d(256, 256, 3, 1, 1)# 构建C2到C5def _make_layer(self, planes, blocks, stride=1, downsample = None):# 残差连接前,需保证尺寸及通道数相同if stride != 1 or self.inplanes != Bottleneck.expansion * planes:downsample = nn.Sequential(nn.Conv2d(self.inplanes, Bottleneck.expansion * planes, 1, stride, bias=False),nn.BatchNorm2d(Bottleneck.expansion * planes))layers = []layers.append(Bottleneck(self.inplanes, planes, stride, downsample))# 更新输入输出层self.inplanes = planes * Bottleneck.expansion# 根据block数量添加bottleneck的数量for i in range(1, blocks):layers.append(Bottleneck(self.inplanes, planes)) # 后面层stride=1return nn.Sequential(*layers)  # nn.Sequential接收orderdict或者一系列模型,列表需*转化# 自上而下的上采样def _upsample_add(self, x, y):_, _, H, W = y.shape  # b c h w# 特征x 2倍上采样(上采样到y的尺寸)后与y相加return F.upsample(x, size=(H, W), mode='bilinear') + ydef forward(self, x):# 自下而上c1=self.relu(self.bn1(self.conv1(x)))   # 1/2# c1=self.maxpool(self.relu(self.bn1(self.conv1(x))))  此时为1/4c2 = self.layer1(self.maxpool(c1))      # 1/4c3 = self.layer2(c2)                    # 1/8c4 = self.layer3(c3)                    # 1/16c5 = self.layer4(c4)                    # 1/32# 自上而下,横向连接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))# 平滑处理p5 = p5  # p5直接输出p4 = self.smooth(p4)p3 = self.smooth(p3)p2 = self.smooth(p2)return p2, p3, p4, p5FPN(layers=[5,5,5,5])  
# 传入生成c2 c3 c4 c5特征层的bottleneck的堆叠数量,返回p2 p3 p4 p5

公式:卷积层输入输出大小的计算公式

卷积层输出feature map大小计算公式: (一般向下取整)

o=\frac{i+2p-k'}{s}+1  

        孔洞卷积 k' = d(k-1) + 1;非孔洞卷积的d=1,因此k'=k。

        o是输出尺寸(H或W),i 是输入尺寸(H或W), k 是卷积核尺寸,p是 padding大小,  s是stride步长, d是空洞卷积dilation膨胀系数。

注意:池化过程的尺寸变化同卷积过程。

细节一:代码中blocks参数的含义

        最后一行需要传入产生c2 c3 c4 c5特征层的bottleneck的堆叠数量(可以设置不同的参数)。例如:ResNet50中block参数为[3,4,6,3],即c2层需c1层经过Maxpool以及3层bottleneck的堆叠,c3层需要c2层经过4层bottleneck的堆叠,以下层同理。

细节二:c1 c2 c3 c4 c5层尺寸分别为原图的1/2 1/4 1/8 1/16 1/32        

        c1层特征代码很多通常写为c1=self.maxpool(self.relu(self.bn1(self.conv1(x)))),但其实maxpool操作在c1->c2过程中。因此采用下面的方法:

c1 = self.relu(self.bn1(self.conv1(x)))   # 1/2
c2 = self.layer1(self.maxpool(c1))      # 1/4

        此时,c1为第一个特征图,根据卷积层输入输出计算公式,由于conv1步长为2,因此尺寸变为原图的1/2。c2特征,由于self.maxpool层,因此尺寸变为c1特征图的1/2,即原图的1/4。c3 c4 c5特征图可使用公式同样计算尺寸。因此,自底向上的过程,相邻层特征图尺寸减半,通道数变为原来的2倍。

细节三:bottleneck实现过程中,原始特征进行下采样

        由于ResNet网络需将输出特征与原始特征进行相加,需要特征层尺寸相同且通道数相同,因此原始特征x需要进行下采样downsample,经过1*1卷积,将通道数变为4*planes。

        关于步长,ResNet中c1->c2层,maxpool层使得尺寸减半,因此卷积层步长stride=1(不改变特征图大小);c3 c4 c5层的生成过程无池化过程,因此第一个block的bottleneck步长设置为2(使特征图宽高减半),后续bottleneck的堆叠,步长为1(不改变特征图尺寸)。


http://chatgpt.dhexx.cn/article/asucSrLq.shtml

相关文章

目标检测之FPN、AugFPN、NAS-FPN

针对小目标的检测有提升的文章。 未完待续~ Feature Pyramid Networks for Object Detection FPN是一种多尺度的目标检测算法。大多数目标检测算法都是采用顶层特征来做预测的,但是我们知道:低层的特征语义信息较少,但是位置信息丰富&#x…

FPN网络和RPN网络介绍

原文链接 神经网络特征提取过程中,一般底层特征具有良好的空间信息,高层的具有良好的语义信息。原来多数的object detection算法都是只采用顶层特征做预测,但我们知道低层的特征语义信息比较少,但是目标位置准确;高层…

Neck网络 FPN + PAN 改进解读

呃 这篇文章的目的在于补充一些知识以便于理解Neck部分的网络 特征提取网络 与 目标检测之间的关系 一个特征提取网络,假设有1000层,开始的特征图包含的细节信息就很多,而随着网络的加深,特征提取网络经过多次被卷积和池化操作&…

FPN论文笔记

FPN论文笔记 现在看FPN和Inception并行结构融合有点像,FPN上采样同时横向连接相加,Inception是堆叠几个感受野不同的feature,融合的思想有点相似。 FPN是什么? Feature Pyramid Networks,用于特征抽取(feature extr…

FPN算法一览

FPN应该是2017年CV顶会的优秀论文,基于目标检测做的研究,在小物体检测方面较为具有吸引力。 1.FPN 源论文:feature pyramid networks for object detection 参考代码:FPN 同时利用低层特征高分辨率和高层特征的高语义信息&…

目标检测中的各种FPN

早期的目标检测算法,无论是一步式的,还是两步式的,通常都是在Backbone的最后一个stage(特征图分辨率相同的所有卷积层归类为一个stage)最后一层的特征图,直接外接检测头做目标检测。此种目标检测算法&#…

FPN(在FasterRCNN里面是如何运用的)

FPN(Feature Pyramid Networks) FPN解决了什么问题? 答:FPN的提出是为了实现更好的feature maps融合,一般的网络都是直接使用最后一层的feature maps,虽然最后一层的feature maps 语义强,但是位置和分辨率都比较低&…

深度学习之FPN+PAN

一、FPN 检测不同尺度的物体具有挑战性,尤其是对于小物体,我们可以使用不同尺度的同一图像的金字塔来检测物体(下左图)但是,处理多尺度图像非常耗时并且内存需求太高而无法同时进行端到端训练,因此创建了一…

FPN全解-最全最详细

这篇论文是CVPR2017年的文章,采用特征金字塔做目标检测,有许多亮点,特来分享。 论文:feature pyramid networks for object detection 论文链接:https://arxiv.org/abs/1612.03144 论文概述: 作者提出的…

FPN和PAN的内容及区别

FPN和PAN都是用于解决在目标检测中特征金字塔网络(FPN)在多尺度检测任务上的不足的方法。下面分别详细介绍一下它们的原理和区别。 FPN FPN全称Feature Pyramid Network,是由FAIR在2017年提出的一种处理多尺度问题的方法。FPN的主要思路是通过构建金字塔式的特征图…

深度学习之FPN和PAN

注:借鉴整理,仅供自学,侵删 FPN是自顶向下,将高层的强语义特征传递下来,对整个金字塔进行增强,不过只增强了语义信息,对定位信息没有传递。PAN就是针对这一点,在FPN的后面添加一个自…

FPN网络介绍

目录 前言一.FPN网络二.网络创新点 前言 上一篇博文我们介绍了FCN结构,这篇博文我们来简答的介绍下FPN网络,FPN (Feature Pyramid Network) 是一种用于图像语义分割、物体检测等任务的神经网络结构。是针对目标检测提出的结构。 一.FPN网络 先来看下FP…

FPN+PAN结构,SPP结构

一、FPNPAN FPN 高维度向低维度传递语义信息(大目标更明确) PAN 低维度向高维度再传递一次语义信息(小目标也更明确) 二、SPP 深层的feature map携带有更强的语义特征,较弱的定位信息。而浅层的feature map携带有…

FPN+PAN结构学习

yolo4的neck结构采用该模式,我们将Neck部分用立体图画出来,更直观的看下两部分之间是如何通过FPN结构融合的。 如图所示,FPN是自顶向下的,将高层特征通过上采样和低层特征做融合得到进行预测的特征图。Neck部分的立体图像&#xf…

FPN网络理解

1.什么是FPN fpn设计动机:1.高层特征向低层特征融合,增加低层特征表达能力,提升性能 2.不同尺度的目标可以分配到不同层预测,达到分而治之。 fpn设计细节:1*1的卷积是让最左侧的三个特征图的通道保持一致,从…

FPN详述

简介 为了使用更多的语义信息,目标检测模型一般在卷积神经网络最后一层的特征图上进行后续操作(随着不断地下采样,语义信息更丰富,空间信息更稀少),而这一层对应的下采样率一般是比较大的,如16…

FPN与Unet的异同

来源:目标检测的FPN和Unet有差别吗? - 知乎 (zhihu.com) 作者:CW不要無聊的風格 链接:https://www.zhihu.com/question/351279839/answer/1598104355 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业…

FPN以及其他结构FPN——Bi-FPN重点(仅供自己学习使用)

FPN FPN特征金字塔结构。 由于目标检测中对小物体检测很困难,因为卷积过程中,大物体的像素点多,小物体的像素点少,随着卷积的深入,大物体的特征容易被保留,小物体的特征越往后越容易被忽略。所以产生了FPN结…

FPN(Feature Pyramid Networks)详解

图像金字塔结构 图a 图a是在传统的图像处理当中是比较常见的一个方法。针对我们要检测不同尺度的目标时,会将图片缩放成不同的尺度,然后将每个尺度的图片依次通过我们的算法进行预测。 优点是它创建的多尺度特征的所有层次都包含很强的语义特征&#xf…

FPN解读

前两篇博客中都说到了FPN这个神器,今天就花了点时间看了下这篇论文,喜欢这个很赞很干净的结构。 Motivation 凡是都要从motivation说起,哈哈哈。rcnn系列在单个scale的feature map做检测(b),尽管conv已经对scale有些鲁棒了&#…