Swin Transformer—— 基于Transformer的图像识别模型

news2024/11/18 21:49:27

概述

Swin Transformer是微软研究院于2021年在ICCV上发表的一篇论文,因其在多个视觉任务中的出色表现而被评为当时的最佳论文。它引入了移动窗口的概念,提出了一种层级式的Vision Transformer,将Shifted Windows(移动窗口)作为其主要贡献。这个概念使得Swin Transformer可以像卷积神经网络一样进行分块,并进行层级式的特征提取,从而在特征表示中引入多尺度的概念。

在OpenAI发布的Sora中也出现了视频patches的概念,这进一步表明了Vision Transformer和Swin Transformer在引入patch概念方面的重要性。目前,许多多模态模型的backbone都采用了这两种模型,因此理解和应用它们的原理对于掌握和应用这些优秀的多模态模型非常必要。

在 Swin Transformer之前,基于Transformer的图像识别模型是视觉变换器(ViT)。它将图像视为由 16x16 个单词组成的句子,是自然语言处理中使用的变换器在图像识别中的首次应用。

本文指出了文本和图像之间的差异,并提出了 Swin Transformer,使 ViT 更适应图像领域。

文字和图像的两个区别如下。

  • 与文字符号不同,图像中的视觉元素在比例上差异很大
  • 图像中的像素比文件中的文字具有更高的分辨率(更多信息)。

为了消除这些差异

  • 计算不同贴片尺寸下的关注度
  • 用较小的补丁尺寸计算关注度。

下图说明了 ViT 和 Swin Transformer在这些方面的区别。

用较小的斑块尺寸计算注意力可以获得精细的特征,但计算成本较高。

这就是在 Swin 变换器中引入基于移位窗口的自注意的原因。多个补丁被合并到一个窗口中,注意力计算只在该窗口中进行,从而减少了计算量。

在下一节中,我们将了解斯温变换器的整体情况,然后了解一些更微小的细节,包括基于移位窗口的自我关注。

Swin Transformer

大画面

下面是 Swin Transformer的全貌。

首先,对输入图像进行补丁分割。

补丁分割:将 4x4 像素分割为一个补丁;由于 ViT将 16x16像素作为一个补丁,因此斯温变换器可以提取更精细的特征。

然后进行线性嵌入。

线性嵌入:将补丁(4x4x3ch)转换为 C 维标记,其中 C 取决于模型的大小。

对于从每个补丁中获得的标记,Swin Transformer Block 会计算关注度并进行特征提取。

Swin Transformer区块:用基于移位窗口的自保持(W-MSA 和 SW-MSA)取代常规变压器区块中使用的多头自保持(MSA)。以下章节将提供更多信息。下文将对它们进行更详细的介绍。其他配置与普通变压器几乎完全相同。

目前看到的线性嵌入和变换块部分被称为第 1 阶段;共有 1 到 4 个阶段,但每个阶段的补丁大小不同,因此可以在不同尺度上进行特征提取。不同大小的补丁是由补丁合并(Patch Merging)产生的,它将邻域中的补丁聚合在一起。

补丁合并:在每个阶段,相邻的(2 × 2)补丁(标记)合并在一起,形成一个标记。具体来说,合并 2 × 2 标记,并通过线性层将所得的 4C 维向量变为 2C 维。例如,在第 2 阶段,(H/4)×(W/4)×C 维度被简化为 (H/8)×(W/8)×2C 维度。

基于移动窗口的自我关注

从计算复杂度的角度解释了普通变压器和斯温变压器模块注意力计算的区别。

法线变换器计算所有标记之间的距离,其中 h 和 w 是图像中垂直和水平斑块的数量,计算量如下

另一方面,Swin 变换器只计算由多个补丁组成的窗口内的关注度:一个窗口包含 M x M 个补丁,基本固定为 M = 7。计算复杂度如下式所示。

在普通变换器中,计算复杂度的增加与补丁数 (hw) 的平方成正比。然而,由于 M = 7,影响很小,即使是补丁数 (hw) 的增加也保持在幂级数以内。这使得 Swin变换器可以计算小尺寸的贴片。

接下来介绍将图像划分为窗口的方法:窗口的排列方式是将图像平均划分为 M x M 个补丁。以这种方式排列的每个窗口都会计算注意力,因此即使是相邻的补丁,如果它们是不同的窗口,也不会计算注意力。为了解决窗口边界问题,在计算第一个注意力(W-MSA:基于窗口的多头自注意力)后,窗口会被移动,注意力会被再次计算(SW-.MSA:基于移动窗口的多头自注意)。

如下图所示,在原窗口分割的基础上移动([M/2], [M/2])个像素。


代码模型:

class PatchEmbed(nn.Module):
    
    def __init__(self, patch_size=4, in_c=3, embed_dim=96, norm_layer=None):
        super().__init__()
        patch_size = (patch_size, patch_size)
        self.patch_size = patch_size
        self.in_chans = in_c
        self.embed_dim = embed_dim
        self.proj = nn.Conv2d(in_c, embed_dim, kernel_size=patch_size, stride=patch_size)
        self.norm = norm_layer(embed_dim) if norm_layer else nn.Identity()

    def forward(self, x):
        _, _, H, W = x.shape

        # 如果输入图片的 H,W 不是patch_size的整数倍,需要进行padding
        pad_input = (H % self.patch_size[0] != 0) or (W % self.patch_size[1] != 0)
        if pad_input:
            # to pad the last 3 dimensions, (W_left, W_right, H_top,H_bottom, C_front, C_back)
            x = F.pad(x, (0, self.patch_size[1] - W % self.patch_size[1],
                          0, self.patch_size[0] - H % self.patch_size[0],
                          0, 0))

        # 下采样patch_size倍
        x = self.proj(x)
        _, _, H, W = x.shape
        # flatten: [B, C, H, W] -> [B, C, HW];  transpose: [B, C, HW] -> [B, HW, C]
        x = x.flatten(2).transpose(1, 2)
        x = self.norm(x)
        return x, H, W

移位配置的高效批量计算

SW-MSA 的窗口大小不同,窗口数量也会增加。因此,如果直接进行处理,就会出现计算量比 W-MSA 增加的问题。因此,在 SW-MSA 中,使用一种称为循环移动的方法进行伪操作,而不是实际改变窗口的排列。

如下图所示,整个图像向左上方移动,溢出区域插入空白区域 (循环移动 )。通过这种方法,它的计算方法与 W-MSA 窗口中的 Attention 计算方法相同。此外,由于窗口中可能包含不相邻的斑块,因此要对这些部分进行掩膜处理。在最终输出中,将执行循环移位的反向操作(反向循环移位),将补丁恢复到原始位置。


代码实现:

class PatchMerging(nn.Module):

    def __init__(self, dim, norm_layer=nn.LayerNorm):
        super().__init__()
        self.dim = dim
        self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False)
        self.norm = norm_layer(4 * dim)

    def forward(self, x, H, W):
        """
        x: B, H*W, C
        """
        B, L, C = x.shape
        assert L == H * W, "input feature has wrong size"

        x = x.view(B, H, W, C)

        # 如果输入feature map的H,W不是2的整数倍,需要进行padding
        pad_input = (H % 2 == 1) or (W % 2 == 1)
        if pad_input:
            # to pad the last 3 dimensions, starting from the last dimension and moving forward.
            # (C_front, C_back, W_left, W_right, H_top, H_bottom)
            # 注意这里的Tensor通道是[B, H, W, C],所以会和官方文档有些不同
            x = F.pad(x, (0, 0, 0, W % 2, 0, H % 2))

        x0 = x[:, 0::2, 0::2, :]  # [B, H/2, W/2, C]
        x1 = x[:, 1::2, 0::2, :]  # [B, H/2, W/2, C]
        x2 = x[:, 0::2, 1::2, :]  # [B, H/2, W/2, C]
        x3 = x[:, 1::2, 1::2, :]  # [B, H/2, W/2, C]
        x = torch.cat([x0, x1, x2, x3], -1)  # [B, H/2, W/2, 4*C]
        x = x.view(B, -1, 4 * C)  # [B, H/2*W/2, 4*C]

        x = self.norm(x)
        x = self.reduction(x)  # [B, H/2*W/2, 2*C]

        return x

结构变体

Swin 变压器有 T、S、B 和 L 四种尺寸,每级的尺寸(dim)、头(head)和块数各不相同,如下表所示。

试验

在 ImageNet-1K 的图像识别任务、COCO 的物体检测任务和 ADE20K 的语义分割任务中与其他模型进行了比较,结果都达到了最高准确率。(实验结果详见本文第四章表 1~表 3)。

在 SW-MSA 中进行的消融研究证实,在这两项任务中,引入 SW-MSA 的准确率都高于单独引入 W-MSA。

摘要

与在所有斑块之间计算注意力的 ViT 不同,注意力计算和斑块聚合可以在相邻斑块的窗口中重复进行,从而可以在不同尺度上提取特征。另一个优点是不在所有斑块之间计算注意力,从而降低了计算复杂度,并能从较小的斑块尺寸中提取特征。

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

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

相关文章

Node.js -- 包管理工具

文章目录 1. 概念介绍2. npm2.1 npm 下载2.2 npm 初始化包2.3 npm 包(1) npm 搜索包(2) npm 下载安装包(3) require 导入npm 包的基本流程 2.4 开发依赖和生产依赖2.5 npm 全局安装(1) 修改windows 执行策略(2) 环境变量Path 2.6 安装包依赖2.7 安装指定版本的包2.8 删除依赖2.…

mysql主库delete一个没主键的表导致从库延迟很久问题处理

一 问题描述 发现线上环境一个从库出现延迟,延迟了2天了,还没追上主库。 查看当前运行的sql及事务,发现这个sql语句是在delete一个没主键的表。 二 问题模拟 这里在测试环境复现下这个问题。 2.1 在主库造数据 use baidd; CREATE TABL…

《QT实用小工具·四十三》历史编辑器(支持历史搜索 关键字匹配)

1、概述 源码放在文章末尾 该项目实现了在输入框中输入部分信息能全部展现之前的历史输入信息&#xff0c;支持历史搜索和关键词匹配&#xff0c;项目demo演示如下所示&#xff1a; 项目部分代码如下所示&#xff1a; #include "historymodel.h" #include <QM…

C语言自定义类型【联合体与枚举】

文章目录 1.联合体1.1联合体的声明1.2联合体的特点1.3联合体的大小计算联合体的使用案例 2.枚举2.1枚举类型的声明2.2枚举类型的优点(为什么使用枚举)2.3枚举类型的使用 结语 1.联合体 1.1联合体的声明 和结构体一样&#xff0c;联合体也是由一个或多个成员构成&#xff0c;同…

ffmpeg中stream_loop参数不生效原因分析

问题 使用ffmpeg把一个视频文件发布成一个rtmp流&#xff0c;并设置成循环推流&#xff0c;此时需要使用参数stream_loop&#xff0c;命令如下: ffmpeg.exe -stream_loop -1 -re -i D:\tools\ffmpeg-5.1.2\bin\sei.h264 -c copy -f flv -safe 0 rtmp://localhost:1935/live/te…

BIO、NIO与AIO

一 BIO 同步并阻塞(传统阻塞型)&#xff0c;服务器实现模式为一个连接一个线程&#xff0c;即客户端有连接请求时服务器端就需要启动一个线程进行处理. BIO&#xff08;Blocking I/O&#xff0c;阻塞I/O&#xff09;模式是一种网络编程中的I/O处理模式。在BIO模式中&#xf…

杂项基础知识-部分

** 杂项基础知识 ** 一.常见的各类文件的文件头和文件结尾 列举常见文件头编码特征&#xff1a; JPEG&#xff1a; PNG&#xff1a; GIF&#xff1a; RAR&#xff1a; ZIP&#xff1a; 十六进制特征&#xff1a; 图片文件&#xff1a; JPEG&#xff1a;文件头格式为…

K8s 使用 CephFS 作为后端存储(静态供给、动态供给)

一、K8s 使用 CephFS CephFS是 Ceph 中基于RADOS&#xff08;可扩展分布式对象存储&#xff09;构建&#xff0c;通过将文件数据划分为对象并分布到集群中的多个存储节点上来实现高可用性和可扩展性。 首先所有 k8s 节点都需要安装 ceph-common 工具&#xff1a; yum -y ins…

C++面经(简洁版)

1. 谈谈C和C的认识 C在C的基础上添加类&#xff0c;C是一种结构化语言&#xff0c;它的重点在于数据结构和算法。C语言的设计首要考虑的是如何通过一个过程&#xff0c;对输入进行运算处理得到输出&#xff0c;而对C&#xff0c;首先要考虑的是如何构造一个对象&#xff0c;通…

PotatoPie 4.0 实验教程(41) —— FPGA实现RISC-V 扩展 GPIO UART Timer功能

TD工程介绍 我们提供的TD工程里的RISC-V核默认就开启了GPIO UART扩展&#xff0c;可以看到还有SPI和I2C扩展。因此后面的实验中TD的工程我们基本不怎么修改TD的内容&#xff0c;只需要修改TD工具中Soc_Top.v文件中的TCM0_INITFILE为FD生成的固件名称即可&#xff0c;主要修我以…

实时通讯技术 WebRTC 介绍

WebRTC WebRTC&#xff08;Web Real-Time Communication&#xff09;是一个支持网页浏览器进行实时语音对话或视频对话的技术。 历史 2010年5月&#xff0c;Google以6820万美元收购VoIP软件开发商Global IP Solutions的GIPS引擎&#xff0c;并改为名为“WebRTC”。WebRTC使用…

C++ ─── 匿名对象+变量的创建顺序

目录 1. 匿名对象&#xff08;临时对象&#xff09; 2. 编译器的优化 3.变量的创建与销毁 1. 匿名对象&#xff08;临时对象&#xff09; 我们先来看有名对象的创建 Date d1; Date d2(2024,4,27);匿名对象的创建 Date(2024,56,1); 生成了一个匿名对象&#xff0c;执行完Da…

数据仓库是什么

写在前面 刚接触大数据的新手小白可能会对数据仓库这个词比较陌生&#xff0c;本文将介绍数据仓库的主要特征及OLTP&OLAP的区别&#xff0c;帮助读者更好理解数据仓库。 一、什么是数据仓库 数据仓库&#xff0c;简称数仓&#xff0c;是一个对数据进行加工&#xff0c;集…

信息系统项目管理师0073:网路集成(5信息系统工程—5.3系统集成—5.3.2网路集成)

点击查看专栏目录 文章目录 5.3.2网路集成5.3.2网路集成 计算机网络系统集成不仅涉及技术问题,而且涉及组织的管理问题,因而比较复杂,特别是大型网络系统更是如此。从技术角度讲,网络集成不仅涉及不同厂家的网络设备和管理软件,也会涉及异构和异质网络系统的互联问题。从管…

【算法学习】day1

文章目录 双指针算法移动零复写零 双指针算法 移动零 思路&#xff1a;通过定义两个下标作为双指针&#xff0c;cur从开始对整个数组进行遍历&#xff0c;而我们的dest代表的是非零元素的最后一个位置&#xff0c;cur位置为0的时候就cur&#xff0c;不为0元素的时候就交换dest…

STM32单片机C语言模块化编程实战:按键控制LED灯详解与示例

一、开发环境 硬件&#xff1a;正点原子探索者 V3 STM32F407 开发板 单片机&#xff1a;STM32F407ZGT6 Keil版本&#xff1a;5.32 STM32CubeMX版本&#xff1a;6.9.2 STM32Cube MCU Packges版本&#xff1a;STM32F4 V1.27.1 之前介绍了很多关于点灯的方法&#xff0c;比如…

设计模式学习笔记 - 项目实战一:设计实现一个支持各种算法的限流框架(实现)

概述 上篇文章&#xff0c;我们介绍了如何通过合理的设计&#xff0c;来实现框架的功能性需求的同时&#xff0c;满足易用、易扩展、灵活、低延迟、高容错等非功能性需求。在设计的过程中&#xff0c;我们也借鉴了之前讲过的一些开源项目的设计思想。比如 Spring 的低侵入松耦…

【ETAS CP AUTOSAR工具链】RTE层基本概念与开发流程

本篇文章续接上篇文章【ETAS CP AUTOSAR工具链】基本概念与开发流程&#xff0c;继续按上篇文章描述的ETAS CP工具链进行开发的基本框架&#xff0c;讲述了“RTE集成与配置”这部分的基本概念与开发流程。 RTE&#xff08;Runtime Environment&#xff09;处于应用层与基础软件…

Web前端开发 小实训(一) 成绩分类统计

用于学生web前端开发课程实训练习&#xff0c;掌握基本语法和数据类型 实训目的 使用分支语句&#xff0c;完成分数统计与等级对比,通过输入框输入分数&#xff0c;可以根据分数多少划分等级。 参考思路&#xff1a; 分析题目&#xff1a;根据输入分数进行等级划分。 操作过…

声光控路灯控制系统设计与仿真

目录 前言 一、设计任务 二、系统组成及工作原理 1、总体设计思路 2、电路各模块设计简介 &#xff08;1&#xff09;光控电路 &#xff08;2&#xff09;声控电路 (3) 逻辑控制电路 (4) 延时电路 三、系统中电源模块的设计 1、方案比较和确定 2、 设计思路 3、直流…