Transformer架构:解码器部分代码实现(基于PyTorch)

部署运行你感兴趣的模型镜像


相关文章

Transformer架构:结构介绍网页链接
Transformer架构:输入部分代码实现(基于PyTorch)网页链接
Transformer架构:核心模块代码实现(基于PyTorch)网页链接
Transformer架构:编码器部分代码实现(基于PyTorch)网页链接
Transformer架构:输出部分代码实现(基于PyTorch)网页链接
Transformer架构:整体实现代码(基于PyTorch)网页链接


一、解码器的核心作用

在Transformer架构中,解码器(Decoder)是序列生成的核心模块,负责基于编码器输出的上下文特征和自身历史输出,生成符合任务需求的目标序列(如机器翻译中的译文、文本摘要中的摘要句)。其核心能力体现在:

  1. autoregressive 生成:通过掩码自注意力机制确保生成时仅依赖已生成的token,避免未来信息泄露。
  2. 跨模态对齐:通过编码器-解码器注意力机制,动态关联目标序列与源序列的上下文信息(如翻译时将“苹果”关联到“Apple”)。
  3. 特征精细化加工:通过多层堆叠的解码器层,逐步优化生成序列的语义一致性和语法正确性。

二、解码器整体工作流程图

在这里插入图片描述


三、解码器层(DecoderLayer):单一层级的序列生成逻辑

解码器层是构成解码器的基本单元,每个层包含“自注意力子层”“编码器-解码器注意力子层”和“前馈网络子层”,通过子层连接结构实现特征的逐步优化。

3.1 代码实现与结构解析

class DecoderLayer(nn.Module):
    def __init__(self, embedding_dim, self_attention, src_attention, feedforward, dropout):
        super().__init__()
        self.embedding_dim = embedding_dim  # 词嵌入维度(如512)
        self.self_attention = self_attention  # 目标序列自注意力模块(带掩码)
        self.src_attention = src_attention    # 编码器-解码器注意力模块
        self.feedforward = feedforward        # 前馈全连接模块
        # 克隆3个子层连接结构(分别对应三个子层)
        self.sublayer = clones(SublayerConnection(embedding_dim, dropout), 3)

    def forward(self, y, encoder_result, target_mask, source_mask):
        m = encoder_result  # 编码器输出的源序列特征
        # 第一个子层:目标序列自注意力 + 残差连接 + 规范化
        y = self.sublayer[0](y, lambda x: self.self_attention(x, x, x, target_mask))
        # 第二个子层:编码器-解码器注意力 + 残差连接 + 规范化
        y = self.sublayer[1](y, lambda x: self.src_attention(x, m, m, source_mask))
        # 第三个子层:前馈网络 + 残差连接 + 规范化
        y = self.sublayer[2](y, self.feedforward)
        return y

3.2 关键细节解析

  1. 模块依赖

    • self_attention:多头注意力实例(如8头),用于目标序列的自注意力计算(query=key=value=y)。
    • src_attention:多头注意力实例,用于关联目标序列与源序列(query=y, key=value=encoder_result)。
    • sublayer:通过clones函数复制的3个子层连接结构,封装“残差连接+LayerNorm+Dropout”逻辑,确保深层网络训练稳定。
  2. 前向传播流程

    • 自注意力子层:输入目标序列y通过自注意力捕捉内部依赖,target_mask屏蔽未来token(如生成第i个词时,仅允许关注1~i个词)。
    • 编码器-解码器注意力子层:使用目标序列作为查询(query),编码器输出作为键值对(key=value),实现“目标序列→源序列”的信息对齐(如翻译时将“我”关联到源文中的“我”)。
    • 前馈网络子层:对注意力输出进行线性变换和ReLU激活,增强模型的非线性拟合能力。
  3. 张量形状变化
    输入y的形状为[batch_size, tgt_seq_len, embedding_dim],经过三层子处理后形状保持不变,确保多层堆叠时的兼容性。


四、解码器(Decoder):多层堆叠的序列生成优化

解码器由N个相同的解码器层堆叠而成,通过多层迭代处理,逐步优化目标序列的生成质量,最终输出可直接用于预测的特征表示。

4.1 代码实现与结构解析

class Decoder(nn.Module):
    def __init__(self, layer, N):
        super().__init__()
        # 克隆N个解码器层(如N=6,与编码器对称)
        self.layers = clones(layer, N)
        # 最终规范化层(输出前的特征分布调整)
        self.norm = LayerNorm(embedding_dim)

    def forward(self, y, encoder_result, target_mask, source_mask):
        # 依次通过N个解码器层
        for layer in self.layers:
            y = layer(y, encoder_result, target_mask, source_mask)
        # 最终规范化,确保输出特征分布稳定
        return self.norm(y)

4.2 关键细节解析

  1. 多层堆叠逻辑
    通过clones(layer, N)复制N个解码器层(Transformer原论文中N=6),形成深度生成网络。每层的输出作为下一层的输入,实现“粗→细”的序列特征优化(如从“词级语义”到“句子级连贯性”的提升)。

  2. 掩码的传递与作用

    • target_mask:贯穿所有解码器层,始终屏蔽目标序列中的未来token和填充token(PAD),确保生成过程的 autoregressive 特性。
    • source_mask:用于屏蔽源序列中的填充token,避免编码器-解码器注意力关注无效信息。
  3. 与编码器的协同
    编码器输出encoder_result在所有解码器层中被复用,作为keyvalue提供源序列的上下文信息,而目标序列y则通过query动态查询相关信息,实现“源→目标”的精准对齐。


五、核心设计思想

  1. 双注意力机制的分工
    自注意力聚焦于目标序列内部的连贯性(如语法正确),编码器-解码器注意力聚焦于跨序列的语义对齐(如语义一致),两者结合确保生成序列“既通顺又准确”。

  2. 掩码机制的必要性
    在自注意力中,target_mask通过下三角矩阵屏蔽未来token(如下表),强制模型仅依赖已生成信息,这是序列生成任务的核心约束。

    # target_mask示例(3个token的序列)
    [[1, 0, 0],
     [1, 1, 0],
     [1, 1, 1]]
    
  3. 模块化设计的扩展性
    解码器层的三个子层通过统一的SublayerConnection接口封装,便于替换子层实现(如将自注意力替换为稀疏注意力以提升效率)。


六、解码器测试与验证

通过test_decoder函数验证解码器的功能,观察输入输出的形状一致性和特征变换效果:

def test_decoder():
    # 模拟目标序列输入(2条样本,每条6个token)
    y = torch.tensor([[10, 20, 30, 40, 50, 60], [70, 80, 90, 100, 110, 120]])
    y = untest_input(y)  # 转换为嵌入向量(形状:[2, 6, 512])
    
    # 获取编码器输出(模拟源序列特征)
    encoder_result = test_encoder()  # 形状:[2, 4, 512]
    
    # 初始化注意力和前馈网络
    attention = clones(MutiHeadAttention(8, embedding_dim, dropout), 2)  # 2个多头注意力实例
    feedforward = PositionwiseFeedForward(embedding_dim, d_ff)  # 前馈网络
    
    # 构建解码器
    decoder_layer = DecoderLayer(embedding_dim, attention[0], attention[1], feedforward, dropout)
    decoder = Decoder(decoder_layer, 6)  # 6层解码器
    
    # 初始化掩码(模拟填充和未来信息屏蔽)
    target_mask = torch.zeros(heads, 6, 6)  # 目标序列掩码(6个token)
    source_mask = torch.zeros(heads, 6, 4)  # 源序列掩码(6个目标token→4个源token)
    
    # 解码器前向传播
    decoder_result = decoder(y, encoder_result, target_mask, source_mask)
    
    # 输出验证
    print(f'{"*"*30}解码器输出{"*"*30}')
    print(decoder_result)
    print(f'解码器输出形状:{decoder_result.shape}')  # 预期:[2, 6, 512]
    return decoder_result

if __name__ == '__main__':
    test_decoder()

测试输出说明

  • 解码器输出形状与输入目标序列一致([2, 6, 512]),确保后续可直接接入线性层预测下一个token。
  • 特征值经过多层处理后发生非线性变换,体现了解码器对序列特征的优化能力。

七、完整代码

from Transformer_encoder import *
from Transformer_moduls import *

# 解码器层类 DecoderLayer 实现
class DecoderLayer(nn.Module):
    def __init__(self, embedding_dim, self_attention, src_attention, feedforward, dropout):
        super().__init__()
        self.embedding_dim = embedding_dim
        self.self_attention = self_attention  # 目标序列自注意力(q=k=v)
        self.src_attention = src_attention    # 编码器-解码器注意力(q≠k=v)
        self.feedforward = feedforward
        self.sublayer = clones(SublayerConnection(embedding_dim, dropout), 3)  # 3个子层连接

    def forward(self, y, encoder_result, target_mask, source_mask):
        m = encoder_result
        # 自注意力子层(带目标掩码)
        y = self.sublayer[0](y, lambda x: self.self_attention(x, x, x, target_mask))
        # 编码器-解码器注意力子层(带源掩码)
        y = self.sublayer[1](y, lambda x: self.src_attention(x, m, m, source_mask))
        # 前馈网络子层
        y = self.sublayer[2](y, self.feedforward)
        return y

# 解码器类 Decoder 实现
class Decoder(nn.Module):
    def __init__(self, layer, N):
        super().__init__()
        self.layers = clones(layer, N)  # 堆叠N个解码器层
        self.norm = LayerNorm(embedding_dim)  # 最终规范化

    def forward(self, y, encoder_result, target_mask, source_mask):
        for layer in self.layers:
            y = layer(y, encoder_result, target_mask, source_mask)
        return self.norm(y)

# 解码器测试函数
def test_decoder():
    y = torch.tensor([[10,20,30,40,50,60],[70,80,90,100,110,120]])
    y = untest_input(y)  # 转换为嵌入向量
    encoder_result = test_encoder()  # 获取编码器输出
    
    # 初始化组件
    attention = clones(MutiHeadAttention(8, embedding_dim, dropout), 2)
    feedforward = PositionwiseFeedForward(embedding_dim, d_ff)
    decoder_layer = DecoderLayer(embedding_dim, attention[0], attention[1], feedforward, dropout)
    decoder = Decoder(decoder_layer, 6)  # 6层解码器
    
    # 掩码设置
    target_mask = torch.zeros(heads, 6, 6)
    source_mask = torch.zeros(heads, 6, 4)
    
    # 前向传播
    decoder_result = decoder(y, encoder_result, target_mask, source_mask)
    print(f'{"*"*30}解码器输出{"*"*30}')
    print(decoder_result)
    print(f'解码器输出形状:{decoder_result.shape}')
    return decoder_result

if __name__ == '__main__':
    test_decoder()

您可能感兴趣的与本文相关的镜像

PyTorch 2.5

PyTorch 2.5

PyTorch
Cuda

PyTorch 是一个开源的 Python 机器学习库,基于 Torch 库,底层由 C++ 实现,应用于人工智能领域,如计算机视觉和自然语言处理

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值