楼主: 朱远
105 0

Transformer模型demo实现 [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

学前班

80%

还不是VIP/贵宾

-

威望
0
论坛币
0 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
30 点
帖子
2
精华
0
在线时间
0 小时
注册时间
2018-5-15
最后登录
2018-5-15

楼主
朱远 发表于 2025-12-4 07:00:42 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

Transformer 与 Diffusion 模型深度对比分析

本文将对两种核心的深度学习架构——Transformer 和 Diffusion 模型进行系统性比较,从基本概念、模型类型、应用场景到核心结构逐一剖析,帮助理解二者在现代人工智能中的不同定位与实现方式。

1. 基本特性对比

对比维度 Transformer Diffusion
模型类型 判别式模型 生成式模型
主要应用领域 NLP、CV、序列建模 图像生成、音频生成、数据合成
核心思想 自注意力机制 渐进式去噪过程
[此处为图片1]

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
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:transform Former Trans DEMO form
相关内容:Transformer模型实现

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
扫码
拉您进交流群
GMT+8, 2026-2-13 15:49