终于到transformer了:an image is worth 16X16 words
2026/6/21 16:26:20 网站建设 项目流程

一、VIT的整体架构图

说实话,只看这个整体架构图,即使看了论文,还是不明白这个框架是什么,所以直接debug github 上的 vit-pytorch 中的VIT结构,先学习模型结构,再深入理解背后含义

二、VIT模型结构分解(代码)

2.1 图片变成transformer能吃的token序列

  • 图片分割成很多小path:输入是Bx3x224x224, patch 大小是16x16,那么把Bx3x224x224每个通道都进行path的分割,那么,可以变成 Bx3x14x16x14x16,每个path的大小是16x16x3,一共有Bx14x14个;如果我们按照词向量token的说法来看,把每个path拉成一个向量,patch = 16x16x3=768;
  • **patch内部进行归一化:**对每个path多归一化,让数值稳定,防止训练爆炸;
  • **patch维度线性投影:**使用nn.Linear(pathc_dim,dim) 进行投影,投影前,每个path的768个值是像素值,例如pixel(0,0,R), pixel(0,0,G), pixel(0,0,B),pixel(0,1,R), pixel(0,1,G), pixel(0,1,B), nn.Linear 的每个输出维度,都是所有像素的加权组合。我之前理解的是,把像素空间,上升到语义空间,GhatGPT纠正说,是像素空间,映射到,模型可以学习的表示空间。我觉得这里后面可以再深入理解。

最后,输入 1x3x224 → 1x196x1024

2.2 CLS token(分类 token)

创建一个可学习的token,专门用来做分类

  • self.cls_token是 1x1024 的随机矩阵,这里的1024 就是 第一步中的1024,两个维度要一致
  • 将分类token和图片token序列放一起:x = torch.cat((cls_tokens, x), dim=1)

最后,输入 1x196x1024 → 1x197x1024

2.2 位置编码

  • 给每个token, 包括CLS +path 分配一个 可学习的位置向量,pos_embedding的大小是 197x1024,pos_embedding[0] → CLS token 的位置,pos_embedding[1] → patch 1
  • 为什么需要它:因为transformer 有一个致命特点,对输入顺序不敏感,如果你打乱path,transformer本身看不出来,但是图像时有空间结构的,左上角 和右下角时完全不同的语义,所以位置编码的作用,告诉模型:每个token在图像中的位置
  • x = x + self.pos_embedding[:seq],这句话就是给每个token加上位置信息偏置

疑问:transformer 位置编码如果仔细看,其实就是一个和已经切片过的输入一样大小的参数,例如输入是x = 197x1024 , 位置编码就是 pos = 197x1024的需要学习的参数,然后 x = x + pos, 到底是什么手段,就给pos 赋予了位置编码的意义?
这个问题是我看到位置编码时候的一个疑问,我觉得,任何先进的技术都是从之前的前驱者进化而来的,这个进化的过程,就是对基本理论的理解后,对当前问题的深入探讨后的结果,因此,有时候看论文,第一遍是这是什么,后面就是一遍一遍的问为什么,然后慢慢的去溯源。
如果我是设计者

  • 在1024后面,扩展一为,用做位置id,有197个patch,位置id就是0~196,这样就发现一个问题,就是数值尺度不匹配,前1024个维度,每个维度是像素值的加权组合得到的,数值在[-1,1]之前,位置编码在0到196,位置维度越来越占主导。
  • 使用one-hot,1024维后面加197维度的one-hot
  • 借鉴NLP界的词向量,意思是,单词不要用ID来表示,而是用连续向量来表示,例如:不要用cat = 17 dog = 18, 而是cat = [0.3,0.2…] dog = [0.4, 0.7…] 等,可以让cat 和 dog 在向量空间接近,那么如果单词ID 可以向量化,那么位置是不是也可以向量化

最后,输入 1x197x1024 → 1x197x1024

2.3 Transformer

2.3.1 参数解析

  • depth :深度,有几个transformer block
  • heads:
  • dim_head:

2.3.2 Attention 模块

  • 归一化,稳定训练,让每个token的分布一致
  • 生成Q/K/V:self.to_qkv = nn.Linear(dim, inner_dim * 3, bias = False), 输入 的 1x197x1024 ,通过一个线性函数,输入是 1x197x1024 , 输出是 1x197x(3x1024); 然后通过chunk函数,切成q: 1x197x1024, k:1x197x1024, v:1x197x1024,因为有16个头,所有将上面的q,k,v 都分到16个头上,变成:q: 1x16 x197x64, k:1x16 x197x64, v:1x16 x197x64;
  • 计算 Attention Score(核心):dots = torch.matmul(q, k.transpose(-1, -2)) * self.scale,数学形式 :Attention score = Q · K^T,其中q: 1x16 x197x64, k:1x16 x197x64,1x16 x197x64 * 1x16x64x197 = 1x16x197x197, 可以理解,计算每个patch 之间的关系,有多少个path, 就有多大的矩阵关系。 scale的作用是,防止 结果太大,softmax 饱和, 梯度消失。
  • Softmax(注意力权重):softmax(dim = -1),对 dots 在横向维度上经softmax 计算,也就是每个token对其他token的注意力分布;
  • dropout(正则化):attn = self.dropout(attn), 防止过度依赖某些token;
  • 加权求和(核心输出): out = torch.matmul(attn, v),其实就是对v进行加权求和,得到out的尺度是1x16 x197x64,最后将out变换为1x197x1024的大小;
  • 输出投影:return self.to_out(out),Linear(D → D),融合多头信息

2.3.3 FeedForward模块

FeedForward 模块 是在self-attention 后面,增加一个这个模块,self-attention:建模token之间关系,FeedForward:增强token自身表达能力 self.net = nn.Sequential( nn.LayerNorm(dim), nn.Linear(dim, hidden_dim), nn.GELU(), nn.Dropout(dropout), nn.Linear(hidden_dim, dim), nn.Dropout(dropout)

)

最后,输入 1x197x1024 → 1x197x1024

2.4 VIT 中可以有多层transformer


最后,输入 1x197x1024 → 1x197x1024

2.5 VIT 中最终分类向量

x = x.mean(dim = 1) if self.pool == ‘mean’ else x[:, 0]
用第197个 1024的向量做最终分类向量

最后,输入 1x197x1024 → 1x1024

2.6 VIT 中占位符

self.to_latent = nn.Identity()
x = self.to_latent(x)
ViT 结构里其实是一个非常标准的工程设计占位符(hook / switch点),当前不做任何变换,但预留一个可替换的接口,Identity的真实作用,不是计算,而是留一个未来可插拔的层。

2.7 VIT 中类别估计

self.mlp_head(x)
self.mlp_head = nn.Linear(dim, num_classes) if num_classes > 0 else None
这个就是我们常见的,估计类别的操作,很好理解

三、VIT论文阅读理解

论文里面关于transformer 结构的部分,这里就不再重复描述了,重点是论文里面说的image-specific inductive bias
CNN有很强的图像先验:

  • 局部性,CNN的卷积核只看一个小窗口,比如3x3,意味着模型一开始就被设计成:只关心附近像素,不会一上来就看全图,着非常符合自然图像,一个物体的边缘、纹理,都是局部结构;
  • 二维领域结构,卷积操作时严格在2D网格上滑动的,左右时空间邻近,上下也是空间临近,CNN天生知道图像是二维的;
  • 平移等变性,注意和平移不变区分,CNN的严格性质是平移等变性,即如果输入平移了,输出特征图也会平移;平移不变性是,猫在左边,输出是猫,猫在右边,输出还是猫;CNN没有严格的不变性,但是可以通过结构+操作变得近似不变,pooling 层丢掉精确位置信息,GAP强烈增强不变性,分类头,最终输出不关心空间位置。

但是VIT只有一堆token,token之间可以任意交互,空间关系完全没定义,没有空间感的语言模式,所有VIT需要特别更大的数据量

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询