DaViT(ECCV 2022,Microsoft)

paper:DaViT: Dual Attention Vision Transformers

official implementation:https://github.com/dingmyu/davit

third-party implementation:https://github.com/huggingface/pytorch-image-models/blob/main/timm/models/davit.py

出发点

现有的视觉Transformer在捕捉全局上下文和计算效率之间存在权衡。传统的方法在像素级或patch级别进行自注意力计算,要么带来高计算开销,要么丧失全局上下文信息。本文提出了一种新的自注意力机制,旨在解决这一问题。

创新点

DaViT通过引入“空间token”和“通道token”来同时捕捉全局上下文和局部信息,并保持计算效率。通过交替使用这两种自注意力机制,DaViT能够有效地处理高分辨率图像,同时保持计算成本的线性增长。

  • 双重注意力机制:引入了空间窗口自注意力和通道组自注意力。这两种注意力机制交替使用,既捕捉了局部精细结构信息,又捕捉了全局上下文。
  • 通道token:通过对token矩阵进行转置,定义通道token,使每个通道token在空间维度上具有全局性,包含整个图像的抽象表示。
  • 计算效率:通过分组注意力,将通道维度的计算复杂度降低为线性,从而在保持全局信息捕捉能力的同时,显著降低计算成本。

方法介绍

DaViT由spatial window self-attention和channel group self-attention组成,其中前者在swin-transformer等多个网络中都已经使用,这里不再过多介绍。这里主要介绍下本文提出的通道组自注意力,如图1(b)和图3(c)所示。

之前的自注意力将pixels或patches定义为token,并沿空间维度收集信息。通道注意力将注意力应用于patch-level token的转置上,为了获得空间维度的全局信息,将heads数设置为1。作者认为每个转置的token都概括了全局信息。这样通道token以线性的空间复杂度与通道维度上的全局信息进行交互。如图1(b)所示。

为了进一步降低复杂度,作者将通道分成多个group,并在每个group内计算self-attention,类似于在空间维度分成多个window并在每个window内计算self-attention。具体来说我们用 \(N_g\) 表示group数量,\(C_g\) 表示每个group内的通道数量,我们有 \(C=N_g*C_g\)。这样channel group attention是全局的,定义如下

其中 \(Q_i,K_i,V_i\in \mathbb{R}^{P\times C_g}\) 是grouped channel-wise image-level的queries、keys和values。

代码解析

下面是timm中的channel attention实现代码,其中输入shape=(1, 3136, 96),1代表batch_size,3136=56x56是空间分辨率,96是通道数。其中k转置后与v相乘得到attention矩阵,然后取softmax再与q的转置相乘。个人理解其实这里q、k、v的符号不重要,毕竟三个张量的维度都是一致的,比如k的转置与q相乘后取softmax再与v的转置相乘也是一样的。重要的是张量中sequence_length或者是token的数量与特征维度的定义,在spatial attention中spatial维度是seq_len,而channel维度是feature dim。这里channel attention中反过来了,channel维度作为seq_len,而spatial维度作为feature_dim,因此需要进行转置。第一步attention矩阵的维度应该是(seq_len, seq_len)的,在普通的attention中是(3136, 3136),这里就是(32, 32)因为num_heads=3,所以feat_dim=96/3=32。

这里特别需要注意的是,前面说过为了保持spatial维度的全局信息,设置num_heads=1,而这里为什么num_heads=3。因为这里的self.qkv的输入是原始的x而不是转置后的x,因此是将96分成3份,对应的是前面说的group,而spatial维度的3136保持不变,即保持了全局的信息。

class ChannelAttention(nn.Module):

    def __init__(self, dim, num_heads=8, qkv_bias=False):
        super().__init__()
        self.num_heads = num_heads  # 3
        head_dim = dim // num_heads
        self.scale = head_dim ** -0.5

        self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
        self.proj = nn.Linear(dim, dim)

    def forward(self, x: Tensor):  # (1,3136,96)
        B, N, C = x.shape

        qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)  # (1,3136,288)->(1,3136,3,3,32)->(3,1,3,3136,32)
        q, k, v = qkv.unbind(0)  # (1,3,3136,32)

        k = k * self.scale
        attention = k.transpose(-1, -2) @ v   # (1,3,32,3136) @ (1,3,3136,32) -> (1,3,32,32)
        attention = attention.softmax(dim=-1)
        # (1,3,32,32) @ (1,3,32,3136)
        x = (attention @ q.transpose(-1, -2)).transpose(-1, -2)  # (1,3,32,3136)->(1,3,3136,32)
        x = x.transpose(1, 2).reshape(B, N, C)  # (1,3136,3,32)->(1,3136,96)
        x = self.proj(x)
        return x

实验结果

不同大小的模型配置如下

其中 \(L\) 表示层数,\(N_g\) 是channel attention中的group数,\(N_h\) 是window attention中的head数。

在ImageNet上的结果如表1所示

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

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

相关文章

独家揭秘!格行随身WiFi‘骄傲’宣言背后的震撼行业的真相!随身WiFi行业内黑马

近几年以来,随行WiFi产品呈现爆发式增长,随行WiFi的火爆,是技术进步带给消费者的一种“福利”,各大直播间也充斥着品牌各异的随身WiFi。但真正脱颖而出、赢得消费者信赖的优质品牌却凤毛麟角。而其中最受欢迎的格行随身WiFi也因设…

Java语言+后端+前端Vue,ElementUI 数字化产科管理平台 产科电子病历系统源码

Java语言后端前端Vue,ElementUI 数字化产科管理平台 产科电子病历系统源码 Java开发的数字化产科管理系统,已在多家医院实施,支持直接部署。系统涵盖孕产全程,包括门诊、住院、统计和移动服务,整合高危管理、智能提醒、档案追踪等…

Stream练习

运用点&#xff1a; 流内数据类型转换(map)、filter、limit、skip、concat(让两个流合并) 题目&#xff1a; 操作1、2&#xff1a; ArrayList<String> manList new ArrayList<>();ArrayList<String> womanList new ArrayList<>();Collections.addAl…

C++之static关键字

文章目录 前提正文多重定义extern关键字使用staticstatic 全局变量(在.cpp文件中定义)static变量存放在哪里static变量可不可以放在.h文件中 static 函数static局部变量static 成员变量static 成员函数 总结参考链接 前提 好吧&#xff0c;八股&#xff0c;我又回来了。这次想…

8.14 矢量图层面要素2.5D渲染

文章目录 前言2.5D渲染QGis设置面符号为2.5D二次开发代码实现2.5D 总结 前言 本章介绍矢量图层面要素2.5D渲染的使用说明&#xff1a;文章中的示例代码均来自开源项目qgis_cpp_api_apps 2.5D渲染 2.5D渲染可以将多边形渲染为类3D效果。 QGis设置面符号为2.5D 以"hou…

数据库7.4

第二次作业 1.登陆数据库 2.创建数据库zoo 3.修改数据库zoo字符集为gbk 4.选择当前数据库为zoo 5.查看创建数据库zoo信息 6.删除数据库zoo C:\Windows\System32>mysql -uroot -p20040830Nmx mysql> create database zoo; alter database zoo character set gbk; mys…

Java springboot校园管理系统源码

Java springboot校园管理系统源码-014 下载地址&#xff1a;https://download.csdn.net/download/xiaohua1992/89364089 技术栈 运行环境&#xff1a;jdk8 tomcat9 mysql5.7 windows10 服务端技术&#xff1a;Spring Boot Mybatis VUE 使用说明 1.使用Navicati或者其它工…

VBA初学:零件成本统计之三(获取材料外协的金额)

第三步&#xff0c;从K3的数据库中获取金额 我这里是使用循环&#xff0c;通过任务单号将金额汇总出来&#xff0c;如果使用数组的话&#xff0c;还要按任务单写GROUP&#xff0c;还要去对应&#xff0c;不如循环直接一点 获取材料和外协金额的表格Sub getje()Dim rowcount A…

【JAVA入门】Day13 - 代码块

【JAVA入门】Day13 - 代码块 文章目录 【JAVA入门】Day13 - 代码块一、局部代码块二、构造代码块三、静态代码块 在 Java 中&#xff0c;两个大括号 { } 中间的部分叫一个代码块&#xff0c;代码块又分为&#xff1a;局部代码块、构造代码块、静态代码块三种。 一、局部代码块…

Linux应用---信号

写在前面&#xff1a;在前面的学习过程中&#xff0c;我们学习了进程间通信的管道以及内存映射的方式。这次我们介绍另外一种应用较为广泛的进程间通信的方式——信号。信号的内容比较多&#xff0c;是学习的重点&#xff0c;大家一定要认真学&#xff0c;多多思考。 一、信号概…

ASP.NET Core----基础学习01----HelloWorld---创建Blank空项目

文章目录 1. 创建新项目--方式一&#xff1a; blank2. 程序各文件介绍&#xff08;Project name &#xff1a;ASP.Net_Blank&#xff09;&#xff08;1&#xff09;launchSettings.json 启动方式的配置文件&#xff08;2&#xff09;appsettings.json 基础配置file参数的读取&a…

Vue 前端修改页面标题无需重新打包即可生效

在public文件夹下创建config.js文件 index.html页面修改 其他页面的标题都可以用window.title来引用就可以了&#xff01;

【算法】(C语言):冒泡排序、选择排序、插入排序

冒泡排序 从第一个数据开始到第n-1个数据&#xff0c;依次和后面一个数据两两比较&#xff0c;数值小的在前。最终&#xff0c;最后一个数据&#xff08;第n个数据&#xff09;为最大值。从第一个数据开始到第n-2个数据&#xff0c;依次和后面一个数据两两比较&#xff0c;数值…

商务办公优选!AOC Q27E3S2商用显示器,打造卓越新体验!

摘要&#xff1a;助办公室一族纵横职场&#xff0c;实现高效舒适办公&#xff01; 在日常商务办公中&#xff0c;对于办公室一族来说总有太多“难难难难难点”&#xff1a;工作任务繁琐&#xff0c;熬夜加班心力交瘁、长时间伏案工作导致颈椎、眼睛等出现问题&#xff0c;职业…

【吊打面试官系列-MyBatis面试题】为什么说 Mybatis 是半自动 ORM 映射工具?它与全自动的区别在哪里?

大家好&#xff0c;我是锋哥。今天分享关于 【为什么说 Mybatis 是半自动 ORM 映射工具&#xff1f;它与全自动的区别在哪里&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; 为什么说 Mybatis 是半自动 ORM 映射工具&#xff1f;它与全自动的区别在哪里&#xf…

[从0开始轨迹预测][NMS]:NMS的应用(目标检测、轨迹预测)

非极大值抑制&#xff08;Non-Maximum Suppression&#xff0c;简称NMS&#xff09;是一种在计算机视觉中广泛应用的算法&#xff0c;主要用于消除冗余和重叠的边界框。在目标检测任务中&#xff0c;尤其是在使用诸如R-CNN系列的算法时&#xff0c;会产生大量的候选区域&#x…

Redis基础教程(九):redis有序集合

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

华为仓颉可以取代 Java 吗?

大家好&#xff0c;我是君哥。 在最近的华为开发者大会上&#xff0c;华为亮相了仓颉编程语言&#xff0c;这是华为历经 5 年&#xff0c;投入大量研发成本沉淀的一门编程语言。 1 仓颉简介 按照官方报告&#xff0c;仓颉编程语言是一款面向全场景智能的新一代编程语言&#…

使用JAR命令打包JAR文件使用Maven打包使用Gradle打包打包Spring Boot应用

本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:王文峰…

XLSX + LuckySheet + LuckyExcel + Web Worker实现前端的excel预览

文章目录 功能简介简单代码实现web worker 版本效果参考 功能简介 通过LuckyExcel的transformExcelToLucky方法&#xff0c; 我们可以把一个文件直接转成LuckySheet需要的json字符串&#xff0c; 之后我们就可以用LuckySheet预览excelLuckyExcel只能解析xlsx格式的excel文件&a…