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

#代码星辉·七月创作之星挑战赛#


相关文章

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


一、编码器的核心作用

在Transformer架构中,编码器(Encoder)是特征提取的核心模块,负责将输入序列(如文本、图像patch)转换为包含上下文信息的特征表示。其核心能力体现在:

  1. 上下文建模:通过自注意力机制捕捉序列中任意位置的依赖关系(如文本中“代词”与“指代对象”的关联)。
  2. 特征逐层抽象:通过多层堆叠的编码器层,从输入中逐层提取从简单到复杂的特征(如文本中从“词向量”→“短语语义”→“句子主题”)。

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

在这里插入图片描述
核心模块的代码实现在 Transformer架构:核心模块代码实现(基于PyTorch)


三、编码器层(EncoderLayer):单一层级的特征变换

编码器层是构成编码器的基本单元,每个层包含“自注意力子层”和“前馈网络子层”,通过子层连接结构实现特征的深度加工。

3.1 代码实现与结构解析

class EncoderLayer(nn.Module):
    def __init__(self, embedding_dim, self_attention, feedforward, dropout):
        super().__init__()
        self.self_attention = self_attention  # 多头自注意力模块
        self.feedforward = feedforward        # 前馈全连接模块
        self.embedding_dim = embedding_dim    # 词嵌入维度(如512)
        # 克隆2个子层连接结构(分别用于注意力子层和前馈子层)
        self.sublayer = clones(SublayerConnection(embedding_dim, dropout), 2)

    def forward(self, x, mask):
        # 第一个子层:自注意力 + 残差连接 + 规范化
        x = self.sublayer[0](x, lambda x: self.self_attention(x, x, x, mask))
        # 第二个子层:前馈网络 + 残差连接 + 规范化
        x = self.sublayer[1](x, self.feedforward)
        return x

3.2 关键细节解析:

  1. 模块依赖

    • self_attention:多头注意力实例(如8头,MultiHeadedAttention类),用于计算自注意力。
    • feedforward:前馈网络实例(PositionwiseFeedForward类),用于非线性特征变换。
    • sublayer:通过clones函数复制的2个子层连接结构,封装了“残差连接+LayerNorm+Dropout”逻辑。
  2. 前向传播流程

    • 自注意力子层
      输入x通过lambda x: self.self_attention(x, x, x, mask)实现自注意力计算(query=key=value=x),再经self.sublayer[0]完成残差连接与规范化。
    • 前馈网络子层
      注意力输出通过前馈网络进行非线性变换,再经self.sublayer[1]处理,最终输出当前编码器层的结果。
  3. 张量形状变化
    输入x形状为[batch_size, seq_len, embedding_dim],经过两层子处理后形状保持不变,确保多层堆叠时的兼容性。


四、编码器(Encoder):多层堆叠的深度特征提取

编码器由N个相同的编码器层堆叠而成,通过多层迭代强化特征表示,最终输出包含全局上下文的序列特征。

4.1 代码实现与结构解析

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

    def forward(self, x, mask):
        # 依次通过N个编码器层
        for layer in self.layers:
            x = layer(x, mask)
        # 最终规范化
        return self.norm(x)

4.2 关键细节解析:

  1. 多层堆叠逻辑
    通过clones(layer, N)复制N个相同的编码器层(如Transformer原论文中N=6),形成深度网络结构。每层的输出作为下一层的输入,实现特征的逐层抽象。

  2. 最终规范化
    所有编码器层处理完毕后,通过LayerNorm进行最终规范化,确保输出特征的分布稳定性,为后续解码器(或下游任务)提供一致的输入。

  3. 掩码作用
    mask在整个编码器流程中传递,用于屏蔽输入序列中的无效位置(如填充的PAD token),确保自注意力计算仅关注有效元素。


五、核心设计思想

  1. 模块化堆叠
    编码器层通过“自注意力+前馈网络”的固定模块重复堆叠,平衡了模型复杂度与可扩展性。增加层数可提升特征抽象能力,但需配合残差连接避免梯度消失。

  2. 自注意力的核心价值
    每个编码器层中的自注意力机制允许序列中的每个元素“关注”其他所有元素,从而捕捉长距离依赖(如文本中跨句子的语义关联),这是Transformer超越RNN的关键。

  3. 与输入模块的衔接
    编码器的输入通常是经过“词嵌入+位置编码”的序列(见《Transformer架构:输入部分代码实现》),其输出可直接作为解码器的“记忆”(如机器翻译任务),或用于文本分类等下游任务。


六、完整代码

from Transformer_moduls import *

# 编码器层类 EncoderLayer 实现思路分析
# init函数 (self, size, self_attn, feed_forward, dropout):
    # 实例化多头注意力层对象self_attn # 前馈全连接层对象feed_forward  size词嵌入维度512
    # clones两个子层连接结构 self.sublayer = clones(SublayerConnection(size,dropout),2)
# forward函数 (self, x, mask)
    # 数据经过子层连接结构1 self.sublayer[0](x, lambda x: self.self_attn(x, x, x, mask))
    # 数据经过子层连接结构2 self.sublayer[1](x, self.feed_forward)
class EncoderLayer(nn.Module):
    def __init__(self,embedding_dim,self_attention,feedforward,dropout):
        super().__init__()
        # 实例化多头注意力层对象
        self.self_attention = self_attention

        # 前馈全连接层对象feed_forward
        self.feedforward = feedforward

        # size词嵌入维度512
        self.embedding_dim = embedding_dim

        # clones两个子层连接结构 self.sublayer = clones(SublayerConnection(size,dropout),2)
        self.sublayer = clones(SublayerConnection(embedding_dim,dropout),2)

    def forward(self,x,mask):


        x = self.sublayer[0](x, lambda x:self.self_attention(x,x,x,mask))

        x = self.sublayer[1](x,self.feedforward)

        return  x

# 编码器类 Encoder 实现思路分析
# init函数 (self, layer, N)
    # 实例化多个编码器层对象self.layers   通过方法clones(layer, N)
    # 实例化规范化层 self.norm = LayerNorm(layer.size)
# forward函数 (self, x, mask)
    # 数据经过N个层 x = layer(x, mask)
    #  返回规范化后的数据 return self.norm(x)
class Encoder(nn.Module):
    def __init__(self,layer,N):
        # 参数layer 1个编码器层
        # 参数 编码器层的个数

        super().__init__()

        # 实例化多个编码器层对象
        self.layers = clones(layer,N)

        # 实例化规范化层
        self.norm = LayerNorm(embedding_dim)

    def forward(self,x,mask):
        # 数据经过N个层 x = layer(x, mask)
        for layer in self.layers:
            x = layer(x,mask)

        #  返回规范化后的数据 return self.norm(x)
        return self.norm(x)

def test_encoder():
    x = torch.arange(8).reshape(2,-1)
    x = untest_input(x)
    self_attention = MutiHeadAttention(8,embedding_dim,dropout)
    feedforward = PositionwiseFeedForward(embedding_dim,d_ff)
    encoder_layer = EncoderLayer(embedding_dim,self_attention,feedforward,dropout)
    encoder = Encoder(encoder_layer,6)
    # 此处应该使用padding mask,为演示方便用全0mask
    mask = torch.zeros(heads,4,4)
    encoder_result = encoder(x,mask)
    print(f'{"*"*30}编码后的值{"*"*30}')
    print(encoder_result)
    print(f'编码后的形状:{encoder_result.shape}')
    return encoder_result


if __name__ == '__main__':
    test_encoder()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值