FPN总体架构如图所示,主要包含自下而上网络自上而下网络、横向连接卷积融合4个部分。

 自下而上:C2到C5代表不同的ResNet卷积组,这些卷积组包含了多个Bottleneck结构,组内的特征图大小相同,组间大小递减。

 自下而上:首先对C5进行1x1卷积降低通道数得到P5,然后依次进行上采样得到P4、P3、P2.目的是得到与C4、C3与C2长宽相同的特征,方便下次进行逐元素相加。采用2倍最近邻上采样(直接对临近元素进行复制,而非线性插值)。

横向连接:(Lateral Connection)目的是为了将上采样后的高语义特征与浅层的定位细节进行融合。高语义特征经过上采样后,其长宽与对应的浅层特征相同,而通道数固定为256。因此需要对特征C2——C4进行1x1卷积使得其通道数变为256.,然后两者进行逐元素相加得到P4、P3与P2。

卷积融合:在得到相加后的特征后,利用3x3卷积对生成的P2,P3,P4进行融合。目的是消除上采样过程中带来的重叠效应,以生成最终的特征图。


import torch.nn as nn
import torch.nn.functional as F
import math#ResNet的基本Bottleneck类
class Bottleneck(nn.Module):expansion=4#通道倍增数def __init__(self,in_planes,planes,stride=1,downsample=None):super(Bottleneck,self).__init__()self.bottleneck=nn.Sequential(nn.Conv2d(in_planes,planes,1,bias=False),nn.BatchNorm2d(planes),nn.ReLU(inplace=True),nn.Conv2d(planes,planes,3,stride,1,bias=False),nn.BatchNorm2d(planes),nn.ReLU(inplace=True),nn.Conv2d(planes,self.expansion*planes,1,bias=False),nn.BatchNorm2d(self.expansion*planes),)self.relu=nn.ReLU(inplace=True)self.downsample=downsampledef forward(self,x):identity=xout=self.bottleneck(x)if self.expansion is not None:identity=self.downsample(x)out+=identityout=self.relu(out)return out#FNP的类,初始化需要一个list,代表RESNET的每一个阶段的Bottleneck的数量
class FPN(nn.Module):def __init__(self,layers):super(FPN,self).__init__()self.inplanes=64#处理输入的C1模块(C1代表了RestNet的前几个卷积与池化层)self.conv1=nn.Conv2d(3,64,7,2,3,bias=False)self.bn1=nn.BatchNorm2d(64)self.relu=nn.ReLU(inplace=True)self.maxpool=nn.MaxPool2d(3,2,1)#搭建自下而上的C2,C3,C4,C5self.layer1=self._make_layer(64,layers[0])self.layer2=self._make_layer(128,layers[1],2)self.layer3=self._make_layer(256,layers[2],2)self.layer4=self._make_layer(512,layers[3],2)#对C5减少通道数,得到P5self.toplayer=nn.Conv2d(2048,256,1,1,0)#3x3卷积融合特征self.smooth1=nn.Conv2d(256,256,3,1,1)self.smooth2=nn.Conv2d(256,256,3,1,1)self.smooth3=nn.Conv2d(256,256,3,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)def _make_layer(self,planes,blocks,stride=1):downsample=Noneif 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.expansionfor i in range(1,blocks):layers.append(Bottleneck(self.inplanes,planes))return nn.Sequential(*layers)#自上而下的采样模块def _upsample_add(self,x,y):_,_,H,W=y.shapereturn F.upsample(x,size=(H,W),mode='bilinear')+ydef forward(self,x):#自下而上c1=self.maxpool(self.relu(self.bn1(self.conv1(x))))c2=self.layer1(c1)c3=self.layer2(c2)c4=self.layer3(c3)c5=self.layer4(c4)#自上而下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))#卷积的融合,平滑处理p4=self.smooth1(p4)p3=self.smooth2(p3)p2=self.smooth3(p2)return p2,p3,p4,p5
net=FPN([3,4,6,3])
net
FPN((conv1): Conv2d(3, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(relu): ReLU(inplace=True)(maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)(layer1): Sequential((0): Bottleneck((bottleneck): Sequential((0): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(4): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True)(downsample): Sequential((0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): Bottleneck((bottleneck): Sequential((0): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(4): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True))(2): Bottleneck((bottleneck): Sequential((0): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(4): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True)))(layer2): Sequential((0): Bottleneck((bottleneck): Sequential((0): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(128, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(4): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True)(downsample): Sequential((0): Conv2d(256, 512, kernel_size=(1, 1), stride=(2, 2), bias=False)(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): Bottleneck((bottleneck): Sequential((0): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(4): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True))(2): Bottleneck((bottleneck): Sequential((0): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(4): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True))(3): Bottleneck((bottleneck): Sequential((0): Conv2d(512, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(4): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(128, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True)))(layer3): Sequential((0): Bottleneck((bottleneck): Sequential((0): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(256, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(4): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True)(downsample): Sequential((0): Conv2d(512, 1024, kernel_size=(1, 1), stride=(2, 2), bias=False)(1): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): Bottleneck((bottleneck): Sequential((0): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(4): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True))(2): Bottleneck((bottleneck): Sequential((0): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(4): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True))(3): Bottleneck((bottleneck): Sequential((0): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(4): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True))(4): Bottleneck((bottleneck): Sequential((0): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(4): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True))(5): Bottleneck((bottleneck): Sequential((0): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(4): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(256, 1024, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(1024, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True)))(layer4): Sequential((0): Bottleneck((bottleneck): Sequential((0): Conv2d(1024, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(512, 512, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)(4): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True)(downsample): Sequential((0): Conv2d(1024, 2048, kernel_size=(1, 1), stride=(2, 2), bias=False)(1): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)))(1): Bottleneck((bottleneck): Sequential((0): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(4): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True))(2): Bottleneck((bottleneck): Sequential((0): Conv2d(2048, 512, kernel_size=(1, 1), stride=(1, 1), bias=False)(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(2): ReLU(inplace=True)(3): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)(4): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)(5): ReLU(inplace=True)(6): Conv2d(512, 2048, kernel_size=(1, 1), stride=(1, 1), bias=False)(7): BatchNorm2d(2048, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True))(relu): ReLU(inplace=True)))(toplayer): Conv2d(2048, 256, kernel_size=(1, 1), stride=(1, 1))(smooth1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(smooth2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(smooth3): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(latlayer1): Conv2d(1024, 256, kernel_size=(1, 1), stride=(1, 1))(latlayer2): Conv2d(512, 256, kernel_size=(1, 1), stride=(1, 1))(latlayer3): Conv2d(256, 256, kernel_size=(1, 1), stride=(1, 1))
)

FPN网络结构及Pytorch实现相关推荐

  1. resnet,retinanet,fpn网络结构及pytorch实现代码

    关于resnet,其巧妙地利用了shortcut连接,解决了深度网络中模型退化的问题.网络结构如下 FPN的目的 熟悉faster rcnn的人都知道,faster rcnn利用的是vgg的最后卷积特 ...

  2. fpn网络结构及代码

    文章目录 一.fpn网络结构 二.代码 一.fpn网络结构 resnet结构组成. fpn(Feature Pyramid Networks)架构如上图所示,以resnet50作为backbone.通 ...

  3. 机器学习之神经网络(从神经网络结构到pytorch基本用法)

    机器学习之神经网络(从神经网络结构到pytorch基本用法) 1.神经网络概念 1.1 网络结构 ​ 人工神经网络(artificial neural network,ANN),简称神经网络(neur ...

  4. ResNet50 网络结构搭建(PyTorch)

    ResNet50是一个经典的特征提取网络结构,虽然Pytorch已有官方实现,但为了加深对网络结构的理解,还是自己动手敲敲代码搭建一下.需要特别说明的是,笔者是以熟悉网络各层输出维度变化为目的的,只对 ...

  5. 【深度学习】VGG16网络结构复现 | pytorch |

    文章目录 前言 一.VGG16介绍 二.VGG16网络复现--pytorch 前言 这篇文章按道理来说应该是很简单的,但是因为一个很小的bug,让我难受了一晚上,直到现在我也没找出原因.后面我会提到这 ...

  6. SSD网络以及FSSD网络结构基于pytorch的搭建

    SSD网络,具体可阅读SSD相关论文: SSD网络:#-*-coding:utf-8-*- import torch import torch.nn as nn import torch.nn.fun ...

  7. 9 大主题卷积神经网络(CNN)的 PyTorch 实现

    Datawhale干货 作者:红色石头,北京大学,Datawhale伙伴 大家还记得这张图吗? 之前,红色石头发文介绍过一份很不错的资源: 52 个深度学习目标检测模型汇总,论文.源码一应俱全! 深度 ...

  8. 【深度学习】9 大主题卷积神经网络(CNN)的 PyTorch 实现

    大家还记得这张图吗? 之前,红色石头发文介绍过一份很不错的资源: 52 个深度学习目标检测模型汇总,论文.源码一应俱全! 深度系统介绍了 52 个目标检测模型,纵观 2013 年到 2020 年,从最 ...

  9. 目标检测算法之FPN(附FPN代码实现)

    论文题目:FeaturePyramidNetworksforObjectDetection 论文链接:https://arxiv.org/abs/1612.03144 所要解决的问题 针对小目标检测网 ...

  10. pytorch模型加载测试_使用Pytorch实现物体检测(Faster R-CNN)

    在本示例中,介绍一种two-stage算法(Faster R-CNN),将目标区域检测和类别识别分为两个任务进行物体检测.本示例采用PyTorch引擎进行模型构建. 如果您已熟练使用Notebook和 ...

最新文章

  1. Realm 使用的简单教程
  2. R语言与概率统计(六) 主成分分析 因子分析
  3. exit函数的头文件问题
  4. PW Live 直播 | 清华大学博士生岂凡超:义原知识库的应用和扩充
  5. 苹果7手机html5测试,HTML5 基础测试题
  6. jclouds_jclouds的命令行界面
  7. nodejs基于art-template模板引擎生成
  8. 技巧分享 PDF如何删除数字签名
  9. HDU1161 Eddy's mistakes
  10. Plugin “GsonFormat“ is incompatible
  11. Android 打包AAB+PAD(Unity篇)
  12. Maya2018安装报错:visual c++ 2010 sp1 错误代码1612
  13. 计算机外文文献ssh,计算机外文文献及翻译(SSH).doc
  14. Coq Art第二章 类型和表达式
  15. Vijos1197 费解的开关 枚举+位运算
  16. ORAN专题系列-28:5G基站如何升级到ORAN基站 - O-RU - 平台和传输层的改进(VLAN, PCP, DHCP, DNS)
  17. 武汉大学计算机系英语挂科,挂科率最高的前100所大学 武大挂的最多的居然是...
  18. 网站制作教程:PageAdmin建站系统在win2012上的安装
  19. 维谛技术(Vertiv)隆重举行“笃行——数据中心基础设施智能化管理研讨会”...
  20. JVM垃圾回收——G1垃圾收集器

热门文章

  1. 计算机专业课考研八月份复习,2016考研:计算机专业暑期复习攻略
  2. 微信UnionID的作用
  3. 手把手教你为 中文PDF电子书自动批量添加书签/目录, 彻底告别手动添加书签的烦恼
  4. 100 个 Python 小例子(练习题)
  5. 计算机需要无线网卡进行网络连,无线网卡
  6. 基于RT1052的FlexSPI读写FLASH(W25Q256JV)
  7. 菜鸟教程:零基础HTML入门
  8. 信息系统项目管理师学习笔记
  9. STM8S103之tim2PWM输出
  10. Linux log工具:zlog编译安装及使用示例(同样适用交叉编译环境)