ASFF自适应空间特征融合

paper:Learning Spatial Fusion for Single-Shot Object Detection

official implementation:https://github.com/GOATmessi7/ASFF

背景

金字塔特征表示pyramid feature representation是解决目标检测中尺度变化挑战的常用方法。特征金字塔的一个主要缺点是在不同尺度上的不一致性,特别是对于one-shot detector。具体来说,当用feature pyramid检测物体时,采用一种启发式引导的特征选择:大目标与深层特征图关联,小目标与浅层特征图关联。当一个对象在某一层的特征图中被视为positive时,其它level的特征图中相应的区域就被视为背景。因此,如果一个图像既包含小物体又包含大物体,不同层次特征之间的冲突往往占据特征金字塔的主要部分。这种不一致性干扰了训练过程中的梯度计算,并降低了特征金字塔的有效性。

本文的创新点

本文提出了一种新的数据驱动的金字塔特征融合策略,称为自适应空间特征融合(adaptively spatial feature fusion, ASFF)。它学习对冲突信息进行空间过滤以抑制不一致性的方法,从而提高了特征的尺度不变性,并几乎没有增加额外开销。

该方法使网络能够直接学习如何在其它层对特征进行空间过滤,从而只保留有用信息进行融合。对于某个level的特征,首先将其它level的特征整合并调整到相同的分辨率,然后通过训练找到最优融合。在每个空间位置,不同level的特征被自适应的融合,即一些特征可能因为在该位置带有矛盾的信息而被过滤掉,一些特征因为带有更具差异性的信息而在该位置占主导。

ASFF具有以下几点优势

  1. 由于搜索最优融合的操作是可微的,因此可以在反向传播中学习
  2. 它对于backbone是不可知的,并应用于带有特征金字塔结构的单阶段目标检测模型中
  3. 实现简单,增加的计算成本可以忽略

方法介绍

Feature Resizing

我们将 \(l\) 层的特征记为 \(\mathbf{x}^{l}\)(对于YOLOv3 \(l\in\{1,2,3\}\))。对于层 \(l\),我们将其它层 \(n(n\ne l)\) 的特征 \(\mathbf{x}^n\) resize到和 \(\mathbf{x}^{l}\) 一样的分辨率。由于YOLOv3中三个level的特征具有不同的分辨率和不同的通道数,因此我们相应地修改了每个尺度的上采样和下采样策略。对于上采样,我们首先通过1x1卷积将特征的通道数压缩到 \(l\) 层对应的通道数,然后通过插值进行上采样。对于1/2比例的下采样,我们通过stride=2的3x3卷积通过修改分辨率和通道数。对于1/4的下采样,我们在2-stride卷积之前添加一个2-stride的max pooling层。

Adaptive Fusion

我们用 \(\mathbf{x}_{ij}^{n\to l}\) 表示从 \(n\) 层resize到 \(l\) 层的特征图上位置 \((i,j)\) 处的特征向量,我们在 \(l\) 层上按下式进行融合

其中 \(\mathbf{y}_{ij}^l\) 表示输出特征图 \(\mathbf{y}^l\) 沿通道的第 \((i,j)\) 个向量。\(\alpha_{ij}^l,\beta_{ij}^l,\gamma_{ij}^l\) 表示三个不同level对level \(l\) 特征图的空间重要性权重,它们是网络自适应学习到的。注意 \(\alpha_{ij}^l,\beta_{ij}^l,\gamma_{ij}^l\) 可以是标量变量,所有通道共享。我们使 \(\alpha_{ij}^l+\beta_{ij}^l+\gamma_{ij}^l=1\),\(\alpha_{ij}^l,\beta_{ij}^l,\gamma_{ij}^l\in [0,1]\),并定义

 

这里 \(\alpha_{ij}^l,\beta_{ij}^l,\gamma_{ij}^l\) 通过对 \(\lambda^{l}_{\alpha_{ij}},\lambda^{l}_{\beta_{ij}},\lambda^{l}_{\gamma_{ij}}\) 使用softmax计算得到,我们使用1x1卷积从 \(\mathbf{x}^{1\to l},\mathbf{x}^{2\to l},\mathbf{x}^{3\to l}\) 得到权重标量 \(\lambda^{l}_{\alpha},\lambda^{l}_{\beta},\lambda^{l}_{\gamma}\)。

使用这种方法,所有lelvel的特征都在每个尺度上自适应地聚合。输出 \(\{\mathbf{y}^1,\mathbf{y}^2,\mathbf{y}^3\}\) 按照YOLOv3相同的pipeline用于目标检测。

实验结果

 

代码

class ASFF(nn.Module):
    def __init__(self, level, rfb=False, vis=False):
        super(ASFF, self).__init__()
        self.level = level
        self.dim = [512, 256, 256]
        self.inter_dim = self.dim[self.level]
        if level == 0:
            self.stride_level_1 = add_conv(256, self.inter_dim, 3, 2)
            self.stride_level_2 = add_conv(256, self.inter_dim, 3, 2)
            self.expand = add_conv(self.inter_dim, 1024, 3, 1)
        elif level == 1:
            self.compress_level_0 = add_conv(512, self.inter_dim, 1, 1)
            self.stride_level_2 = add_conv(256, self.inter_dim, 3, 2)
            self.expand = add_conv(self.inter_dim, 512, 3, 1)
        elif level == 2:
            self.compress_level_0 = add_conv(512, self.inter_dim, 1, 1)
            self.expand = add_conv(self.inter_dim, 256, 3, 1)

        compress_c = 8 if rfb else 16  # when adding rfb, we use half number of channels to save memory

        self.weight_level_0 = add_conv(self.inter_dim, compress_c, 1, 1)
        self.weight_level_1 = add_conv(self.inter_dim, compress_c, 1, 1)
        self.weight_level_2 = add_conv(self.inter_dim, compress_c, 1, 1)

        self.weight_levels = nn.Conv2d(compress_c*3, 3, kernel_size=1, stride=1, padding=0)
        self.vis = vis

    def forward(self, x_level_0, x_level_1, x_level_2):  # (b,512,13,13),(b,256,26,26),(b,256,52,52)
        if self.level == 0:
            level_0_resized = x_level_0
            level_1_resized = self.stride_level_1(x_level_1)  # (b,512,13,13)

            level_2_downsampled_inter = F.max_pool2d(x_level_2, 3, stride=2, padding=1)  # (b,256,26,26)
            level_2_resized = self.stride_level_2(level_2_downsampled_inter)  # (b,512,13,13)
        elif self.level == 1:
            level_0_compressed = self.compress_level_0(x_level_0)  # (b,256,13,13)
            level_0_resized = F.interpolate(level_0_compressed, scale_factor=2, mode='nearest')  # (b,256,26,26)
            level_1_resized = x_level_1
            level_2_resized = self.stride_level_2(x_level_2)  # (b,256,26,26)
        elif self.level == 2:
            level_0_compressed = self.compress_level_0(x_level_0)  # (b,256,13,13)
            level_0_resized = F.interpolate(level_0_compressed, scale_factor=4, mode='nearest')  # (b,256,52,52)
            level_1_resized = F.interpolate(x_level_1, scale_factor=2, mode='nearest')  # (b,256,52,52)
            level_2_resized = x_level_2

        level_0_weight_v = self.weight_level_0(level_0_resized)  # (b,16,13,13)
        level_1_weight_v = self.weight_level_1(level_1_resized)  # (b,16,13,13)
        level_2_weight_v = self.weight_level_2(level_2_resized)  # (b,16,13,13)
        levels_weight_v = torch.cat((level_0_weight_v, level_1_weight_v, level_2_weight_v), 1)  # (b,48,13,13)
        levels_weight = self.weight_levels(levels_weight_v)  # (b,3,13,13)
        levels_weight = F.softmax(levels_weight, dim=1)

        fused_out_reduced = level_0_resized * levels_weight[:, 0:1, :, :] + \
                            level_1_resized * levels_weight[:, 1:2, :, :] + \
                            level_2_resized * levels_weight[:, 2:, :, :]

        out = self.expand(fused_out_reduced)  # (b,1024,13,13)

        if self.vis:
            return out, levels_weight, fused_out_reduced.sum(dim=1)
        else:
            return out

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring Cloud项目整合Sentinel及简单使用

说明:Sentinel是阿里巴巴开发的微服务治理中间件,可用于微服之间请求的流量管控、权限控制、熔断降级等场景。本文介绍如何在Spring Cloud项目中整合Sentinel,以及Sentinel的简单使用。 环境 首先搭建一个简单的微服务环境,有以…

Linux下的编辑器——Vim

vi/vim 的区别简单点来说,它们都是多模式编辑器,不同的是 vim 是 vi 的升级版本,它不仅兼容 vi 的所有指令,而且还有一些新的特性在里面。例如语法加亮,可视化操作不仅可以在终端运行,也可以运行于x window…

【数据结构】详解线性表的各个函数接口+OJ习题讲解(画图比写代码更重要!!!)

文章目录 一、线性表二、顺序表1、什么是顺序表2、顺序表的分类 三、动态顺序表的实现1、结构的定义2、顺序表的初始化3、检查容量4、在头部插入数据5、在尾部插入数据6、在指定位置插入数据7、在尾部删除数据8、在头部删除数据9、删除指定位置的数据10、查找数据11、修改指定位…

2024 年 2 月公链行业研报

作者:stellafootprint.network 数据来源:Footprint Analytics 公链研究页面 二月份,加密货币市场展现出强劲的上涨势头,这主要得益于比特币和以太坊的价值大幅上涨超过 45%。这一乐观态势也影响到其他代币,前十大代币…

iOS 判断触摸位置是否在图片的透明区域

装扮功能系列: Swift 使用UIScrollerView 实现装扮功能(基础)Swift 使用UIScrollerView 实现装扮功能(拓展)iOS 判断触摸位置是否在图片的透明区域 背景 在装扮功能中,一般都是长按使道具进入编辑状态&…

安装MySQL8.0及以上版本操作步骤

关于mysql安装过程中命令mysqld --initialize --console出错的解答 C:\mysql-8.3.0-winx64\bin>mysqld --initialize --usermysql --console 2024-03-12T11:21:23.201387Z 0 [System] [MY-015017] [Server] MySQL Server Initialization - start. 2024-03-12T11:21:23.2068…

【C语言】字符串函数上

👑个人主页:啊Q闻 🎇收录专栏:《C语言》 🎉道阻且长,行则将至 前言 这篇博客是字符串函数上篇,主要是关于长度不受限制的字符串函数(strlen,strcpy,strcat,strcm…

报错:Nginx 部署后刷新页面 404 问题

文章目录 问题分析解决 问题 在部署完项目后 刷新页面,页面进入了404 分析 加载单页应用后路由改变均由浏览器处理,而刷新时将会请求当前的链接,而Nginx无法找到对应的页面 关键代码try_files,剩下俩如果其他地方配置了则可以省略。 在这…

网络安全等级测评师考试培训可以参考哪些资料?

网络安全是国家安全的重要组成部分,也是企业安全的重中之重;而网络安全等级测评师则是守护这一安全领域的重要力量。所以专业的网络安全等级测评师是非常重要。作为专业的网络安全等保测评师,他们肩负着对信息系统进行安全评估、发现潜在风险…

三星泄露微软 Copilot 新功能:用自然语言操控各种功能

3 月 11 日消息,微软计划本月晚些时候发布新款 Surface 电脑和适用于 Windows 11 的 Copilot 新功能,但三星似乎等不及了,在其即将推出的 Galaxy Book4 系列产品宣传材料中泄露了一些即将到来的 Copilot 功能。 三星官网上发布的图片证实了此…

leetcode刷题(javaScript)——堆相关场景题总结

堆是什么?堆都能用树表示,并且一般树的实现都是利用链表。平时使用的最多的是二叉堆,它可以用完全二叉树表示,二叉堆易于存储,并且便于索引。在堆的实现时注意:因为是数组,所以父子节点的关系就…

【智能算法】蝠鲼觅食优化算法(MRFO)原理及实现

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.代码实现4.参考文献 1.背景 2017年,Zhao等人受到蝠鲼自然捕食行为启发,提出了蝠鲼觅食优化算法(Manta Ray Foraging Optimization,MRFO)。 2.算法原理 2.1算法思想 MRFO模拟了蝠鲼在海洋中…

54、WEB攻防——通用漏洞跨域CORS资源JSONP回调域名接管劫持

文章目录 同源策略CORSJSONP跨域回调子域名劫持 同源策略 同源策略包括三个条件:同域名、同域名、同端口。同源策略限制从一个源加载的文档或脚本与来自另一个源的资源进行交互。 CORS CORS(跨域资源共享)已被所有浏览器支持,跨…

简单了解 vim 编辑器最基础的操作

简单了解 vim 编辑器最基础的操作 vim 这个是 Linux 上自带的一个文本编辑器,使用 vim 就可以更灵活的对文件进行编辑了(虽然和记事本的定位差不多,实际上vim的使用要复杂很多) 1.打开文件 语法:vim 文件名 示例:…

简单理解NAT模式和桥接模式

目录 桥接模式NAT模式总结 桥接模式 1.桥接模式下 当物理机X创建了一台或多台虚拟机 那么这些创建出来的虚拟机 可以视作一台独立的新机器 加入了该局域网 并允许和该局域网的物理机或者其他虚拟机直接通信 2.问题一在于 C类网的分配是有范围的(0-255) 假如是一个教室里的局域…

智慧公厕建设,助力打造宜居、韧性、可持续的智慧城市

公共厕所作为智慧城市的重要组成部分,对于城市的高质量发展起着至关重要的作用。智慧公厕建设旨在通过全面监测、控制和管理公共厕所,实现多方面功能,包括公共厕所环境监测与调控、厕位占用监测与引导、消耗品监测与缺失提示、安全防范与管理…

WPF监控平台(科技大屏)[一]

跟着B站的视频敲了一个略微复杂的WPF界面,链接如下.在这里我详细的写一份博客进行设计总结. 系统介绍和配置及主窗口设计_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Wy421Y7QD?p1&vd_source4796b18a2e4c1ec8a310391a5644b6da 成果展示 实现过程 总体来说,我的…

Shell常用脚本:hadoop集群启动、停止、重启脚本

脚本内容以我搭建的hadoop集群为例,你们自用的时候自行根据你们的情况进行修改即可 hadoop-cluster-manager.sh #!/bin/bash # 1. 调用此脚本前,请使用ssh-keygen -t rsa、ssh-copy-id -f 目标机器这两个命令使得目标机器是免密登录的 # 2. ssh远程执行…

Linux常用操作命令和服务器硬件基础知识

🌟 前言 欢迎来到我的技术小宇宙!🌌 这里不仅是我记录技术点滴的后花园,也是我分享学习心得和项目经验的乐园。📚 无论你是技术小白还是资深大牛,这里总有一些内容能触动你的好奇心。🔍 &#x…

嵌入式学习day37 数据结构

1.sqlite3_open int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */ ); 功能: 打开数据库文件(创建一个数据库连接) 参数: filename:数据库文…