位置: IT常识 - 正文

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

编辑:rootadmin
FPN细节剖析以及pytorch代码实现

目录

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细节剖析以及pytorch代码实现,希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!

        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 nnimport 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=downsample def forward(self, x): identity = x # 初始的x out = 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__() # 构建C1 self.inplanes = 64 self.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、C5 self.layer1 = self._make_layer(64, layers[0]) self.layer2 = self._make_layer(128, layers[1], 2) # c2->c3第一个bottleneck的stride=2 self.layer3 = self._make_layer(256, layers[2], 2) # c3->c4第一个bottleneck的stride=2 self.layer4 = self._make_layer(512, layers[3], 2) # c4->c5第一个bottleneck的stride=2 # 对C5减少通道,得到P5 self.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到C5 def _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=1 return 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') + y def forward(self, x): # 自下而上 c1=self.relu(self.bn1(self.conv1(x))) # 1/2 # c1=self.maxpool(self.relu(self.bn1(self.conv1(x)))) 此时为1/4 c2 = self.layer1(self.maxpool(c1)) # 1/4 c3 = self.layer2(c2) # 1/8 c4 = self.layer3(c3) # 1/16 c5 = 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公式:卷积层输入输出大小的计算公式FPN细节剖析以及pytorch代码实现

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

  

        孔洞卷积 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/2c2 = 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(不改变特征图尺寸)。

本文链接地址:https://www.jiuchutong.com/zhishi/300079.html 转载请保留说明!

上一篇:Java Web中的ServletContext对象(java web中的转发和重定向)

下一篇:前端实现tab栏切换,这么常见的案例你学会了吗?(前端按钮跳转界面)

  • 华为手机怎么把小艺放到桌面(华为手机怎么把数据导入苹果手机)

    华为手机怎么把小艺放到桌面(华为手机怎么把数据导入苹果手机)

  • 苹果11pro反向充电怎么打开(iqoo11pro可以给苹果反向充电吗)

    苹果11pro反向充电怎么打开(iqoo11pro可以给苹果反向充电吗)

  • 路由器和无线路由器有区别吗(路由器和无线路由器可以分开吗)

    路由器和无线路由器有区别吗(路由器和无线路由器可以分开吗)

  • 美篇可以加音频吗(美篇可以加音频吗怎么弄)

    美篇可以加音频吗(美篇可以加音频吗怎么弄)

  • 快手拉黑再移出对方知道吗(快手拉黑再移出来就不是我的粉丝了)

    快手拉黑再移出对方知道吗(快手拉黑再移出来就不是我的粉丝了)

  • id被锁定是什么意思(id 被锁定)

    id被锁定是什么意思(id 被锁定)

  • 飞行模式怎么关闭(苹果飞行模式怎么关)

    飞行模式怎么关闭(苹果飞行模式怎么关)

  • 手机承载系统lte收费吗(手机承载系统lte打开好不好)

    手机承载系统lte收费吗(手机承载系统lte打开好不好)

  • ipad可以剪辑视频吗(ipad可以剪辑视频发抖音吗)

    ipad可以剪辑视频吗(ipad可以剪辑视频发抖音吗)

  • 微信记录跑步轨迹在哪里(微信记录跑步轨迹的软件哪个好)

    微信记录跑步轨迹在哪里(微信记录跑步轨迹的软件哪个好)

  • vivo手机充电保护在哪(vivo手机充电保护广告怎么关闭)

    vivo手机充电保护在哪(vivo手机充电保护广告怎么关闭)

  • 苹果最近通话删除找回(苹果最近通话删除了开机了之后又恢复了)

    苹果最近通话删除找回(苹果最近通话删除了开机了之后又恢复了)

  • win7专用版忘记密码怎么办(windows7专业版忘记密码怎么办)

    win7专用版忘记密码怎么办(windows7专业版忘记密码怎么办)

  • wifi6是wifi5的多少倍(wifi6是5gwifi吗)

    wifi6是wifi5的多少倍(wifi6是5gwifi吗)

  • 荣耀20和荣耀v20区别(荣耀20和荣耀v20一样吗)

    荣耀20和荣耀v20区别(荣耀20和荣耀v20一样吗)

  • 手机与电脑投屏怎么弄(手机与电脑投屏怎么投)

    手机与电脑投屏怎么弄(手机与电脑投屏怎么投)

  • 华为荣耀9x指纹在哪里(华为荣耀9x指纹识别地方烫手)

    华为荣耀9x指纹在哪里(华为荣耀9x指纹识别地方烫手)

  • 普通测厚仪怎么读数(测厚仪怎么样)

    普通测厚仪怎么读数(测厚仪怎么样)

  • 微信号被别人注册了怎么办(微信号被别人注销了怎么恢复)

    微信号被别人注册了怎么办(微信号被别人注销了怎么恢复)

  • 云闪付证件号关联超限(云闪付证件号关联用户个数)

    云闪付证件号关联超限(云闪付证件号关联用户个数)

  • ipada1670是几代(ipada1674是几代)

    ipada1670是几代(ipada1674是几代)

  • 苹果手机删了的软件怎么找回来(苹果手机删了的照片还能恢复吗知乎)

    苹果手机删了的软件怎么找回来(苹果手机删了的照片还能恢复吗知乎)

  • Windows 10如何设置默认视频播放器(windows10如何设置桌面背景)

    Windows 10如何设置默认视频播放器(windows10如何设置桌面背景)

  • windows无法验证此应用程序的许可证解决方法(windows无法验证此设备数字签名)

    windows无法验证此应用程序的许可证解决方法(windows无法验证此设备数字签名)

  • 由浅入深介绍 Python Websocket 编程(由浅入深英语怎么说)

    由浅入深介绍 Python Websocket 编程(由浅入深英语怎么说)

  • 印花税的征税对象是条例列举的凭证未列举的不征税
  • 留抵税额是什么意思啊
  • 税后净营业利润英文
  • 免税收入是什么票据类型
  • 如何自己开小公司
  • 电梯维保费属于建筑服务吗
  • 企业所得税成本调减怎么填
  • 低值易耗可以直接入管理费用吗
  • 进项税额转出忘记填在申报表里
  • 农业技术服务个人总结
  • 支票盖财务章盖在哪里
  • 计提存货跌价准备怎么计算
  • 核定征收企业股权转让所得税
  • 企业所得税的常设机构
  • 企业一直亏损但是汇算清缴调增
  • 土地转让合同也叫什么
  • 成品油进项税转出
  • 财务中预付账款是什么意思
  • 海关增值税进项转出
  • 房地产开发贷款管理办法
  • 专票红冲后的账务处理
  • 如何计算房地产容积率与土地面积
  • 个人所得税生产经营所得投资者减除费用
  • 生育津贴需要缴纳五险一金吗
  • 自产农产品销售怎么做账
  • 个人账户付款到对公账户
  • 企业微信收入也要交税吗
  • 应交增值税为负数代表什么
  • 苹果怎么充电更好
  • 个税是负数直接工资加上吗
  • 疫情期间企业贷款利率多少
  • 新办企业装修会计分录
  • 个人投资额是什么意思
  • 华硕笔记本装win8
  • 无形资产摊销是什么科目
  • 存货 计价
  • 电脑前面板耳机没声音怎么设置bios
  • 若依框架搭建
  • 若依前后端分离做的系统
  • 东京塔的意义
  • 财务比率分析的主要内容
  • 固定资产折旧企业所得税税前扣除标准
  • 一天看小说十几个小时的人
  • reactvate
  • php基于mcrypt_encrypt和mcrypt_decrypt实现字符串加密解密的方法
  • php生成文件函数
  • 母公司与子公司交易属于关联交易吗
  • 专用发票费率
  • 其他发票是什么意思
  • 劳务派遣差额征税的账务处理实例
  • 小规模纳税人增值税税率
  • 企业资产的范围
  • PostgreSql新手必学入门命令小结
  • sql server join
  • 销售增长率计算公式财务管理
  • 小微企业流转税优惠政策
  • 制造费用主要包括哪些内容
  • 不得从销项税额中抵扣的进项税额,不得计提加计抵减额
  • sqlserver表结构如何导入到oracle
  • mysql查询结果是什么类型
  • ms sql mysql
  • ubuntu系统怎么更新
  • win10mobile现在能干吗
  • xp系统怎么调性能
  • realshed.exe - realshed是什么进程 有什么用
  • perl处理特殊符号
  • quick3.3 UIListview扩展应用
  • ExtJS 2.0实用简明教程之应用ExtJS
  • Android游戏开发教程
  • javascript scrollTop正解使用方法
  • javascript函数自调用
  • shell发送邮件
  • nodejs搭建个人博客网站
  • python3+PyQt5实现使用剪贴板做复制与粘帖示例
  • python用装饰器自动注册Tornado路由详解
  • javascript面向对象 第三方类库
  • 广东省国家税务局网上办税大厅
  • 开票员怎么登录电子税务局进行开票验证
  • 建筑企业所交的税项有多少
  • 误餐费报销管理办法
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设