Transformers在计算机视觉领域中的应用【第1篇:ViT——Transformer杀入CV界之开山之作】

目录

  • 1 模型结构
  • 2 模型的前向过程
  • 3 思考
  • 4 结论

论文: AN IMAGE IS WORTH 16X16 WORDS: TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE
代码:https://github.com/google-research/vision_transformer
Huggingface:https://github.com/huggingface/pytorch-image-models/blob/main/timm/models/vision_transformer.py

1 模型结构

在模型的设计上,作者尽可能地按照最原始的Transformer来做的,好处是可以把NLP那边已经成功的Transformer架构直接拿过来用,就不用自己去魔改模型了。而且因为Transformer已经在NLP火了这么多年了,有一些写得非常高效的实现,ViT也可以直接拿过来使用。

下图是ViT的模型总览图。给定一张图,先把这张图打成一系列patch,然后这些patch变成一个序列,每个patch会通过一个叫线性投影层的操作特到一个特征,即论文里说的patch embedding。因为自注意力是所有元素两两之间去做交互,所以它本身不存在顺序的问题,但是对于图片来说是一个整体,每个patch是有顺序的,例如图中的1、2、3, …。如果顺序颠倒了,就不是这张图片了。类似NLP那边,作者给patch embedding加上了位置编码position embedding,这样整体的token就包含了这个图片块原本有的图像信息,又包含了这个图像块所在的位置信息。得到这样的一个个token之后,就跟NLP那边是完全一样的了,直接输入到Transformer Encoder,编码器就会反馈给我们很多的输出。

问题来了,这么多输出,我们该拿哪个输出去做最后的分类呢?借鉴BERT,BERT模型有一个extra learnable embedding的特殊字符,即叫cls的分类字符,同样的,ViT也加了这样的一个特殊字符,用星号*代替,也是有position embedding,位置信息永远是0。

因为所有的token都跟其他所有的token做交互信息,所以cls embedding能够从别的embedding里学到有用的信息,从而我们只需要根据cls的输出做最后的判断即可。最后的MLP head,实际上就是一个通用的分类头,最后用交叉熵去进行模型的训练。

这个编码器是一个标准的Transformer Encoder,具体的结果列在图的右边。对于这些patches,先输入进来做一次Layer Norm,然后再做multi-head self-attention,然后再经过Layer Norm,再做MLP。这就是一个Transformer Block,可以把它叠加L次,就得到了Transformer Encoder。

ViT的模型结构是非常简洁的,特殊之处就在于如何把图片变成一系列的token。

ViT

ViT模型大小:
参数量

2 模型的前向过程

  • 输入图片

    • 对于输入图片,X = 224×224×3,3表示RGB通道;patch大小是16×16,那么得到的token数N = (224/16)×(224/16) = 196,即一共得到196个图像块,每个图像块的维度是16×16×3=768;所以我们把原来的图片变成了196×768。
  • 线性投射层

    • 线性投射层实际上就是一个全连接层,用E来表示,维度是768×768,右边这个768是文章中的符号D,可以变大,Transformer有多大,D就可以设置多大。但是左边的768是patch的大小计算过来的,是不变的。

    • 经过线性投射层之后,就得到了patch embedding,具体来说就是X * E = [196×768]×[768×768] = 196×768。意思是指这里得到了196个token,每个token的维度是768。这里的中括号表示矩阵,X*E表示矩阵相乘。至此,已经成功把vision的问题转化成NLP的问题了。

    • 这里还需要加上一个额外的cls token,所以最终序列的长度就是整体进入Transformer Encoder中的序列,长度是(196+1)×768 = 197×768,197是指196个图片块对应的token和1个特殊字符cls token。

  • 位置编码

    • 我们还需要加上位置编码信息,我们不可能把1、2、3,… 这些字符直接给Transformer去学,具体的做法是:设置一个表,表的每一行代表这里的1、2、3,… 这些序号,每一行都是一个向量,维度和D是一样的,都是768,这个向量也是可学习的。然后我们把这个位置信息加入到token里面,注意这里是用的Add,而不是拼接concatenation。加完位置编码之后,序列还是197×768。至此,我们就做完了整个图片的预处理了。
  • Transformer Encoder

    • 编码器的输入就是一个197×768的tensor,经过Layer Norm之后还是197×768。

    • 随后经过多头注意力,变成了三份:q、k、v,因为这里做的是多头注意力,假设用的是ViT的base版本,用了12个头,那么q、k、v的维度分别都变成了197×768/12 = 197×64,最后再把12个头的输出拼接起来,又变回197×768了,所以多头注意力的最终输出结果还是197×768。

    • 然后再经过Layer Norm,还是197×768,再过一层MLP,会把维度相对应的放大,一般是放大4倍,所以会变成197×768×4 = 197×3072,然后再缩小回去,再变成197×768输出。

    • 这就是一个Transformer Block的前向传播过程,进去是197×768,出来还是197×768,序列的长度和每个token对应的维度大小都是一样的,所以可以在一个Block上不停地往上叠加Block,想加多少加多少。最后有L层Block组成Transformer Encoder。

3 思考

论文是真的把计算机视觉当做自然语言处理去做,只使用了标准的Transformer编码器,而没有使用计算机视觉中常用的卷积神经网络。

把图片分成一系列16×16的patch的原因是:self-attention需要对所有token两两进行计算,操作复杂度是n×n,如果是把每个像素点当做token去输入到编码器中,那么对于一张224×224的图片,就有50176个token,对于检测任务的输入,图片大小通常是600×600,这样的计算复杂度是非常大的,需要很大的计算资源都难以实现,所以需要把图片分成一系列小的patch。

对于中等大小的数据集,ViT的结果反而会比ResNet的结果要弱几个点,主要的原因:Transformer跟卷积神经网络相比,缺少一些CNN所独有的归纳偏置(inductive bias)。归纳偏置指的是一种先验知识,或者一种我们提前做好的假设。常说的归纳偏置有两种:

  1. 局部性(locality):CNN是以滑动窗口这种形式一点一点地在图片上进行卷积的,它假设图片上相邻的区域会有相邻的特征,比如说桌子和椅子大概率会在相邻的位置,靠的越近的东西,相关性越强。

  2. 平移等变性(translation equivariance):公式形式是f(g(x)) = g(f(x)),无论是先计算g函数还是f函数,最终的结果都是不变的,可以把f理解成卷积,g理解成平移,也就是说,无论是先做平移还是先做卷积,结果都是不变的。因为卷积核相当于一个模板template,无论这个图片同样的物体移动到哪里,只要是同样的输入进来,遇到了同样的卷积核,那他的输出永远是一样的。

一旦CNN有了这两个归纳偏置之后,就有了很多的先验信息,所以就需要相对少的数据去学一个比较好的模型。但是对于Transformer来说,没有这些先验信息,所以它的所有这些能力、对视觉世界的感知全部都需要从这些数据里自己学。

为了验证这个假设,作者在大的数据集上训练,发现大规模的预训练比归纳偏置要好。ViT只要在足够的数据去预训练的情况下,就能在下游任务上获得很好的迁移学习效果。

4 结论

这篇论文直接拿NLP领域里标准的Transformer来解决计算机视觉问题,除了在刚开始的抽图像块的时候和位置编码用了一些图像特有的归纳偏置之外,就再也没有引入任何图像特有的归纳偏置了,把图片理解成一个序列的图像块,就像一个句子里有很多单词一样,可以直接用NLP里一个标准的Transformer来做图像分类。这个简单、扩展性很好的策略,跟大规模预训练结合起来的时候,效果出奇的好。ViT在很多图像分类的benchmark上超过了之前最好的方法。

ViT还能做检测和分割这两个最主流的视觉任务,后面出来了一系列的工作,例如:ViT-FRCNN(检测)、SETR(分割)、Swin Transformer(将多尺度的设计融合到Transformer里)等等。

ViT实现了CV和NLP大一统之后,多模态任务就可以用一个Transformer去解决了,这篇论文的影响力相当巨大。

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

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

相关文章

Unity3D模型场景等测量长度和角度功能demo开发

最近项目用到多段连续测量物体长度和角度功能,自己研究了下。 1.其中向量角度计算: 需要传入三个坐标来进行计算。三个坐标确定两条向量线段的方向,从而来计算夹角。 public Vector3 SetAngle(Vector3 p1, Vector3 p2,Vector3 p3) { …

蓝桥杯第 23 场 小白入门赛

一、前言 好久没打蓝桥杯官网上的比赛了,回来感受一下,这难度区分度还是挺大的 二、题目总览 三、具体题目 3.1 1. 三体时间【算法赛】 思路 额...签到题 我的代码 // Problem: 1. 三体时间【算法赛】 // Contest: Lanqiao - 第 23 场 小白入门赛 …

从0开始学PHP面向对象内容之常用设计模式(享元)

二、结构型设计模式 7、享元模式(Flyweight Pattern) 这里是引用享元模式(Flyweight Pattern) 是一种结构型设计模式,旨在通过共享对象来减少内存使用,尤其适用于大量相似对象的场景。通过共享和重用对象的…

YOLO 标注工具 AutoLabel 支持 win mac linux

常见的标注工具,功能基础操作繁琐,无复制粘贴,标签无法排序修改,UI不美观,bug修正不及时,没有集成识别、训练、模型导出… 怎么办呢?AutoLabel它来了 Quick Start 一图胜千言 图像标注 支持YOL…

《Python基础》之Python中可以转换成json数据类型的数据

目录 一、JSON简介 JSON有两种基本结构 1、对象(Object) 2、数组(Array) 二、将数据装换成json数据类型方法 三、在Python中,以下数据类型可以直接转换为JSON数据类型 1、字典(Dictionary&#xff09…

如何在Bash中等待多个子进程完成,并且当其中任何一个子进程以非零退出状态结束时,使主进程也返回一个非零的退出码?

文章目录 问题回答参考 问题 如何在 Bash 脚本中等待该脚本启动的多个子进程完成,并且当这其中任意一个子进程以非零退出码结束时,让该脚本也返回一个非零的退出码? 简单的脚本: #!/bin/bash for i in seq 0 9; docalculations $i & d…

远程桌面协助控制软件 RustDesk v1.3.3 多语言中文版

RustDesk 是一款开源的远程桌面软件,支持多平台操作,包括Windows、macOS、Linux、iOS、Android和Web。它提供端到端加密和基于角色的访问控制,确保安全性和隐私保护。使用简单,无需复杂配置,通过输入ID和密码即可快速连…

LWIP和FATFS 实现 FTP 服务端

目录 一、前言 二、LWIP 和 FTP 简介 1.LWIP 2.FTP 三、实现 FTP 服务端的主要步骤 1.初始化 LWIP 2.创建 FTP 服务器任务 3.处理客户端连接 4.实现 FTP 命令处理 5.文件系统操作 6.错误处理和日志记录 四、示例代码 1.创建FTP任务 2. FTP任务代码 3.处理交互数据…

多线程篇-8--线程安全(死锁,常用保障安全的方法,安全容器,原子类,Fork/Join框架等)

1、线程安全和不安全定义 (1)、线程安全 线程安全是指一个类或方法在被多个线程访问的情况下可以正确得到结果,不会出现数据不一致或其他错误行为。 线程安全的条件 1、原子性(Atomicity) 多个操作要么全部完成&a…

【css实现收货地址下边的平行四边形彩色线条】

废话不多说&#xff0c;直接上代码&#xff1a; <div class"address-block" ><!-- 其他内容... --><div class"checked-ar"></div> </div> .address-block{height:120px;position: relative;overflow: hidden;width: 500p…

【Python网络爬虫笔记】5-(Request 带参数的get请求) 爬取豆瓣电影排行信息

目录 1.抓包工具查看网站信息2.代码实现3.运行结果 1.抓包工具查看网站信息 请求路径 url:https://movie.douban.com/typerank请求参数 页面往下拉&#xff0c;出现新的请求结果&#xff0c;参数start更新&#xff0c;每次刷新出20条新的电影数据 2.代码实现 # 使用网络爬…

「Mac畅玩鸿蒙与硬件35」UI互动应用篇12 - 简易日历

本篇将带你实现一个简易日历应用&#xff0c;显示当前月份的日期&#xff0c;并支持选择特定日期的功能。用户可以通过点击日期高亮选中&#xff0c;还可以切换上下月份&#xff0c;体验动态界面的交互效果。 关键词 UI互动应用简易日历动态界面状态管理用户交互 一、功能说明…

elastic net回归

Elastic Net回归是一种结合了**岭回归&#xff08;Ridge Regression&#xff09;和Lasso回归&#xff08;Lasso Regression&#xff09;**的回归方法&#xff0c;旨在同时处理多重共线性和变量选择问题。Elastic Net通过惩罚项&#xff08;正则化&#xff09;对模型进行约束&am…

CSP-J初赛不会备考咋办?

以下备考攻略仅供参考&#xff0c;如需资料请私信作者&#xff01;求支持&#xff01; 目录 一、编程语言基础 1.语法知识 -变量与数据类型 -运算符 -控制结构 -函数 2.标准库的使用 -输入输出流 -字符串处理 -容器类&#xff08;可选&#xff09; 二、算法与数据结构 1.基…

IDEA全局设置-解决maven加载过慢的问题

一、IDEA全局设置 注意&#xff1a;如果不是全局设置&#xff0c;仅仅针对某个项目有效&#xff1b;例在利用网上教程解决maven加载过慢的问题时&#xff0c;按步骤设置却得不到解决&#xff0c;原因就是没有在全局设置。 1.如何进行全局设置 a.在项目页面&#xff0c;点击f…

JAVAWeb之CSS学习

前引 CSS&#xff0c;层叠样式表&#xff08;Cascading Style Sheets&#xff09;&#xff0c;能够对网页中元素位置的排版进行像素级精确控制&#xff0c;支持几乎所有的字体字号样式&#xff0c;拥有网页对象和模型样式编辑的能力&#xff0c;简单来说&#xff0c;美化页面。…

基于PHP的香水销售系统的设计与实现

摘 要 时代科技高速发展的背后&#xff0c;也带动了经济的增加&#xff0c;人们对生活质量的要求也不断提高。香水作为一款在人际交往过程中&#xff0c;给对方留下良好地第一印象的产品&#xff0c;在生活中也可以独自享受其为生活带来的点缀。目前香水市场体量庞大&#xff…

3. STM32_串口

数据通信的基础概念 什么是串行/并行通信&#xff1a; 串行通信就是数据逐位按顺序依次传输 并行通信就是数据各位通过多条线同时传输。 什么是单工/半双工/全双工通信&#xff1a; 单工通信&#xff1a;数据只能沿一个方向传输 半双工通信&#xff1a;数据可以沿两个方向…

网络安全相关证书资料

网络安全相关证书有哪些&#xff1f; 网络安全相关证书有哪些呢&#xff1f;了解一下&#xff01; 1. CISP &#xff08;国家注册信息安全专业人员&#xff09; 说到CISP&#xff0c;安全从业者基本上都有所耳闻&#xff0c;算是国内权威认证&#xff0c;毕竟有政府背景给认证…

【目标检测】YOLO:深度挖掘YOLO的性能指标。

YOLO 性能指标 1、物体检测指标2、性能评估指标详解2.1 平均精度&#xff08;mAP&#xff09;2.2 每秒帧数&#xff08;FPS&#xff09;2.3 交并比&#xff08;IoU&#xff09;2.4 混淆矩阵&#xff08;Confusion Matrix&#xff09;2.5 F1-Score2.6 PR曲线&#xff08;Precisi…