Nas-FPN(CVPR 2019)原理与代码解析

paper:NAS-FPN: Learning Scalable Feature Pyramid Architecture for Object Detection

third-party implementation:https://github.com/open-mmlab/mmdetection/tree/main/configs/nas_fpn

本文的创新点

本文采用神经网络结构搜索(Neural Architecture Search, NAS),在一个覆盖所有跨尺度连接的新型可扩展搜索空间中发现了一个新的特征金字塔结构,NAS-FPN。与原始FPN相比,NAS-FPN显著提高了目标检测的性能,并取得了更好了速度-精度的平衡。

方法介绍

考虑到其简单而高效的结构,目标检测模型采用RetinaNet,如图2所示

作者提出了merging cell作为FPN的basic building block,将任何两层的输入特征融合为一层的输出特征。如图3所示

其中Binary Op包括两种候选方案,如图4所示 

最终搜索到的NAS-FPN的完整结构如图6所示 

图7展示的搜索到的所有结构,其中(a)是原始FPN结构,(b)-(f)的精度逐渐变高,(f)是最终的NAS-FPN结构。

因为是搜索到的结构,并且图示非常清晰,这里就不过多介绍具体结构了。接下来结合代码和图(6)(7)的结构介绍一下实现细节 

代码解析

这里以mmdetection中的实现为例,实现代码在mmdet/models/necks/nas_fpn.py中,下面是完整的forward函数。其中self.fpn_stages=7是nas-fpn重复的次数,每个nas-fpn的输出是下一个nas-fpn的输入。forward最开始的输入是backbone的输出C2~C5,这里只取C3~C5通过lateral_conv得到P3~P5,然后进行下采样得到P6和P7,完整的P3~P7作为第一个nas-fpn的输入。

def forward(self, inputs: Tuple[Tensor]) -> tuple:# [(8,256,160,160),#  (8,512,80,80),#  (8,1024,40,40),#  (8,2048,20,20)]"""Forward function.Args:inputs (tuple[Tensor]): Features from the upstream network, eachis a 4D-tensor.Returns:tuple: Feature maps, each is a 4D-tensor."""# build P3-P5feats = [lateral_conv(inputs[i + self.start_level])for i, lateral_conv in enumerate(self.lateral_convs)]  # [(8,256,80,80),(8,256,40,40),(8,256,20,20)]# build P6-P7 on top of P5for downsample in self.extra_downsamples:feats.append(downsample(feats[-1]))  # [..., (8,256,10,10),(8,256,5,5)]p3, p4, p5, p6, p7 = featsfor stage in self.fpn_stages:# gp(p6, p4) -> p4_1# print(stage['gp_64_4'])p4_1 = stage['gp_64_4'](p6, p4, out_size=p4.shape[-2:])  # (8,256,40,40)# sum(p4_1, p4) -> p4_2p4_2 = stage['sum_44_4'](p4_1, p4, out_size=p4.shape[-2:])  # (8,256,40,40)# sum(p4_2, p3) -> p3_outp3 = stage['sum_43_3'](p4_2, p3, out_size=p3.shape[-2:])  # (8,256,80,80)# sum(p3_out, p4_2) -> p4_outp4 = stage['sum_34_4'](p3, p4_2, out_size=p4.shape[-2:])  # (8,256,40,40)# sum(p5, gp(p4_out, p3_out)) -> p5_outp5_tmp = stage['gp_43_5'](p4, p3, out_size=p5.shape[-2:])  # (8,256,20,20)p5 = stage['sum_55_5'](p5, p5_tmp, out_size=p5.shape[-2:])  # (8,256,20,20)# sum(p7, gp(p5_out, p4_2)) -> p7_outp7_tmp = stage['gp_54_7'](p5, p4_2, out_size=p7.shape[-2:])  # (8,256,5,5)p7 = stage['sum_77_7'](p7, p7_tmp, out_size=p7.shape[-2:])  # (8,256,5,5)# gp(p7_out, p5_out) -> p6_outp6 = stage['gp_75_6'](p7, p5, out_size=p6.shape[-2:])  # (8,256,10,10)return p3, p4, p5, p6, p7

在for循环中,从上到到下分别对应图6中从左到右按顺序所有的GP和Sum。其中GP对应GlobalPoolingCell,Sum对应SumCell,具体实现都在MMCV中。

GlobalPoolingCell的实现如下,其中self.input1_conv和self.input2_conv是空的,self._resize通过双线性插值进行上采样,通过max pooling进行下采样。

def forward(self,x1: torch.Tensor,x2: torch.Tensor,out_size: Optional[tuple] = None) -> torch.Tensor:assert x1.shape[:2] == x2.shape[:2]assert out_size is None or len(out_size) == 2if out_size is None:  # resize to larger oneout_size = max(x1.size()[2:], x2.size()[2:])x1 = self.input1_conv(x1)x2 = self.input2_conv(x2)x1 = self._resize(x1, out_size)x2 = self._resize(x2, out_size)x = self._binary_op(x1, x2)if self.with_out_conv:x = self.out_conv(x)return x

self._binary_op的实现如下,其中self.global_pool是全局平均池化。

def _binary_op(self, x1, x2):x2_att = self.global_pool(x2).sigmoid()return x2 + x2_att * x1

最后的self.out_conv是Conv+BN+ReLU的组合,对应图6中的R-C-B。注意图6中只有第一个GP和最后一个GP后有R-C-B,中间两个GP后没有,即上面代码中self.with_out_conv=False。

SumCell和GlobalPoolingCell继承自同一个基类,forward函数是一样的。区别在于SumCell中的self._binary_op就是sum操作,如下

class SumCell(BaseMergeCell):def __init__(self, in_channels: int, out_channels: int, **kwargs):super().__init__(in_channels, out_channels, **kwargs)def _binary_op(self, x1, x2):return x1 + x2

此外,5个SumCell后都有R-C-B。

实验结果

和其他SOTA模型的对比如表1所示

其中7@256表示NAS-FPN堆叠7次,通道数为256。

文中特别提到由于NAS-FPN的结构堆叠多层引入了更多的参数,需要一个合适的正则化方法来防止过拟合。本文采用DropBlock,具体介绍见DropBlock(NeurIPS 2018)论文与代码解析-CSDN博客。图10展示了DropBlock显著提升了NAS-FPN的性能。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ctfshow-反序列化(web267-web270)

目录 web267 web268 web269 web270 总结 web267 页面用的什么框架不知道 看源码看一下 框架就是一种软件工具,它提供了一些基础功能和规范,可以帮助开发者更快地构建应用程序。比如Yii框架和ThinkPHP框架就是两个流行的PHP框架,它们提供…

SpringBoot集成mybatis时idea控制台中文乱码问题解决

在application.yml中配置好映射文件打印数据库日志文件时,控制台出现乱码的情况解决如下 问题 在执行查询操作的时候,查询时可以查看是没有问题的,但是控制台乱码了 解决 在File-Setting-Editor-File Encodings中设置如图所示就可以了 现在…

激光无人机打击系统——光束控制和指向系统

激光无人机(UAV)打击系统中的光束控制和指向系统通常包括以下几个关键组件和技术: 激光发射器:这是系统的核心,负责生成高能量的激光束。常用的激光类型包括固体激光器、化学激光器、光纤激光器等,选择取决…

Hive-SQL语法大全

Hive SQL 语法大全 基于语法描述说明 CREATE DATABASE [IF NOT EXISTS] db_name [LOCATION] path; SELECT expr, ... FROM tbl ORDER BY col_name [ASC | DESC] (A | B | C)如上语法,在语法描述中出现: [],表示可选,如上[LOCATI…

学单片机前先学什么?

学单片机前先学什么? 在开始前我有一些资料,是我根据网友给的问题精心整理了一份「单片机的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!&#xff…

[计算机网络]基本概念

目录 1.ip地址和端口号 1.1IP地址 1.2端口号 2.认识协议 2.1概念: 2.2知名协议的默认端口 3.五元组 4.协议分层 4.1分层的作用 4.2OSI七层模型 4.3TCP/IP五层(四层)模型 ​编辑4.4网络设备对应的分层: ​编辑以下为跨…

使用PHP自定义一个加密算法,实现编码配合加密,将自己姓名的明文加密一下

<meta charset"UTF-8"> <?phpfunction customEncrypt($lin, $key mySecretKey){// 定义一个简单的替换规则$li array(L > M, I > Y, Y > O, A > N, E > Q, );$yan ;for($i 0; $i < strlen($lin); $i){$char $lin[$i];if(isset($li[…

这才是问界M9惊艳到你的10大配置

文 | AUTO芯球 作者 | 李诞 盘点M9的十项科技&#xff0c;看看有没有惊艳到你&#xff1f; 一、猫头转向&#xff0c;5米2的大型SUV转弯可5.8米&#xff0c; 比很多我们的额家用小车的转弯半径都小&#xff0c;好开。 二、大灯抠图&#xff0c;夜晚开启大灯可以不晃对面车的…

Python列表与元组

Python 列表和元组是Python编程语言中两种重要的数据结构&#xff0c;它们在实际的编程中扮演着不可或缺的角色。本文将深入探讨Python列表和元组的特性、用法以及它们之间的区别&#xff0c;帮助读者更好地理解和运用这两种数据结构。 Python 列表 Python 列表是一种有序、可…

SpringBoot+Vue充电桩管理系统 附带详细运行指导视频

文章目录 一、项目演示二、项目介绍三、运行截图四、主要代码1. 分页获取预约数据代码2.保存预约信息代码3.修改订单状态代码 一、项目演示 项目演示地址&#xff1a; 视频地址 二、项目介绍 项目描述&#xff1a;这是一个基于SpringBootVue框架开发的充电桩管理系统。首先&…

postgresql(Windows)初始化数据库教程

省流&#xff1a;本文章内容讲的是如何初始化postgresql数据库环境&#xff0c;前提是已经安装好postgresql数据库&#xff0c;安装步骤参考postgresql&#xff08;Windows&#xff09;安装教程 # 开始&#xff1a;安装postgresql-12.14-2-windows-x64.exe完成后进行初始化数据…

指针-回调函数

回调函数的含义 回调函数通常作为参数传递给其他函数&#xff0c;它是一个通过函数指针调用的函数。简单来说这个函数的作用就是用来在特殊的条件满足时用来调用其他函数的一个函数。 回调函数的使用 当相同或者相似的函数出现多份的时候&#xff0c;那么由于相同的部分出现…

【后端技术】术有千法,道本归一

目录 1.概述 2.机器的问题 2.1.计算 2.2.存储 2.3.传输 3.人的问题 3.1.代码工程的管理 3.2.过程的把控 4.总结 1.概述 术有千法&#xff0c;道本归一。 之所以这样说&#xff0c;是因为当前出现的纷繁复杂的后端技术&#xff0c;其本质其实都是为了解决同一套问题。…

Node.JS CreateWriteStream(大容量写入文件流优化)

Why I Need Node.JS Stream 如果你的程序收到以下错误&#xff0c;或者需要大容量写入很多内容(几十几百MB甚至GB级别)&#xff0c;则必须使用Stream文件流甚至更高级的技术。 Error: EMFILE, too many open files 业务场景&#xff0c;我们有一个IntradayMissingRecord的补…

Webpack5 基本使用 - 3(完结)

环境区分 可以定义多个配置文件&#xff0c;通过 webpack-merge 合并配置文件。 安装 webpack-merge yarn add webpack-merge公共配置 // webpack.common.js const path require(path) const HtmlWebpackPlugin require(html-webpack-plugin)module.exports {entry: path…

Spring第七天(AOP)

简介 AOP(Aspect Oriented Programing)面向切面编程&#xff0c;一种编程范式&#xff0c;指导开发者如何组织程序结构 作用 在不惊动原始设计的基础上为其进行功能增强 Spring理念&#xff1a;无入侵式/无侵入式 基本概念 连接点(JoinPoint) : 程序执行过程中的任意位置&a…

5分钟做自己的微信红包封面

文章目录 怎么制作自己的红包封面&#xff1f;开通红包封面的要求如下&#xff1a;收费情况制作具体网站&#xff1a;https://chatapi.onechat.fun/register?affYoU6 提交审核logo封面、挂件、气泡证明材料 发放红包封面其他 怎么制作自己的红包封面&#xff1f; 开通红包封面…

离了个大谱,只因外貌被换角?

♥ 为方便您进行讨论和分享&#xff0c;同时也为能带给您不一样的参与感。请您在阅读本文之前&#xff0c;点击一下“关注”&#xff0c;非常感谢您的支持&#xff01; 文 |猴哥聊娱乐 编 辑|徐 婷 校 对|侯欢庭 电视剧选角也能如此抓马&#xff0c;真是让人大开眼界。还没开…

开始学习Vue2(脚手架,组件化开发)

一、单页面应用程序 单页面应用程序&#xff08;英文名&#xff1a;Single Page Application&#xff09;简 称 SPA&#xff0c;顾名思义&#xff0c;指的是一个 Web 网站中只有唯一的 一个 HTML 页面&#xff0c;所有的功能与交互都在这唯一的一个页面内完成。 二、vue-cli …

mp4文件可以转成mp3音频吗

现在是个非常流行刷短视频一个年代&#xff0c;刷短视似乎成了人们休闲娱乐的一种方式&#xff0c;在日常刷短视频过程中&#xff0c;肯定会有很多同学被短视频 bgm 神曲洗脑&#xff0c;比如很多被网红翻唱带火的歌曲&#xff0c;例如其中"不负人间”&#xff0c;就是其中…