Transformer 与 Diffusion 模型深度对比分析
本文将对两种核心的深度学习架构——Transformer 和 Diffusion 模型进行系统性比较,从基本概念、模型类型、应用场景到核心结构逐一剖析,帮助理解二者在现代人工智能中的不同定位与实现方式。
1. 基本特性对比
| 对比维度 | Transformer | Diffusion |
|---|---|---|
| 模型类型 | 判别式模型 | 生成式模型 |
| 主要应用领域 | NLP、CV、序列建模 | 图像生成、音频生成、数据合成 |
| 核心思想 | 自注意力机制 | 渐进式去噪过程 |
2. 架构设计详解
Transformer 架构核心实现
Transformer 模型依赖于自注意力机制来捕捉输入序列中各元素之间的关系。其基础模块通常包含多头自注意力层和前馈神经网络,并结合残差连接与层归一化以稳定训练过程。
import torch
import torch.nn as nn
import math
class TransformerBlock(nn.Module):
# Transformer基础块
def __init__(self, d_model, nhead, dim_feedforward=2048, dropout=0.1):
super().__init__()
# 多头自注意力机制
self.self_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout)
# 前馈神经网络
self.linear1 = nn.Linear(d_model, dim_feedforward)
self.linear2 = nn.Linear(dim_feedforward, d_model)
# 层归一化
self.norm1 = nn.LayerNorm(d_model)
self.norm2 = nn.LayerNorm(d_model)
self.dropout = nn.Dropout(dropout)
self.activation = nn.ReLU()
def forward(self, src):
# 自注意力 + 残差连接 + 层归一化
src2 = self.self_attn(src, src, src)[0]
src = self.norm1(src + self.dropout(src2))
# 前馈网络 + 残差连接 + 层归一化
src2 = self.linear2(self.dropout(self.activation(self.linear1(src))))
src = self.norm2(src + self.dropout(src2))
return src
Diffusion 模型架构关键组件
Diffusion 模型通过逐步添加噪声破坏数据,再训练网络逆向恢复原始样本。为了有效建模时间信息,位置编码被广泛应用于其中,尤其在基于Transformer的扩散模型中更为常见。
# 导入torch库,这是主要的深度学习框架
import torch
# 导入torch.nn模块,包含构建神经网络所需的各种类
import torch.nn as nn
# 导入math库,用于数学运算如指数、对数等
import math
# 定义位置编码类,继承自nn.Module,使其成为PyTorch可管理的模块
class PositionalEncoding(nn.Module):
"""
位置编码 - 为输入序列添加位置信息
Transformer本身不具备顺序感知能力,需额外引入位置编码
"""
def __init__(self, d_model, max_len=5000):
super(PositionalEncoding, self).__init__()
# 创建一个全零张量用于存储位置编码,形状为(max_len, d_model)
pe = torch.zeros(max_len, d_model)
# 生成位置索引序列并转换为浮点类型,增加维度便于后续计算
position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
# 计算分母项:exp(-log(10000) * i / d_model),其中i为偶数维度索引
div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000) / d_model))
# 对偶数维度应用正弦函数
pe[:, 0::2] = torch.sin(position * div_term)
# 对奇数维度应用余弦函数
pe[:, 1::2] = torch.cos(position * div_term)
# 调整张量形状以便广播操作:(max_len, 1, d_model)
pe = pe.unsqueeze(0).transpose(0, 1)
# 将位置编码注册为常量(不参与梯度更新)
self.register_buffer('pe', pe)
[此处为图片2]
# 将位置编码张量注册为模型的缓冲区(buffer)
# 缓冲区属于模型结构的一部分,随模型一同保存与加载
# 但不会被当作可训练参数,不参与梯度更新和反向传播过程
self.register_buffer('pe', pe)
# 前向传播函数定义,描述输入数据在模块中的流动方式
def forward(self, x):
# 输入x的维度为 (seq_len, batch_size, d_model)
# 取出对应序列长度的位置编码,self.pe[:x.size(0), :] 获取前 seq_len 行
# 利用PyTorch的广播机制,自动将位置编码加到每个batch的各个时间步上
x = x + self.pe[:x.size(0), :]
# 返回融合了位置信息的输出张量
return x
# 定义一个用于序列分类任务的简易Transformer编码器模型
class SimpleTransformer(nn.Module):
"""
简单的Transformer架构,适用于序列分类场景
"""
def __init__(self, input_size, d_model, nhead, num_layers, num_classes, max_len=100):
super(SimpleTransformer, self).__init__()
# 保存模型特征维度,便于后续引用
self.d_model = d_model
# 构建输入嵌入层:使用线性变换将原始输入维度 input_size 映射至 d_model
self.embedding = nn.Linear(input_size, d_model)
# 初始化位置编码组件,为模型提供序列顺序信息
self.pos_encoder = PositionalEncoding(d_model, max_len)
# 搭建单个Transformer编码器层,作为堆叠结构的基础单元
encoder_layer = nn.TransformerEncoderLayer(
d_model=d_model, # 特征向量维度
nhead=nhead, # 多头注意力机制的头数
dim_feedforward=512, # 前馈网络中间层宽度
dropout=0.1, # Dropout比率,缓解过拟合
activation='relu' # 激活函数类型
)
# 组合多层编码器形成完整的编码器堆栈
self.transformer_encoder = nn.TransformerEncoder(
encoder_layer,
num_layers=num_layers # 编码器层数量
)
# 分类头设计:通过全连接层将高维特征映射至类别空间
self.classifier = nn.Linear(d_model, num_classes)
# 添加Dropout层,提升模型泛化性能,在训练时随机屏蔽部分神经元
self.dropout = nn.Dropout(0.3)
# 前向传播逻辑实现
def forward(self, x):
# 输入张量形状:(batch_size, seq_len, input_size)
# 解构输入尺寸,下划线忽略第三个维度(input_size)
batch_size, seq_len, _ = x.shape
# 通过嵌入层进行维度转换,并对嵌入结果进行缩放
# 缩放因子为 sqrt(d_model),有助于稳定梯度训练过程
x = self.embedding(x * math.sqrt(self.d_model))
# 调整维度顺序以满足PyTorch Transformer的要求
# 目标格式:(seq_len, batch_size, d_model)
x = x.transpose(0, 1)
# 注入位置编码信息,使模型感知序列中元素的位置关系
x = self.pos_encoder(x)
# 将带有位置信息的数据送入Transformer编码器堆栈处理
# 输入必须符合 (seq_len, batch_size, d_model) 格式
x = self.transformer_encoder(x)
# 输出保持相同结构:(seq_len, batch_size, d_model)
# 提取序列起始位置(索引0)的隐藏状态作为整体表示
# 类似于BERT中的[CLS]标记,常用于分类任务的聚合向量
x = x[0, :, :] # 结果变为 (batch_size, d_model)
# 应用Dropout操作,进一步防止过拟合
x = self.dropout(x)
# 经由分类器生成最终的类别得分(logits)
x = self.classifier(x)
# 输出维度为 (batch_size, num_classes),表示每个样本属于各类别的分数
return x
# 定义用于序列到序列任务的Transformer模型,典型应用场景包括机器翻译等 class TransformerForSequenceToSequence(nn.Module): """ 实现一个标准的Seq2Seq结构Transformer,适用于翻译、文本生成等任务 """ def __init__(self, src_vocab_size, tgt_vocab_size, d_model, nhead, num_layers): super(TransformerForSequenceToSequence, self).__init__() # 编码器模块构建 # 源语言词汇嵌入层:将输入词索引转换为d_model维度的稠密向量 self.encoder_embedding = nn.Embedding(src_vocab_size, d_model) # 添加位置信息编码,使模型能感知序列顺序 self.pos_encoder = PositionalEncoding(d_model) # 构建单层编码器结构,设定前馈网络维度和注意力dropout比例 encoder_layer = nn.TransformerEncoderLayer(d_model, nhead, 512, 0.1) # 堆叠多个编码器层形成深层编码器 self.encoder = nn.TransformerEncoder(encoder_layer, num_layers) # 解码器模块构建 # 目标语言词汇嵌入层:将目标端词映射为d_model维向量 self.decoder_embedding = nn.Embedding(tgt_vocab_size, d_model) # 解码器侧的位置编码层 self.pos_decoder = PositionalEncoding(d_model) # 创建单层解码器结构 decoder_layer = nn.TransformerDecoderLayer(d_model, nhead, 512, 0.1) # 堆叠多层解码器 self.decoder = nn.TransformerDecoder(decoder_layer, num_layers) # 最终输出层:将解码器输出投影至目标词汇表大小的空间 # 用于计算每个时间步上各个词的概率分布 self.output_layer = nn.Linear(d_model, tgt_vocab_size) def forward(self, src, tgt): """ 前向传播过程 参数: src: 源语言序列,形状为 (seq_len, batch_size) tgt: 目标语言序列,训练时为完整序列(已右移) """ # --- 编码器处理阶段 --- # 将源序列进行词嵌入并按维度缩放 src_embed = self.encoder_embedding(src) * math.sqrt(self.d_model) # 注入位置信息 src_embed = self.pos_encoder(src_embed) # 经过整个编码器得到上下文表示memory memory = self.encoder(src_embed) # 输出维度: (src_seq_len, batch_size, d_model) # --- 解码器处理阶段 --- # 对目标序列进行嵌入操作并缩放 tgt_embed = self.decoder_embedding(tgt) * math.sqrt(self.d_model) # 添加位置编码以保留序列顺序信息 tgt_embed = self.pos_decoder(tgt_embed) # 解码器利用目标序列自身信息(自注意力)及编码器输出(交叉注意力)进行解码 output = self.decoder(tgt_embed, memory) # 形状: (tgt_seq_len, batch_size, d_model) # --- 输出层映射 --- # 将解码结果转换为词汇表上的预测分数 output = self.output_layer(output) # 形状: (tgt_seq_len, batch_size, tgt_vocab_size) return output # 演示函数:展示如何实例化并使用上述Transformer模型 def demo_transformer(): # 配置超参数 batch_szie = 32 # 批次大小,控制每次训练样本数量 seq_len = 20 # 序列长度,每条数据包含的词元数 input_size = 16 # 输入特征原始维度(若需要额外嵌入) d_model = 128 # Transformer内部表示维度,决定模型宽度 nhead = 8 # 多头注意力机制中的头数 num_layers = 3 # 编码器与解码器堆叠层数,影响模型深度 num_classes = 5 # 分类任务中类别总数(如用于下游分类) # 初始化SimpleTransformer模型实例
# 程序入口,当直接运行此脚本时,调用演示函数
if __name__ == '__main__':
# 执行Transformer模型演示,返回构建好的模型实例与前向输出结果
transformer_model, transformer_output = demo_transformer()
# 定义一个简易的Transformer模型结构
model = SimpleTransformer(input_size, d_model, nhead, num_layers, num_classes)
# 模拟生成一批随机输入张量
# 张量维度为:batch_size, seq_len, input_size
x = torch.randn(batch_size, seq_len, input_size)
# 将生成的数据输入模型,进行前向计算,获得输出结果
output = model(x)
# 输出输入与输出张量的形状信息,帮助理解数据在模型中的流动过程
# 同时返回模型对象和输出张量,便于后续扩展或调试使用
return model, output


雷达卡


京公网安备 11010802022788号







