Transformer在NLP任务中表现很好,但是在CV任务中应用还很有限,基本都是作为CNN的一个辅助,Vit尝试使用纯Transformer结构解决CV的任务,并成功将其应用到了CV的基本任务--图像分类中。

因此,简单而言,这篇论文的主旨就是,用Transformer结构完成图像分类任务。

结构概述

基本结构如下:

核心要点:

  • 图像切patch
  • Patch0
  • Position Embedding
  • Multi-Head Attention

图像切patch

在NLP任务中,将自然语言使用Word2Vec转为向量(Embedding)送入模型进行处理,在CV中没有对应的序列化token,因此作者采用将原始图像切分为多个小块,然后将每个小块儿内的信息展平的方式。

假设输入的shape为:(1, 3, 288, 288)

切分为9个小块,则每个小块的shape为:(1, 3, 32, 32)

然后将每个小块展平,则每个小块为(1, 3072),有9个小块,所以Linear Projection of Flattened Patched的shape为:(1, 9, 3072)输出shape为(1, 9, 1024),再加上Position Embedding,Transformer Encoder的输入shape为(1, 10, 1024),也就是图中Embedded Patches的shape。

Patch0

为什么需要有Patch0?

这是因为需要对1-9个patches信息的整合,最后送入MLP Head的只有Patch0。

Position Embedding

图像被切分和展开后,丢失了位置信息,对于图像处理任务来说,这是很怪异的,因此,作者这里采用在每个Patch上增加一个位置信息的方式,将位置信息纳入考虑。

Multi-Head Attention

参考Attention的基本结构。[Todo, Link]

代码[Pytorch]

使用repo pytorch_vit

import torch
from vit_pytorch import ViT v = 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) preds = v(img)
print(preds.shape) # 1000,与ViT定义的num_classes一致

ViT类参数解析:

  • dim:Linear Projection的输出维度:1024
  • depth:有多少个Transformer Blocks
  • heads:Multi-Head的Head数
  • mlp_dim:Transformer Encoder内部的MLP的维度
  • dropout
  • ......

ViT的forward函数:

def forward(self, img):
x = self.to_patch_embedding(img)
b, n, _ = x.shape cls_tokens = repeat(self.cls_token, '1 1 d -> b 1 d', b = b)
x = torch.cat((cls_tokens, x), dim=1)
x += self.pos_embedding[:, :(n + 1)]
x = self.dropout(x) x = self.transformer(x) x = x.mean(dim = 1) if self.pool == 'mean' else x[:, 0] x = self.to_latent(x)
return self.mlp_head(x)

输入端的切分主要由下面这句话完成:

x = self.to_patch_embedding(img)

==>

self.to_patch_embedding = nn.Sequential(
Rearrange('b c (h p1) (w p2) -> b (h w) (p1 p2 c)', p1 = patch_height, p2 = patch_width),
nn.LayerNorm(patch_dim),
nn.Linear(patch_dim, dim),
nn.LayerNorm(dim),
)
#由传入参数: image_size = 256, patch_size = 32
# Rearrange完成的shape变换为(b, c, 256, 256) -> (b, 64, 1024*c)
# nn.LayerNorm
# nn.Linear: (b, 64, 1024*c) --> (b, 64, 1024)

Rearrange用更加可理解的方式实现transpose的功能:

We don't write:

y = x.transpose(0, 2, 3, 1)

We write comprehensible code:

y = rearrange(x, 'b c h w -> b h w c')

ViT简述【Transformer】的更多相关文章

  1. VIT Vision Transformer | 先从PyTorch代码了解

    文章原创自:微信公众号「机器学习炼丹术」 作者:炼丹兄 联系方式:微信cyx645016617 代码来自github [前言]:看代码的时候,也许会不理解VIT中各种组件的含义,但是这个文章的目的是了 ...

  2. ICCV2021 | Tokens-to-Token ViT:在ImageNet上从零训练Vision Transformer

    ​  前言  本文介绍一种新的tokens-to-token Vision Transformer(T2T-ViT),T2T-ViT将原始ViT的参数数量和MAC减少了一半,同时在ImageNet上从 ...

  3. Transformer详解

    0 简述 Transformer改进了RNN最被人诟病的训练慢的缺点,利用self-attention机制实现快速并行. 并且Transformer可以增加到非常深的深度,充分发掘DNN模型的特性,提 ...

  4. 从零搭建Pytorch模型教程(三)搭建Transformer网络

    ​ 前言 本文介绍了Transformer的基本流程,分块的两种实现方式,Position Emebdding的几种实现方式,Encoder的实现方式,最后分类的两种方式,以及最重要的数据格式的介绍. ...

  5. 论文阅读 | Transformer-XL: Attentive Language Models beyond a Fixed-Length Context

    0 简述 Transformer最大的问题:在语言建模时的设置受到固定长度上下文的限制. 本文提出的Transformer-XL,使学习不再仅仅依赖于定长,且不破坏时间的相关性. Transforme ...

  6. attention、self-attention、transformer和bert模型基本原理简述笔记

    attention 以google神经机器翻译(NMT)为例 无attention: encoder-decoder在无attention机制时,由encoder将输入序列转化为最后一层输出state ...

  7. ICCV2021 | TransFER:使用Transformer学习关系感知的面部表情表征

    ​  前言  人脸表情识别(FER)在计算机视觉领域受到越来越多的关注.本文介绍了一篇在人脸表情识别方向上使用Transformer来学习关系感知的ICCV2021论文,论文提出了一个TransFER ...

  8. ICCV2021 | PnP-DETR:用Transformer进行高效的视觉分析

    ​  前言  DETR首创了使用transformer解决视觉任务的方法,它直接将图像特征图转化为目标检测结果.尽管很有效,但由于在某些区域(如背景)上进行冗余计算,输入完整的feature maps ...

  9. pycaffe︱caffe中fine-tuning模型三重天(函数详解、框架简述)

    本文主要参考caffe官方文档[<Fine-tuning a Pretrained Network for Style Recognition>](http://nbviewer.jupy ...

  10. 带你读Paper丨分析ViT尚存问题和相对应的解决方案

    摘要:针对ViT现状,分析ViT尚存问题和相对应的解决方案,和相关论文idea汇总. 本文分享自华为云社区<[ViT]目前Vision Transformer遇到的问题和克服方法的相关论文汇总& ...

随机推荐

  1. Kubernetes(K8S) 配置管理-ConfigMap 介绍

    作用:存储不加密数据到 etcd,让 Pod 以变量或者 Volume 挂载到容器中 场景:配置文件 创建配置文件 redis.properties redis.host=127.0.0.1 redi ...

  2. 【kafka】JDBC source&sink connect实现数据从Oracle实时同步插入更新到PostgreSQL(PG)

    〇.所需资料 1.JDBC connect的plugins下载地址(confluent) 一.Oracle建表 1.表规划 表名:Test_TimeFormat_Order.Test_Stress_O ...

  3. Go 每日一库之 go-carbon,优雅的golang日期时间处理库

    Carbon 是一个轻量级.语义化.对开发者友好的 golang 时间处理库,支持链式调用. Carbon 已被 awesome-go 收录, 如果您觉得不错,请给个 star 吧. github.c ...

  4. React报错之Function components cannot have string refs

    总览 当我们在一个函数组件中使用一个字符串作为ref时,会产生"Function components cannot have string refs"错误.为了解决该错误,使用u ...

  5. Windows上使用QEMU创建银河麒麟ARM64虚拟机完全手册

    "好记性不如烂笔头." -- 张溥 0x00 大纲 目录 0x00 大纲 0x01 前言 0x02 物料准备 0x03 安装 QEMU 0x04 创建虚拟磁盘 0x05 安装麒麟系 ...

  6. 2022的ShellCTF之web_WP

    Extractor: 考点是SQL注入,不过数据库不是mysql,而是sqlite 首先尝试了:1' or 1=1# 尝试1' or 1=1 -- 发现有东西,使用 :order by 判断列表,知道 ...

  7. 利用WordPress搭建属于自己的网站

    怎么用WordPress给自己搭建了一个网站?可能很多人都想拥有属于自己的网站,这篇文章就找你怎么利用WordPress搭建属于自己的网站.如果你也正好有搭建个人网站的想法,那么本文会给你一个参考,我 ...

  8. [python] 向量检索库Faiss使用指北

    Faiss是一个由facebook开发以用于高效相似性搜索和密集向量聚类的库.它能够在任意大小的向量集中进行搜索.它还包含用于评估和参数调整的支持代码.Faiss是用C++编写的,带有Python的完 ...

  9. Redis-01 常用命令

    创建和获取 key 命令 说明 例子 set 创建一个名为 key 值为 value 键值对 set views 10 get 获取名为 key 的值,存在返回值,不存在返回 nil get view ...

  10. 深入理解C++虚函数底层机制和RTTI运行时类型识别

    当调用一个虚函数时,被执行的代码必须与调用函数对象的动态类型相一致:指向对象的指针或引用的类型是不重要的,编译器是如何高效地提供这种行为呢?大多数编译器是使用virtual table和virtual ...