【mmdetection代码解读 3.x版本】FPN层的解读

news2024/11/26 0:23:16

文章目录

    • 1. forward函数
      • 1.1 self.fpn_convs的构建

1. forward函数

def forward(self, inputs: Tuple[Tensor]) -> tuple:

在这里插入图片描述

assert len(inputs) == len(self.in_channels)

# build laterals
laterals = [
    lateral_conv(inputs[i + self.start_level])
    for i, lateral_conv in enumerate(self.lateral_convs)
]

查输入特征 inputs 的数量是否等于定义的 self.in_channels 中的通道数
构建特征金字塔网络中的侧边连接

在这里插入图片描述
在这里插入图片描述

used_backbone_levels = len(laterals)
for i in range(used_backbone_levels - 1, 0, -1):
    # In some cases, fixing `scale factor` (e.g. 2) is preferred, but
    #  it cannot co-exist with `size` in `F.interpolate`.
    if 'scale_factor' in self.upsample_cfg:
        # fix runtime error of "+=" inplace operation in PyTorch 1.10
        laterals[i - 1] = laterals[i - 1] + F.interpolate(
            laterals[i], **self.upsample_cfg)
    else:
        prev_shape = laterals[i - 1].shape[2:]
        laterals[i - 1] = laterals[i - 1] + F.interpolate(
            laterals[i], size=prev_shape, **self.upsample_cfg)

取了实际用于 top-down 路径的侧边连接的数量
循环,从最顶层的侧边连接开始向下构建 top-down 路径:
	条件判断,检查是否设置了 'scale_factor'
	根据上一层的尺寸,使用 F.interpolate 对下一层的侧边连接进行上采样,然后将两层的特征相加

在这里插入图片描述

outs = [
         self.fpn_convs[i](laterals[i]) for i in range(used_backbone_levels)
        ]

通过对输入的侧边连接 laterals 进行卷积操作,生成用于网络输出的特征图 outs

在这里插入图片描述

 if self.num_outs > len(outs):
     # use max pool to get more levels on top of outputs
     # (e.g., Faster R-CNN, Mask R-CNN)
     if not self.add_extra_convs:
         for i in range(self.num_outs - used_backbone_levels):
             outs.append(F.max_pool2d(outs[-1], 1, stride=2))
     # add conv layers on top of original feature maps (RetinaNet)
     else:
         if self.add_extra_convs == 'on_input':
             extra_source = inputs[self.backbone_end_level - 1]
         elif self.add_extra_convs == 'on_lateral':
             extra_source = laterals[-1]
         elif self.add_extra_convs == 'on_output':
             extra_source = outs[-1]
         else:
             raise NotImplementedError
         outs.append(self.fpn_convs[used_backbone_levels](extra_source))
         for i in range(used_backbone_levels + 1, self.num_outs):
             if self.relu_before_extra_convs:
                 outs.append(self.fpn_convs[i](F.relu(outs[-1])))
             else:
                 outs.append(self.fpn_convs[i](outs[-1]))
 return tuple(outs)

检查是否需要在 outs 中添加额外的层级,以确保输出的特征图数量达到 self.num_outs
如果 self.add_extra_convs 参数设置为 False:
	使用最大池化来生成额外的输出层级,F.max_pool2d 用于对 outs 中的最后一层进行最大池化,将分辨率减半
如果 self.add_extra_convs 参数设置为其他值:
	根据 self.add_extra_convs 的设置,选择额外层级的输入来源
	使用 self.fpn_convs 中的卷积层对额外层级的输入 extra_source 进行处理,生成一个额外的输出层级
	如果仍然需要更多的输出层级,进行循环操作:
		检查是否在额外卷积前应用了 ReLU 激活函数,如果是:
			将 ReLU 激活函数应用于前一个输出层级 的特征图,并使用 self.fpn_convs[i] 中的卷积层进行处理
		如果没有应用 ReLU:
			将前一个输出层级 outs[-1] 直接送入 self.fpn_convs[i] 中的卷积层进行处理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


1.1 self.fpn_convs的构建

self.lateral_convs = nn.ModuleList()
self.fpn_convs = nn.ModuleList()

for i in range(self.start_level, self.backbone_end_level):
    l_conv = ConvModule(
        in_channels[i],
        out_channels,
        1,
        conv_cfg=conv_cfg,
        norm_cfg=norm_cfg if not self.no_norm_on_lateral else None,
        act_cfg=act_cfg,
        inplace=False)
    fpn_conv = ConvModule(
        out_channels,
        out_channels,
        3,
        padding=1,
        conv_cfg=conv_cfg,
        norm_cfg=norm_cfg,
        act_cfg=act_cfg,
        inplace=False)

    self.lateral_convs.append(l_conv)
    self.fpn_convs.append(fpn_conv)

创建了一个空的 PyTorch 模块列表,用于存储侧边连接的卷积层
创建了另一个空的 PyTorch 模块列表,用于存储上采样卷积层
通过循环,对从 self.start_level 到 self.backbone_end_level - 1:
	l_conv 是一个 1x1 卷积层,用于对输入特征进行降维,将通道数从输入级别的 in_channels[i] 减少到 out_channels
	fpn_conv 是一个 3x3 卷积层,用于对输入特征进行上采样
	将侧边连接卷积层 l_conv 添加到 lateral_convs 模块列表中
	将上采样卷积层 fpn_conv 添加到 fpn_convs 模块列表中
extra_levels = num_outs - self.backbone_end_level + self.start_level
if self.add_extra_convs and extra_levels >= 1:
    for i in range(extra_levels):
        if i == 0 and self.add_extra_convs == 'on_input':
            in_channels = self.in_channels[self.backbone_end_level - 1]
        else:
            in_channels = out_channels
        extra_fpn_conv = ConvModule(
            in_channels,
            out_channels,
            3,
            stride=2,
            padding=1,
            conv_cfg=conv_cfg,
            norm_cfg=norm_cfg,
            act_cfg=act_cfg,
            inplace=False)
        self.fpn_convs.append(extra_fpn_conv)

计算需要添加的额外级别数量
检查是否需要添加额外级别并且是否有至少一个额外级别要添加:
	循环遍历要添加的每个额外级别:
		在第一个额外级别时,检查配置是否要将额外级别卷积添加到输入上:
			将额外级别卷积添加到输入级别上
		否则:
			设置输入通道数等于输出通道数。这是因为额外级别的输入是上一个额外级别的输出
			extra_fpn_conv 是一个额外级别的卷积层。它是一个 3x3 大小的卷积核,带有 2 的步长,用于将上一个级别的特征图上采样
		将额外级别的卷积层添加到 fpn_convs 模块列表中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1089616.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QMidi Pro for Mac:打造您的专属卡拉OK体验

你是否曾经厌倦于在KTV里与朋友们争夺麦克风?是否想要在家中享受自定义的卡拉OK体验?现在,有了QMidi Pro for Mac,一切变得简单而愉快! QMidi Pro是一款功能强大的卡拉OK播放器,专为Mac用户设计。它充分利…

机器学习(二)什么是机器学习

文章目录 什么是机器学习1.4.1确定是否为机器学习问题 1.5基于规则学习和基于模型的学习1.5.1基于规则学习1.5.2基于模型学习1.5.3房价预测问题 1.6机器学习数据的基本概念1.6.1机器学习数据集基本概念强化实践 后记 什么是机器学习 在开始讲解术语概念之前我们首先梳理下之前…

互联网Java工程师面试题·Java 并发编程篇·第三弹

目录 26、什么是线程组,为什么在 Java 中不推荐使用? 27、为什么使用 Executor 框架比使用应用创建和管理线程好? 27.1 为什么要使用 Executor 线程池框架 27.2 使用 Executor 线程池框架的优点 28、java 中有几种方法可以实现一个线程…

天猫用户重复购买预测(速通二)

天猫用户重复购买预测(二) 模型训练分类相关模型1、逻辑回归分类模型2、K近邻分类模型3、高斯贝叶斯分类模型4、决策树分类模型5、集成学习分类模型 模型验证模型验证指标 特征优化特征选择技巧1、搜索算法2、特征选择方法 模型训练 分类相关模型 1、逻…

基于Springboot实现商务安全邮箱邮件收发系统项目【项目源码+论文说明】

基于Springboot实现商务安全邮箱邮件收发系统演示 摘要 随着社会的发展,社会的方方面面都在利用信息化时代的优势。计算机的优势和普及使得商务安全邮箱的开发成为必需。 本文以实际运用为开发背景,运用软件工程原理和开发方法,采用jsp技术…

Altium Designer | 5 - 网表导入及模块化布局设计(待续)

导入常见报错解决办法(unknow pin及绿色报错等) 在原理图界面 CtrlF搜索元器件位号 在PCB界面,CtrlF是左右翻转, 快捷键JC才是搜索元器件位号 报错信息: Unknow pin 1.没有封装 2.封装管脚缺失 3.元件库对应的管脚不对 ... 常见绿色报…

一键部署开源AI(人工智能对话模型)(支持显卡或CPU加内存运行)--ChatGLM2-6B

一、基本介绍: ChatGLM2-6B 是开源中英双语对话模型 ChatGLM-6B 的第二代版本,在保留了初代模型对话流畅、部署门槛较低等众多优秀特性的基础之上,ChatGLM2-6B 引入了如下新特性: 更强大的性能: 基于 ChatGLM 初代模…

盘点15个前端开源项目,yyds!

目录 1、vue-color-avatar2、Reader3、Ant Design4、小游戏2048(Vue版)5、跳一跳6、lifeRestart(人生重开模拟器)7、GOVIEW8、vlife9、网易云音乐 API10、饿了么11、QQ音乐 API12、ChatGPT API13、Node.js 最佳实践14、Awesome No…

云计算革命:多云管理与混合云的实践指南

文章目录 云计算的演进多云管理的优势1. 降低风险2. 提高性能3. 降低成本4. 提高安全性 实践指南1. 选择适当的云提供商2. 使用云管理平台3. 实施一致的安全策略4. 数据管理和迁移5. 自动化和编排 混合云的实践1. 私有云和本地数据中心2. 数据一致性3. 安全性和合规性4. 负载均…

IDEA启动报错Failed to create JVM. JVM path的解决办法

今天启动IDEA时IDEA报错,提示如下。 if you already hava a JDK installed, define a JAVA_HOME variable in Computer > Systen Properties > System Settings > Environment Variables.Failed to create JVM. JVM path:D:\ideaIU2023.2.3\IntelliJ IDE…

表单页面风格如何选择?弹窗 or 抽屉 or 页面?

一、类型介绍 在 PC 端项目中,用户触发了某个操作,当需要向用户展示新的内容时,有很多交互方式,弹窗、抽屉、页面就是其中典型的3种。下面来分析下3种交互方式的优势、劣势和使用场景。 1.1 弹窗 定义:分为模态和非模态对话框2种,常用的为模态对话框。 优势:在不离开…

AI项目十六:YOLOP 训练+测试+模型评估

若该文为原创文章,转载请注明原文出处。 通过正点原子的ATK-3568了解到了YOLOP,这里记录下训练及测试及在onnxruntime部署的过程。 步骤:训练->测试->转成onnx->onnxruntime部署测试 一、前言 YOLOP是华中科技大学研究团队在2021年…

2023软件测试面试题(亲身经历)

在职,5年测试经验,坐标广州,有点想666。于是进行了几场线上面试… 1、python有哪些数据类型 数字型:int/float/bool/complex 字符串:str 列表:list 元组:tuple 字典:dict 集合&…

云原生应用安全性:解锁云上数据的保护之道

文章目录 云原生应用的崛起云原生应用安全性挑战1. **容器安全性**:容器技术如Docker和Kubernetes已成为云原生应用的核心组成部分。容器的安全性变得至关重要,以防止恶意容器的运行和敏感数据泄漏。2. **微服务安全性**:微服务架构引入了多个…

从零开始使用webpack搭建一个react项目

先做一个正常编译es6语法的webpack demo 1. 初始化package.json文件 npm init一路enter下去 2. 添加插件 {"name": "demo","version": "1.0.0","description": "","main": "index.js",&q…

Springboot利用CompletableFuture异步执行线程(有回调和无回调)

目录 背景 实现 一、异步线程配置类 二、自定义异步异常统一处理类 三、实现调用异步(无回调-runAsync()) 四、实现调用异步(有回调-supplyAsync()) 五、异步执行错误异常示例 背景 项目中总会有需要异步执行来避免浪费…

Windows中将tomcat以服务的形式安装,然后在服务进行启动管理

Windows中将tomcat以服务的形式安装,然后在服务进行启动管理 第一步: 在已经安装好的tomcat的bin目录下: 输入cmd,进入命令窗口 安装服务: 输入如下命令,最后是你的服务名,避免中文和特殊字符 service.…

Redis数据类型及命令

目录 (一)通用命令(二)String类型(三)Hash类型(四)List类型(五)Set类型(六)SortedSet类型 在redis命令行查询redis通用命令&#xff1…

如何使用摩尔信使MThings连接网络设备

帽子: 摩尔信使MThings支持Modbus-TCP、Modbus-RTU Over TCP、Modbus-TCP Over UDP、Modbus-RTU Over UDP。 TCP链接中,摩尔信使MThings支持灵活的连接方式,主机可作为客户端也可以作为服务端,同时支持模拟从机以客户端方式向远…

1600*C. Add One(数位DP找规律)

Problem - 1513C - Codeforces 解析: 考虑DP,DP[ i ] 为从 0 开始执行 i 次操作,此时数字的位数。 我们发现当一个9再操作一次就会变成1和0,并且相邻的大部分长度都不会变化,0会影响10次操作之后的位数,1会…