Vision Transformer (ViT) 基本原理
flyfish
Vision Transformer (ViT) 是一种基于 Transformer 架构的计算机视觉模型
一、ViT 的基本原理
ViT 的核心思想是将一张图像视为一组序列,将其嵌入到 Transformer 的输入中,通过自注意力机制捕获全局上下文信息,从而进行分类或其他视觉任务。
- 传统卷积神经网络 (CNN): 使用卷积核逐层提取局部特征,通常关注图像的局部模式。
- ViT 的创新点: 不使用卷积操作,而是将图像划分为小块 (patches),通过 Transformer 模型直接处理全局特征。
二、ViT 的核心架构
1. 输入处理
1.1 图像分块 (Patch Partitioning)
将输入图像 x ∈ R H × W × C x \in \mathbb{R}^{H \times W \times C} x∈RH×W×C ( H H H: 高, W W W: 宽, C C C: 通道数)分割为 N N N 个固定大小的图像块 (patch)。
每个 patch 的大小为 P × P P \times P P×P,则总的 patch 数量为:
N = H P × W P N = \frac{H}{P} \times \frac{W}{P} N=PH×PW
每个 patch 被展平成向量,形状为 R P 2 ⋅ C \mathbb{R}^{P^2 \cdot C} RP2⋅C。
1.2 Patch 嵌入 (Patch Embedding)
通过一个线性投影将每个 patch 转换为 D D D-维的向量:
z 0 = [ z 0 1 , z 0 2 , … , z 0 N ] 其中 z 0 i ∈ R D z_0 = [z_0^1, z_0^2, \dots, z_0^N] \quad \text{其中 } z_0^i \in \mathbb{R}^D z0=[z01,z02,…,z0N]其中 z0i∈RD
公式:
z 0 i = W e ⋅ Flatten ( x i ) + b e z_0^i = W_e \cdot \text{Flatten}(x_i) + b_e z0i=We⋅Flatten(xi)+be
其中, W e W_e We 是嵌入权重, b e b_e be 是偏置。
1.3 加入位置编码 (Positional Encoding)
因为 Transformer 缺乏对序列顺序的感知,需要加入位置编码:
z 0 = z 0 + E p o s z_0 = z_0 + E_{pos} z0=z0+Epos
E p o s ∈ R N × D E_{pos} \in \mathbb{R}^{N \times D} Epos∈RN×D 是位置编码矩阵。
2. Transformer 编码器 (Transformer Encoder)
Transformer 编码器由多层组成,每层包含两个主要模块:
2.1 多头自注意力机制 (Multi-Head Self-Attention, MHSA)
自注意力机制的核心思想是捕捉输入序列中每个元素与其他元素之间的关系。
计算步骤:
-
对输入 z l − 1 ∈ R N × D z_{l-1} \in \mathbb{R}^{N \times D} zl−1∈RN×D 进行线性变换得到 Q , K , V Q, K, V Q,K,V:
Q = z l − 1 W Q , K = z l − 1 W K , V = z l − 1 W V Q = z_{l-1}W_Q, \quad K = z_{l-1}W_K, \quad V = z_{l-1}W_V Q=zl−1WQ,K=zl−1WK,V=zl−1WV -
计算注意力权重:
Attention ( Q , K , V ) = softmax ( Q K ⊤ D k ) V \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^\top}{\sqrt{D_k}}\right)V Attention(Q,K,V)=softmax(DkQK⊤)V其中, D k D_k Dk 是 Q Q Q 和 K K K 的维度,用于缩放防止梯度爆炸。
-
多头注意力的输出为:
MHSA ( z l − 1 ) = [ head 1 , … , head h ] W O \text{MHSA}(z_{l-1}) = [\text{head}_1, \dots, \text{head}_h]W_O MHSA(zl−1)=[head1,…,headh]WOW Q , W K , W V , W O W_Q, W_K, W_V, W_O WQ,WK,WV,WO 是学习参数, h h h 是注意力头数。
2.2 前向全连接层 (Feed-Forward Network, FFN)
每个位置的特征通过一个两层全连接网络进行变换:
FFN ( x ) = ReLU ( x W 1 + b 1 ) W 2 + b 2 \text{FFN}(x) = \text{ReLU}(xW_1 + b_1)W_2 + b_2 FFN(x)=ReLU(xW1+b1)W2+b2
2.3 残差连接与归一化
每个模块后有残差连接和 LayerNorm:
z l ′ = LayerNorm ( z l − 1 + MHSA ( z l − 1 ) ) z_l' = \text{LayerNorm}(z_{l-1} + \text{MHSA}(z_{l-1})) zl′=LayerNorm(zl−1+MHSA(zl−1))
z l = LayerNorm ( z l ′ + FFN ( z l ′ ) ) z_l = \text{LayerNorm}(z_l' + \text{FFN}(z_l')) zl=LayerNorm(zl′+FFN(zl′))
3. 分类头 (Classification Head)
通过一个 learnable 的分类标记 z cls z_{\text{cls}} zcls 获取全局特征,最后用全连接层输出分类结果:
y = softmax ( W h e a d ⋅ z cls + b h e a d ) y = \text{softmax}(W_{head} \cdot z_{\text{cls}} + b_{head}) y=softmax(Whead⋅zcls+bhead)
三、与传统 Transformer 的主要区别
-
输入类型:
- 传统 Transformer: 输入为一维序列(如词向量)。
- ViT: 输入为二维图像分块。
-
位置编码:
- 传统 Transformer: 通常使用正弦或可学习的位置编码。
- ViT: 通常直接添加 learnable 的二维位置编码。
-
任务目标:
- 传统 Transformer: 多用于 NLP 任务(如翻译、文本分类)。
- ViT: 多用于视觉任务(如图像分类、目标检测)。
四、ViT 中的注意力机制如何运作
ViT 的注意力机制核心是 自注意力 (Self-Attention),通过计算每个 patch 之间的相关性,捕获全局信息。
1. 自注意力权重的计算
α i j = exp ( q i ⋅ k j D k ) ∑ j = 1 N exp ( q i ⋅ k j D k ) \alpha_{ij} = \frac{\exp\left(\frac{q_i \cdot k_j}{\sqrt{D_k}}\right)}{\sum_{j=1}^N \exp\left(\frac{q_i \cdot k_j}{\sqrt{D_k}}\right)} αij=∑j=1Nexp(Dkqi⋅kj)exp(Dkqi⋅kj)
其中:
- α i j \alpha_{ij} αij 表示 patch i i i 对 j j j 的注意力权重。
- q i q_i qi 和 k j k_j kj 分别是 query 和 key 向量。
2. 输出特征的加权求和
Attention ( Q , K , V ) = ∑ j = 1 N α i j v j \text{Attention}(Q, K, V) = \sum_{j=1}^N \alpha_{ij} v_j Attention(Q,K,V)=j=1∑Nαijvj
五、示例计算流程
假设输入图像大小为 224 × 224 × 3 224 \times 224 \times 3 224×224×3,每个 patch 大小为 16 × 16 16 \times 16 16×16,则:
- 总 patch 数 N = 224 16 × 224 16 = 196 N = \frac{224}{16} \times \frac{224}{16} = 196 N=16224×16224=196。
- 每个 patch 被展平为向量,形状为 16 × 16 × 3 = 768 16 \times 16 \times 3 = 768 16×16×3=768。
- 经过线性投影后,转换为 D D D-维(如 D = 768 D=768 D=768)。
经过多层 Transformer 编码器后,分类标记 z cls z_{\text{cls}} zcls 被用于分类。
ViT 是计算机视觉领域的重要进步,通过将 Transformer 应用于图像任务,突破了传统 CNN 的局限,在大规模数据集上表现出色。
Vision Transformer (ViT) 整体流程
图像处理流程:
图像切分 Patch → Patch 序列化 → Patch + Position Embedding → Transformer Encoder → MLP Head → 分类结果
- 输入预处理:将图像划分为固定大小的 Patch,转化为 Token 序列,加入 [CLS] Token 和位置编码,形成符合 Transformer 的输入格式。
- Transformer Encoder:通过自注意力机制捕获全局特征,堆叠多个编码器以提取深层次特征。
- 分类头:利用 [CLS] Token 表示全局特征,通过 MLP 进行分类。
详细些就是
首先,要对图像进行切分操作,将完整的图像切割成一个个的小部分,也就是所谓的 “Patch”。
接着,把这些切分好的 “Patch” 按照一定顺序进行序列化处理,使其能够以有序的形式来参与后续的流程。
然后,为序列化后的 “Patch” 添加上位置嵌入信息(Position Embedding),通过这样的方式让模型能够知晓每个 “Patch” 在图像中的位置情况,便于后续准确地处理。
之后,把带有位置嵌入的 “Patch” 送入到 Transformer Encoder 当中,Transformer Encoder 会运用其自身的机制对输入的内容进行特征提取等相关处理,进一步挖掘和分析其中蕴含的特征信息。
再之后,经过 Transformer Encoder 处理后的结果会传递到多层感知机头部(MLP Head),由多层感知机对这些特征做进一步的整合、变换等操作。
最终,经过前面一系列的处理后,多层感知机头部输出相应的分类结果,以此来判断图像属于哪一类别的内容。
1. 图像切分 Patch
给定一张 RGB 图像,尺寸为 ( 224 , 224 , 3 ) (224, 224, 3) (224,224,3),假设 Patch 的大小为 16 × 16 16 \times 16 16×16:
-
Patch 数量:
N = 22 4 2 1 6 2 = 196 N = \frac{224^2}{16^2} = 196 N=1622242=196 -
每个 Patch 的尺寸:
每个 Patch 为 ( 16 , 16 , 3 ) (16, 16, 3) (16,16,3),展开后为一维向量,维度大小为:
16 × 16 × 3 = 768 16 \times 16 \times 3 = 768 16×16×3=768 -
线性嵌入矩阵:
使用一个线性投影矩阵将每个 Patch 映射到 D D D-维嵌入空间,这里 D = 768 D = 768 D=768。嵌入后的 Patch 表示为 ( 196 , 768 ) (196, 768) (196,768)。
处理到这里,已经将原始的视觉问题转化为 NLP 问题:输入序列由一系列一维的 Token 表示。
2. [CLS] Token
ViT 借鉴了 BERT 中的 [CLS] 特殊 Token,用于表示整个图像的全局信息:
- [CLS] Token 的位置信息始终固定为 0,但通过注意力机制,它能够与所有的 Patch Token 交互,从而获取全局特征。
- 在 [CLS] Token 的基础上,仅需根据其输出的嵌入来进行最终分类任务。
加入 [CLS] Token 后,输入序列长度由 196 196 196 变为 197 197 197,输入维度变为:
( 197 , 768 ) (197, 768) (197,768)
实验对比:ViT 对比了两种获取全局特征的方式:[CLS] Token 和 Global Average Pooling (GAP)。实验表明二者效果相当,但为了与原始 Transformer 保持一致,ViT 选择了 [CLS] Token。
3. 位置编码 (Positional Embedding)
Transformer 缺乏对序列位置信息的直接感知,因此需要加入位置编码:
- 对每个 Patch 编号(1~196),通过映射表生成一个 768 维的位置向量作为位置编码。
- 位置编码与 Patch 的嵌入直接相加,得到最终送入 Transformer 的向量,维度仍为 ( 197 , 768 ) (197, 768) (197,768)。
实验对比:
ViT 探索了多种位置编码方式,包括:
- 一维位置编码 (1D Positional Embedding)
- 二维位置编码 (2D Positional Embedding)
- 相对位置编码 (Relative Positional Embedding)
结果表明三者均能很好地学习位置信息,这可能是因为 ViT 处理的是 Patch-Level 而非 Pixel-Level 的特征,Patch 数量较少(196 个),学习位置关系较为简单。
4. Transformer 编码器 (Transformer Encoder)
经过上述数据预处理,得到输入矩阵:
Input: ( 197 , 768 ) \text{Input: } (197, 768) Input: (197,768)
Transformer Encoder 的组成:
-
多头自注意力机制 (Multi-Head Self-Attention, MHSA):
- 输入序列 ( 197 , 768 ) (197, 768) (197,768) 通过线性变换生成 Q , K , V Q, K, V Q,K,V 三组矩阵,维度分别为 ( 197 , 768 ) (197, 768) (197,768)。
- 假设有 H = 12 H=12 H=12 个注意力头,每个头的维度为 768 12 = 64 \frac{768}{12} = 64 12768=64。通过线性投影,降维得到 ( 197 , 64 ) (197, 64) (197,64) 的表示。
- 每个头独立计算注意力,输出 H H H 个 ( 197 , 64 ) (197, 64) (197,64) 矩阵,最后拼接成 ( 197 , 768 ) (197, 768) (197,768)。
-
前向全连接网络 (MLP):
通常包含两层全连接层,伴随激活函数:
( 197 , 768 ) → 升维 ( 197 , 3072 ) → 降维 ( 197 , 768 ) (197, 768) \xrightarrow{\text{升维}} (197, 3072) \xrightarrow{\text{降维}} (197, 768) (197,768)升维(197,3072)降维(197,768) -
残差连接和归一化:
每个模块后通过残差连接和 LayerNorm,使输入输出维度一致,便于堆叠多个 Transformer Block。
经过一个 Transformer Block 后,输入维度从 ( 197 , 768 ) (197, 768) (197,768) 转换为相同的 ( 197 , 768 ) (197, 768) (197,768),可以堆叠多个 Block(例如 ViT-B 中堆叠 12 层)。
5. 分类头 (MLP Head)
最终通过 Transformer 编码器得到的 [CLS] Token 表示 z c l s z_{cls} zcls,维度为 ( 1 , 768 ) (1, 768) (1,768)。
通过全连接层生成最终的分类结果:
Output: softmax ( W ⋅ z c l s + b ) \text{Output: } \text{softmax}(W \cdot z_{cls} + b) Output: softmax(W⋅zcls+b)