Transformer太过强大,目前有很多模型都将其引入自己的领域做调整,除了它最先发迹的NLP外,也初步的从NLP到达CV的战场。本篇只整理几篇在纯CV届的Transformer应用。博主曾经整理过Cross-modal的Transformer也可以参考,传送门:Cross-modal Pretraining in BERT(跨模态预训练)。

首先先看看既然Transformer能在NLP中淘汰RNN,那么作为另一个神经网络基石级的CNN,是否也可以直接被替代呢?


Generative Pretraining from Pixels(iGPT)
来自ICML20,尝试不使用CNN直接做image分类。作者提到,由于BERT 和 GPT-2 等 Transformer 模型是域不可知的,这意味着它们可以直接应用于任何形式的 1D 序列。所以作者直接把2D的图像处理成1D的序列,然后输入到Transformer,然后做next pixel prediction任务。

完整的架构如上图,最左边的图1是把图像由2D展平为1D,这里直接处理原像素。图2是作者使用的2种预训练目标:auto-regressive next pixel prediction 和masked pixel prediction,一个像AE一样直接预测所有像素,另一个类似BERT预测masked像素。

attn_mask = torch.full((len(x), len(x)), -float("Inf"), device=x.device, dtype=x.dtype
)
attn_mask = torch.triu(attn_mask, diagonal=1)#[784, 784]
#attn_mask = [[0,-inf,-inf...,-inf],
#            [0,0,-inf,...,-inf],
#            [0,0,0,...,-inf],
#            [0,0,0,...,0]]

最后fine-turning。如图3有两种方式:

  • (i) fine-tune:增加了一个小的分类头,用于优化分类目标并adapt所有权重。
  • (ii)Linear-probe:将pretraining的模型视作特征提取器,增加一个分类头,只训练这个分类头。第二种方式的直觉在于“一个好的特征应该能够区分不同的类”。

fine-tune效果好有可能是因为架构很适合下游任务,但是linear-probe只取决于特征质量。

# x:原始图像处理后得到的序列 [32*32, 64],64为batchsize,32是下采样后的长款
length, batch = x.shape
# 将每个pixel作为token求embedding,128为embedding的维度
h = self.token_embeddings(x) # [32*32, 64, 128]
# 添加位置编码
h = h + self.position_embeddings(positions).expand_as(h)
# transformer
for layer in self.layers:h = layer(h)
# 自回归编码需要输出logits,映射回字典长度
logits = self.head(h) # [32*32,64,16]
# 16类的cross_entropy,对每个pixel计算损失
loss = self.criterion(logits.view(-1, logits.size(-1)), x.view(-1))

paper:http://proceedings.mlr.press/v119/chen20s.html


An image is worth 16x16 words: Transformers for image recognition at scale(ViT)
来自ICLR2021,这篇文章在上一篇文章的基础上更加的深入。同样的motivation也是直接用Transformer来代替CNN。作者认为虽然Transformer相比CNN缺少一些归纳偏差,例如平移等变和局部性,但在数据集足够的情况下,泛化能力同样也是可以达到很强的。

ViT的具体架构如上图,直接将图像分割成小块,其中图像块的position处理方式与标记(单词)相同,然后输入到Transformer中,最后以监督的方式训练模型进行图像分类。此时因为不会使用CNN抽特征,那么输入存在一个问题:图像是2D,不用CNN的话不就没有特征做输入吗?

针对这一点,需要重塑图片为扁平的序列块,采用可训练的线性映射将patch进行平化,映射到D维上,即原先正常图片的H x W x C直接变成Nx(P^2 x C)。z0=[xclass;xp1E;xp2E;...;xpNE]+Epos,E∈R(P2⋅C)×D,Epos∈R(N+1)×Dz_0=[x_{class};x_p^1E;x_p^2E;...;x_p^NE]+E_{pos},E \in R^{(P^2 \cdot C)\times D},E_{pos} \in R^{(N+1)\times D}z0=[xclass;xp1E;xp2E;...;xpNE]+Epos,ER(P2C)×D,EposR(N+1)×D其中C是通道的数量,(P, P)是每个图像块的分辨率,N是patch的数量,D是投影到的维度。class和在NLP中使用的一样,最后可以直接用它输出进行分类预测(值得注意的是ViT只有encoder,没有decoder)。

然后将这个z输入到Transformer中:zl′=MSA(LN(zl−1))+zl−1z'_l=MSA(LN(z_{l-1}))+z_{l-1}zl=MSA(LN(zl1))+zl1zl=MLP(LN(zl′))+zl′z_l=MLP(LN(z'_{l}))+z'_{l}zl=MLP(LN(zl))+zly=LN(zL0)y=LN(z^0_L)y=LN(zL0)这里就和Transformer的结构相差不多,由多头自注意力MSA和MLP交替层组成。在每个块之前使用Layernorm (LN),在每个块之后使用残差连接,且该MLP包含两个具有GELU非线性的层。

使用的话可以直接调库:pip install vit-pytorch

  • code: https://github.com/google-research/vision_transformergithub.com
import torch
from vit_pytorch import ViTv = ViT(image_size = 256,patch_size = 32,num_classes = 1000,dim = 1024,depth = 6,heads = 16,mlp_dim = 2048,dropout = 0.1,emb_dropout = 0.1
)img = torch.randn(1, 3, 256, 256)
mask = torch.ones(1, 8, 8).bool() # optional mask, designating which patch to attend topreds = v(img, mask = mask) # (1, 1000)

实验结果证明了ViT的效果真的挺不错。以上这两篇文章应该是代替CNN的最著名的两篇文章了。接下来介绍Transformer在其他CV领域中的表现。首先是比较主流的High-level vision任务目标检测。


End-to-end object detection with transformers(DERT)
来自ECCV2020,DETR将目标检测任务视为一个直观的集合预测问题,并摆脱传统手工制作的组件,如锚的生成和非最大抑制(NMS)后处理。它的整体架构图如上,DETR使用常规的CNN主干来学习输入图像的2D表示。 然后将将其展平送到transformer(此处仍然有positional encoding) 。然后在object query的约束下,得到Transformer的输出,然后用四个FFN来得到class box(类和边界框)和on object(有无目标的)的结果。比较重要的是有两个loss的设计:

  • a set prediction loss, 用于计算预测 和 真值 之间的差异。
  • an architecture, 预测一组物体并且建模他们之间的关系。

即同时得到N个推理结果,然后计算真值和预测这两个集合的差异,并用二分图loss以匹配预测和真相对象。不过由于DERT的速度比较慢,之后有ACT等方案的解决,甚至引入蒸馏网络的MTKD方法等。缺点:训练周期长,对小物体检测效果差。


补一个Transformer-based backbone for detection,也是做目标检测,但是它基本与前面的ViT处理图像的方式一致,但是输出的patch feature重新调整为一个图像的特征图送入传统的目标检测模型。


Pre-Trained Image Processing Transformer(IPT)
有了High-level vision,还整理一篇Low-level vision(超分生成模型)的任务Image enhancement(例如,去噪,超分辨率和去雨)。其针对不同的图像处理任务,有着多头多尾结构和任务嵌入。

具体来说,它也是先将特征分为补丁(patches),然后放入Transformer结构中,然后将输出重塑为相同大小的特征,即image变patches,过Transformer之后还原patches再得到image的生成。

此外为了提高IPT模型的泛化能力,引入了一种自监督方法。 然后利用相应的头、尾和任务嵌入对每个任务进行微调。其他的没有什么很特别的部分,具体可以自己看原论文:

paper:https://arxiv.org/pdf/2012.00364.pdf

以上各任务都需要在比较大的数据集上效果出色,这也说明了Transformer确实需要喂入比较多的数据才能比较有效。



TransReID:Transformer-based Object Re-Identification
Transformer+ReID。首先想说ReID的领域中,本来就有很多的基于切分的方法了,此时再跟ViT结合真的不要太合适!!模型架构如上图,比较基底的是ViT会作为backbone提取特征,首先看它对ViT的一些改良ViT-BoT(ViT- Bag of Tricks):

  • Overlapping Patches。如果像ViT将图像块拆分为N个不重叠块的话,会导致块的局部近邻结构信息无法较好的保持,所以作者提出采用滑动窗口形式生成重叠块。其中重叠区域越大,所提图像块数量越多。
  • Position Embedding。只载入ViT在ImageNet上的预训练模型,而其位置投影的预训练参数不加载(任务不同不通用),即Side Information Embedding(SIE) ,把不同相机和不同视角的信息也编码进去,即若相机编号为 C,则相机embedding为 S(C)S(C)S(C);若视角标签为 VVV,则视角embedding为 S(V)S(V)S(V)。当需要同时使用这两种信息时,采用了联合编码,即 S(C, V)。E=F(p)+p+λS(C,V)E=F(p)+p+\lambda S(C,V)E=F(p)+p+λS(C,V)其实就是特征 embedding+位置的embedding+辅助信息embedding。对应模型图就是position Embedding位置的三个小矩形。
  • Feature Learning。class token作为全局信息输出,然后定义soft-margin三元组损失:LT=log[1+exp(∣∣fa−fp∣∣22−∣∣fa−fn∣∣22)]L_T=log[1+exp(||f_a-f_p||_2^2-||f_a-f_n||_2^2)]LT=log[1+exp(fafp22fafn22)]

然后为了适应ReID任务,模型分为两个分支,分别学习全局信息和局部信息,都是基于刚刚的ViT-BoT。比较重点是局部信息怎么学?即作者提出的 Jigsaw Patch Module(JPM)。具体的做法是,直接将输入特征分为k组,然后送入transformer层中学习k个局部特征,如模型架构的右上角,分组通过移动操作+块置换来完成,然后在每个局部都计算和全局一样的loss,所以最后的loss为:L=LID(fg)+LT(fg)+1k∑(LID(fli)+LT(fli))L=L_{ID}(f_g)+L_T(f_g)+\frac{1}{k}\sum (L_{ID}(f_l^i)+L_T(f_l^i))L=LID(fg)+LT(fg)+k1(LID(fli)+LT(fli))


TransGAN: Designing Pure Transformer-based Architectures for Generative Adversarial NetworksTrans
继续补文。这篇文章是利用Transformer不要CNN能不能直接搭一个GAN呢?模型图如上,基本也是基于ViT,和GAN的思路一致分为生成器和判别器。

  • 生成器:如左图,也是从noise开始生成,然后逐步增加特征图的分辨率+减小每个阶段的嵌入维数,意思就是比如(8x8)xC 变成(16x16)xC/4,图逐渐变大而通道数减少,这样有助于提高图像平滑,减少模糊。最后把特征unflatten就能得到生成的图片了。
  • 判别器:如右图,和ViT一样先把图片切成小块,加入position,然后输入Transformer(默认encoder数目是5、2和2),最后用Head来判别输入是真 or 假。

paper:https://arxiv.org/pdf/2102.07074.pdf
code:https://github.com/VITA-Group/TransGAN


Transformer iN Transformer
ViT采用了标准transformer处理块序列,打破了块间的局部结构关系,如上图a。而TNT可以同时学习图像的全局(patch)与局部信息(pixel),具体来说使用了outer和inner两个模块来做,一个用于跨块操作,一个用于块内像素操作。

  • inner transformer block,用于处理像素嵌入的局部特征,像素级特征通过线性变换投影到块嵌入空间并与块嵌入相加,Zl′i=Zl−1′i+MSA(LN(Zl−1i))Zli=Zl′i+MLP(LN(Zl′i))Z_l^{'i}=Z_{l-1}^{'i}+MSA(LN(Z_{l-1}^{i}))Z_{l}^{i}=Z_{l}^{'i}+MLP(LN(Z_{l}^{'i}))Zli=Zl1i+MSA(LN(Zl1i))Zli=Zli+MLP(LN(Zli)) MSA是自注意力,LN是层归一,MLP是神经网络,该过程构建了任意两个像素之间的相关性。
  • outer transformer block,用于处理块嵌入,Yl′i=Yl−1′i+MSA(LN(Yl−1i))Yli=Yl′i+MLP(LN(Yl′i))Y_l^{'i}=Y_{l-1}^{'i}+MSA(LN(Y_{l-1}^{i}))Y_{l}^{i}=Y_{l}^{'i}+MLP(LN(Y_{l}^{'i}))Yli=Yl1i+MSA(LN(Yl1i))Yli=Yli+MLP(LN(Yli))它用于建模块嵌入之间的相关性。

最后类别token作为图像特征表达,全连接层用于分类。


Is Space-Time Attention All You Need for Video Understanding
把transformer也做到视频理解中吧,TimeSformer 。论文的motivation来自传统的C3D模型对长距离的时空关系捕捉有限(往往只能处理几秒钟),所以作者提出主要的做法是将输入视频抽象成从每个帧中提取的图像 patch 的时间 - 空间序列,然后利用自注意力机制显式地将每个 patch 与视频中的其他 patch 进行比较来捕获每个 patch 的含义,以捕获相邻 patch 之间的短程依赖性(空间)以及远距离 patch 之间的远程关联(时间),看论文的最后结果,模型可以处理几分钟的动作。。

具体看上图的模型架构就行,每个 patch(中间蓝色框)在空间上在单帧的其他patch进行比较(中间红色框),时间上就与每一帧的相同位置进行比较(两边的绿色框)。这样算时空注意力的优势在于时间复杂度变成了T+S,T是时间步数即算时间注意力需要的,S是空间块即算空间注意力的次数。

paper:https://arxiv.org/pdf/2102.05095.pdf


CvT: Introducing Convolutions to Vision Transformers
这个领域出文也真的太快了点,继续补文CvT。CvT的改进重点在于引入卷积到Transformer中以同时保持CNN平移不变性的特点,和Transformer的全局泛化性优势。模型结构图上图,具体来说有两个重要的操作引入了卷积:

  • 包含卷积Token嵌入的Transformer层次结构(绿色部分)。即将Transformer划分为多个阶段(如图中的多个stage),形成一个分层结构的Transformer,每个阶段的开始由一个卷积Token嵌入组成,这种卷积Token嵌入是在一个二维重塑的Token映射上进行卷积操作(即将Flattened的Token序列重塑回空间网格),然后再接LN等后续操作如图b。这个操作使得模型不仅可以捕获局部信息,而且还可以逐步减少序列长度,同时在不同阶段增加Token特征的维数,实现空间下采样,同时增加特征映射的数量。
  • 利用卷积映射的卷积Transformer Block(蓝色部分)。将Transformer模块中每个Self-Attention Block之前的线性投影替换为卷积投影,该卷积投影在二维重塑的Token映射上采用深度可分卷积。这使得该模型在注意力机制中能够进一步捕获局部空间语义信息,减少语义歧义。它还允许管理计算复杂度,因为卷积的Stride可以用于对键和值矩阵进行子采样,以提高4倍或更多的效率,同时最小化性能的损失。

paper:https://arxiv.org/abs/2103.15808
code:https://github.com/leoxiaobin/CvT


CNN与Vision Transformer
回到开篇的那个问题,Transformer是否可以替代CNN呢?两者的区别其实主要在:

  • 动态权重不一样。一个是静态,一个是动态计算。
  • 权重共享不一样。主要是spatial,另一个更灵活多样。
  • 稀疏连接不一样。特别是最近MLP系列的文章也会做channel和spatial的分离和稀疏连接,把self-attention变成local版本的,多尺度低秩正则化等等都证明稀疏是有效的。

所以可能结合两者才是正道?

Transformer in CV的优势?

  • 通用的建模能力。
  • 和卷积形成互补。
  • 更强的建模能力。
  • 对大模型和大数据的可扩展性。
  • 更好地连接视觉和语言。

相关文章博主也整理过了,传送门们:
Vision MLP(MLP-Mixer,RepMLP,ResMLP,gMLP,aMLP)
Vision MLP(CycleMLP,Swin Transformer,ConvMixer)
Cross-modal Transformer
OpenAI CLIP,DALL-E

Vision Transformer(iGPT,ViT,DERT,IPT,TransReID,TransGAN,TNT,CvT)相关推荐

  1. Pyramid Vision Transformer(PVT): 纯Transformer设计,用于密集预测的通用backbone

    论文地址:https://arxiv.org/pdf/2102.12122.pdf 官方代码:https://github.com/whai362/PVT 目录 0.摘要 1.引言 2.相关工作 2. ...

  2. Vision Transformer(ViT)PyTorch代码全解析(附图解)

    Vision Transformer(ViT)PyTorch代码全解析 最近CV领域的Vision Transformer将在NLP领域的Transormer结果借鉴过来,屠杀了各大CV榜单.本文将根 ...

  3. 神经网络学习小记录68——Tensorflow2版 Vision Transformer(VIT)模型的复现详解

    神经网络学习小记录68--Tensorflow2版 Vision Transformer(VIT)模型的复现详解 学习前言 什么是Vision Transformer(VIT) 代码下载 Vision ...

  4. Vision Transformer(ViT)简介理解

    参考:https://gitee.com/mindspore/vision/blob/master/examples/classification/vit/vit.ipynb 模型特点 ViT模型是应 ...

  5. Vision Transformer(ViT)

    1. 概述 Transformer[1]是Google在2017年提出的一种Seq2Seq结构的语言模型,在Transformer中首次使用Self-Atttention机制完全代替了基于RNN的模型 ...

  6. 简单有趣的变形金刚网络(VIT) Vision Transformer(可以直接替换自己数据集)-直接放置自己的数据集就能直接跑(网络结构详解+详细注释代码+核心思想讲解)——pytorch实现

    论文题目: An Image Is Worth 16x16 Words: Transformers For Image Recognition At Scale 原论文下载链接:https://arx ...

  7. vision transformer(viT)教学视频【通俗易懂】

    11.1 Vision Transformer(vit)网络详解_哔哩哔哩_bilibili 文章地址:Vision Transformer详解_霹雳吧啦Wz-CSDN博客 其中两个关键的图

  8. 基于Pyramid Vision Transformer(PVT-v2)实现奥特曼识别

    前言 大家好,我是阿光. 本专栏整理了<PyTorch深度学习项目实战100例>,内包含了各种不同的深度学习项目,包含项目原理以及源码,每一个项目实例都附带有完整的代码+数据集. 正在更新 ...

  9. ICCV2021-PiT-池化操作不是CNN的专属,ViT说:“我也可以”;南大提出池化视觉Transformer(PiT)...

    关注公众号,发现CV技术之美 本文分享一篇 ICCV2021 论文:『Rethinking Spatial Dimensions of Vision Transformers』. 详细信息如下: 论文 ...

最新文章

  1. Python执行精确的浮点数运算
  2. .net语言_Excel处理控件Aspose.Cells v20.3 Java.NET语言开启3月新版功能
  3. jq select操作全集
  4. 何必言精通——十年杂感
  5. eclipse 取消自动括号补全
  6. Amlogic_t962x_android7.1红外遥控驱动浅析
  7. win7上Android环境搭建以及调试
  8. ae怎么卸载已经安装的插件_ae红巨人插件卸载教程!
  9. 金蝶盘点机PDA轻松扫码生产领料,生产型企业进销存条码管理软件
  10. 金融行业网络安全等级保护测评指南
  11. 计算机的声卡怎么安装教程,图文详解如何安装声卡驱动_给电脑安装声卡驱动的详细教程...
  12. 软件测试到底有多重要?
  13. Bug算法(Bug Algorithms)简介(Bug1 Bug2 Tangent Bug)
  14. 微信小程序根据用户当前位置并打开地图选择周边地址,完成外卖地址选择并计算距离
  15. Obsidian看板指北
  16. 情人节表白专用代码,希望你成功
  17. Linux之Xshell工具使用
  18. 【逻辑思维训练 二】系统思维训练
  19. 量化投资和主观投资到底有什么区别?
  20. 数据库连接池之自定义连接池(mysql)

热门文章

  1. 5月~给你的第三封信
  2. Vue——生命周期钩子调用时机
  3. c语言课程设计——影院管理系统
  4. 【计算机网络】网络基础(二)
  5. 苹果字体怎么改_苹果手机的APPLE ID密码忘了怎么改?
  6. 画论01 顾恺之《画云台山记》
  7. VS2017环境下配置OpenGL的简单方法(glut,glew,freeglut,gltools)
  8. 常见三维文件格式之IGES
  9. C# 以管理员权限删除文件
  10. matlab怎样做单值spc,统计过程控制_spc_及MATLAB实现_宋景涛.pdf