Transformer


这是一篇关于Transformer以及变种Vision Transformer,Diffusion Transformer的粗浅解析文章,仅代表作者个人理解,可能存在很多谬误,还望理解。


Transformer

标准的 Transformer 由两大部分组成:

  1. 编码器 (Encoder): 负责理解输入序列(如一句话的中文部分),将其转化为一个高级的、上下文丰富的语义表示(Semantic Representation)。它通常由 $N$ 个相同的编码器层堆叠而成。

  2. 解码器 (Decoder): 负责接收编码器的输出,并结合自身的前一个输出,逐步生成目标序列(如对应句子的英文部分)。它通常也由 $N$ 个相同的解码器层堆叠而成。


核心组件:编码器层(Encoder Layer)

每个编码器层(Encoder Block)的结构非常简洁,主要包含两个子层:

1. 多头自注意力机制(Multi-Head Self-Attention, MHA)

这是 Transformer 的核心,负责计算序列中所有元素之间的依赖关系,并生成上下文向量。

🔹 Q, K, V 的生成与计算

对于输入 $\mathbf{X}$:

  1. 输入映射: 通过三个训练好的权重矩阵 $\mathbf{W}_Q, \mathbf{W}_K, \mathbf{W}_V$ 将输入 $\mathbf{X}$ 线性投影到 $Q$ (Query), $K$ (Key), $V$ (Value) 三个不同的特征空间。

  1. 注意力分数计算(Scaled Dot-Product Attention):

    • 相关性得分: $\mathbf{Q}$ 与 $\mathbf{K}$ 的转置相乘,得到一个相关性得分矩阵。

    • 缩放: 除以 $\sqrt{d_k}$($d_k$ 是 $K$ 的维度),防止点积结果过大导致 Softmax 梯度过小。

    • 归一化: 使用 Softmax 函数将得分转换为 $0 \sim 1$ 的权重(Attention Map)。

    • 加权求和: 用这些权重与 $\mathbf{V}$ 相乘,得到注意力输出 $\mathbf{Z}$。

🔹 多头机制 (Multi-Head)

模型不是只进行一次注意力计算,而是并行地进行 $h$ 次独立的注意力计算(即 $h$ 个“头”)。

  1. 分割: $\mathbf{Q}, \mathbf{K}, \mathbf{V}$ 被分割成 $h$ 份(即 $h$ 个头)。

  2. 并行计算: 每个头独立计算注意力输出 $\mathbf{Z}_i$。

  3. 拼接与投影: 将所有 $\mathbf{Z}_i$ 拼接起来,并通过另一个训练好的权重矩阵 $\mathbf{W}_O$ 进行线性投影,得到最终的多头注意力输出。

前馈网络(Feed-Forward Network, FFN)

这是一个标准的两层全连接网络,对自注意力机制的输出 $\mathbf{Z}$ 中的 每一个位置(Token/Patch) 独立地进行非线性变换。

  • 公式:
  • FFN 通常使用 ReLU 激活函数,其内部维度通常会比输入输出维度 $d_{model}$ 大四倍(如 $d_{ff} = 4 \cdot d_{model}$)。它负责对信息进行深度加工和特征提取。

残差连接与层归一化(Residual Connection & Layer Normalization)

为了确保信息在深层网络中稳定流动:

  • 残差连接 (Residual Connection): 将子层的输入 $\mathbf{x}$ 直接加到子层的输出 $\text{Sublayer}(\mathbf{x})$ 上,即 $\mathbf{x} + \text{Sublayer}(\mathbf{x})$。这有助于防止梯度消失,加速训练。

  • 层归一化 (Layer Normalization): 在残差连接后,对序列维度(每个 Token 的特征维度)进行归一化。

整个编码器层的最终输出为:


核心组件:解码器层(Decoder Layer)

解码器层比编码器层多了一个交叉注意力机制,主要包含三个子层:

1. 掩码多头自注意力(Masked Multi-Head Self-Attention)

功能与编码器的自注意力相同,但增加了一个掩码(Mask)机制:

  • 在 Softmax 之前,对当前 Token 之后的所有 Token 的得分设置为 $-\infty$(即权重为 0)。

  • 目的: 确保在生成第 $t$ 个 Token 时,模型只能看到第 $1$ 到 $t-1$ 个 Token,从而维持序列生成任务的因果性(Autoregressive)。

2. 多头交叉注意力(Multi-Head Cross-Attention)

该层连接了编码器和解码器,负责从编码器的输出中提取相关信息。

  • Q 向量: 来自解码器前一层的输出(即解码器的自我理解)。

  • K 和 V 向量: 来自编码器的最终输出(即输入序列的全局语义表示)。

  • 目的: 让解码器知道在生成当前词时,应该“关注”输入序列中的哪些部分。

3. 前馈网络(FFN)与归一化

结构与编码器层中的完全相同。


四、输入与输出:位置编码与线性层

1. 词嵌入(Embedding)

输入序列的每个 Token(或 ViT 中的 Patch)被转换为一个 $d_{model}$ 维的向量。

2. 位置编码(Positional Encoding, PE)

由于自注意力机制是并行计算,它无法感知序列中 Token 的位置信息。因此,Transformer 必须显式地加入位置编码。

  • 实现方式: 将位置编码向量 直接加到 词嵌入向量上。
  • 编码方法: 原始论文使用固定的正弦和余弦函数来计算位置编码:

  • $pos$ 是位置索引,$i$ 是维度索引。这种编码能让模型学习到相对位置信息。

3. 输出线性层与 Softmax

解码器最终的输出向量经过一个线性层(Linear Layer) 和一个 Softmax 层:

  1. 线性层: 将解码器的输出向量投影回词汇表的大小 $\mathbf{V}_{vocab}$。

  2. Softmax 层: 将线性层的输出转化为每个词汇的概率分布。

组件名称 所在层次 详细定位 核心功能
词嵌入 (Embedding) 输入层 / 输出层 编码器输入、解码器输入、解码器输出 将符号(Token)转化为数值向量
位置编码 (PE) 输入层 / 输出层 编码器输入、解码器输入 引入序列中元素的顺序信息
编码器层 (Encoder Layer) 编码器堆栈 ($N$ 个) - 提取输入序列的上下文语义
多头自注意力 (MHA) 编码器层 / 解码器层 1. 编码器子层 2. 解码器第一个子层 (带掩码) 计算输入序列内部的依赖关系
多头交叉注意力 (MHA) 解码器层 解码器第二个子层 连接编码器和解码器,关注输入语义
前馈网络 (FFN) 编码器层 / 解码器层 编码器第二个子层、解码器第三个子层 对每个位置的特征进行非线性加工
残差连接 & LayerNorm 贯穿始终 每个子层之后(注意力/FFN) 稳定信息流,防止梯度消失
线性层 & Softmax 输出层 解码器末端 预测目标词汇的概率分布

Vision Transformer

ViT 是将 Transformer 架构从自然语言处理(NLP)领域成功引入计算机视觉(CV)领域的开创性工作。它证明了 Transformer 可以直接应用于图像分类任务,而无需依赖传统的卷积神经网络(CNN)。

核心思想: 将一张图片视为一个序列,将图像的局部小块(Patch)视为序列中的一个个“词汇”(Token),然后将这个序列输入到标准的 Transformer 编码器中进行处理。

一、宏观架构与数据流

ViT 的整体架构主要由三大部分组成:

  1. 输入处理(Embedding Layer): 负责将原始图像转换为 Transformer 编码器所需的一维序列

  2. Transformer 编码器(Encoder): 由多个标准的 Transformer 编码器层堆叠而成,负责捕获 Patch 之间的全局依赖关系

  3. 分类头(Classification Head): 位于编码器输出端,负责基于学习到的特征进行最终的分类预测


二、输入处理:将图像序列化

这是 ViT 与传统 Transformer 最主要的区别所在。

1. 图像分块(Patch Embedding)

  • 操作: 将输入的 $H \times W \times C$(高 $\times$ 宽 $\times$ 通道)图像,分割成 $N$ 个不重叠的、固定大小的图像块(例如 $16 \times 16$ 像素)。

    • 如果图像大小是 $256 \times 256$,Patch 大小是 $16 \times 16$,则总共会得到 $N = (256/16) \times (256/16) = 16 \times 16 = 256$ 个 Patch。
  • 展平(Flattening): 每个 $P \times P \times C$ 的 Patch 被展平为一个长向量。

  • 线性投影(Linear Projection): 展平后的向量通过一个可学习的线性层(类似全连接层),将其映射到 Transformer 的特征维度 $D$(例如 $D=768$)。

2. 分类标记

$CLS$ Token

  • 操作: 在 Patch 序列的最前面,添加一个特殊的、可学习的向量,称为 Class Token
    $CLS$ Token。

  • 功能: 这个 Token 不对应图像的任何部分,但它将通过自注意力机制与所有图像 Patch 交互,汇聚整个图像的全局信息。最终,模型将只使用这个 Class Token 的输出进行分类。

3. 位置嵌入(Positional Embedding)

  • 操作: 为序列中的每一个元素(包括$CLS$ Token 和所有 Patch ),添加一个可学习的位置编码向量。

  • ViT 的特点: 与原始 Transformer 使用固定的正弦/余弦函数不同,ViT 通常使用可学习的位置嵌入。

  • 功能: 告诉模型每个 Patch 在原始图像中的空间位置

至此,图像被转换成一个 $N+1$ 个向量组成的序列,维度为 $(N+1) \times D$,准备送入 Transformer 编码器。


三、核心处理:Transformer 编码器

ViT 采用标准的 Transformer 编码器堆栈

  • 结构: 堆栈由 $L$ 个相同的编码器层组成。

  • 编码器层组成:

    • 多头自注意力(MHA): 计算序列中 Patch 与 Patch 之间 的依赖关系。例如,它可以捕捉到图片中“狗的头” Patch 与“狗的身体” Patch 之间的关联。

    • 前馈网络(FFN): 对 MHA 的输出进行非线性加工。

    • 残差连接和 LayerNorm: 保持信息稳定流动。

与 NLP 的区别: 编码器处理的不再是词语间的语法和语义关系,而是图像局部区域(Patch)间的空间和特征关系


四、输出与分类(Classification Head)

1. 提取CLS Token

  • 操作: 忽略所有 Patch 对应的输出向量,只提取最后一个编码器层
    $CLS$ Token 对应的输出向量 $$\mathbf{Z}_{CLS}$。

2. 分类预测

  • 操作: $\mathbf{Z}_{CLS}$ 向量通常通过一个简单的 多层感知机(MLP) 分类头,进行最终的分类预测。

总结 ViT 的创新点

特点 描述 意义
Patch 序列化 将 2D 图像无缝转换为 1D 序列。 使图像数据能够直接利用 Transformer 强大的序列建模能力。
全局自注意力 通过 MHA 计算所有 Patch 之间的关系。 捕获长距离依赖,优于传统 CNN 的局部感受野。
CLS Token 引入一个特殊的 Token 汇聚全局信息。 提供一个简洁的分类接口,将所有 Patch 的上下文信息汇总到一点进行预测。
可学习位置编码 使用可学习的 PE 而非固定的 PE。 实验证明这在图像任务中表现更好,更能适应不同的输入分辨率。

Diffusion Transformer

核心思想: DiT 的主要贡献在于,它用一个 ViT 骨干网络 替换了传统扩散模型中用于去噪的 U-Net 骨干网络,从而将 Transformer 强大的全局建模能力引入图像生成任务。

一、DiT 的背景:潜扩散模型与去噪

DiT 并非直接作用于原始像素,而是通常用于潜在扩散模型 (Latent Diffusion Models, LDM) 中,如 Stable Diffusion。

  1. 潜在空间 (Latent Space): 原始高分辨率图像首先通过一个编码器(Encoder)压缩成一个低维的、信息量更丰富的潜在表示 (Latent Representation)。DiT 在这个潜在空间中工作,大大提高了计算效率。

  2. 去噪任务: 扩散模型的核心任务是:给定一张带有噪声的潜在表示 $\mathbf{z}_t$ 和当前的时间步 $t$,模型必须预测并去除添加到图像中的噪声 $\epsilon$。

  3. U-Net 的局限: 传统的扩散模型使用 U-Net 结构进行去噪。U-Net 擅长处理局部细节,但由于其卷积性质,难以有效地捕捉图像中大尺度、长距离的依赖关系

二、DiT 的架构创新:ViT 作为骨干

DiT 的结构与 ViT 的编码器部分高度相似,但在输入和注意力机制中融入了条件信息(Conditioning)

1. 输入处理(Patching & Embedding)

  • 输入: 带有噪声的潜在表示 $\mathbf{z}_t$。

  • 分块与嵌入: 与 ViT 完全相同,$\mathbf{z}_t$ 被分割成潜在 Patch 并通过线性层嵌入到 Transformer 维度 $D$。

  • 序列: 生成一个 Patch 序列 $\mathbf{X}$。(DiT 通常不使用CLS Token,因为它不是分类任务。)

2. 条件化(Conditioning)

DiT 的关键在于如何将扩散过程所需的额外信息(时间步 $t$ 和文本/类别条件 $c$)融入到 Transformer 块中。

  • 时间步 $t$: 时间步 $t$(表示噪声程度)首先被编码成一个高维向量。

  • 条件信息 $c$: 文本提示 $c$ 通常通过一个独立的文本编码器(如 CLIP Text Encoder)转换为特征向量。

  • 自适应层归一化 (Adaptive Layer Normalization, AdaLN): DiT 使用 AdaLN 将这些条件信息高效地注入每个 Transformer 块。

    • 在标准的 Layer Normalization 之后,DiT 通过时间步 $t$ 和条件 $c$ 计算出的参数来对特征进行仿射变换(Scaling $\gamma$ 和 Shifting $\beta$)
  • 定位: $\gamma$ 和 $\beta$ 参数被注入到 DiT 块中的 MHA 层和 FFN 层 的 Layer Normalization 之后。

3. DiT 块(Transformer Encoder)

DiT 的核心是基于 ViT 编码器修改而成的 DiT 块。

  • 结构: 与 ViT 类似,由 MHA 和 FFN 组成,但两者都包含了 AdaLN 注入的条件信息。

  • 功能: 计算潜在 Patch 之间的全局注意力,同时受到当前噪声程度和文本提示的精确控制。

三、输出与重构

  1. 输出序列: 经过 $L$ 个 DiT 块后,模型输出一个与输入 $\mathbf{X}$ 相同维度的序列 $\mathbf{Y}$。

  2. 逆向投影: $\mathbf{Y}$ 序列通过一个线性投影层,将特征维度 $D$ 逆向投影回潜在 Patch 的维度。

  3. 重构潜在图: 这些潜在 Patch 被重新排列、组合,重构回二维的潜在噪声图 $\epsilon$(或去噪后的潜在表示 $\mathbf{z}_{t-1}$)。

  4. 去噪: 这个预测出的 $\epsilon$ 被用于扩散模型的采样步骤,逐步去除 $\mathbf{z}_t$ 中的噪声,最终生成清晰的潜在表示。


文章作者: Chen Zhou
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Chen Zhou !
  目录