当前位置: 首页 > news >正文

仅仅使用pytorch来手撕transformer架构(3):编码器模块和编码器类的实现和向前传播

仅仅使用pytorch来手撕transformer架构(2):编码器模块和编码器类的实现和向前传播

往期文章:
仅仅使用pytorch来手撕transformer架构(1):位置编码的类的实现和向前传播

最适合小白入门的Transformer介绍

仅仅使用pytorch来手撕transformer架构(2):多头注意力MultiHeadAttention类的实现和向前传播

# Transformer 编码器模块
class TransformerBlock(nn.Module):
    def __init__(self, embed_size, heads, dropout, forward_expansion):
        super(TransformerBlock, self).__init__()
        self.attention = MultiHeadAttention(embed_size, heads)
        self.norm1 = nn.LayerNorm(embed_size)
        self.norm2 = nn.LayerNorm(embed_size)

        self.feed_forward = nn.Sequential(
            nn.Linear(embed_size, forward_expansion * embed_size),
            nn.ReLU(),
            nn.Linear(forward_expansion * embed_size, embed_size),
        )

        self.dropout = nn.Dropout(dropout)

    def forward(self, value, key, query, mask):
        attention = self.attention(value, key, query, mask)

        x = self.dropout(self.norm1(attention + query))
        forward = self.feed_forward(x)
        out = self.dropout(self.norm2(forward + x))
        return out

# 编码器
class Encoder(nn.Module):
    def __init__(self, src_vocab_size, embed_size, num_layers, heads, device, forward_expansion, dropout, max_length):
        super(Encoder, self).__init__()
        self.embed_size = embed_size
        self.device = device
        self.word_embedding = nn.Embedding(src_vocab_size, embed_size)
        self.position_embedding = PositionalEncoding(embed_size, dropout, max_length)

        self.layers = nn.ModuleList(
            [
                TransformerBlock(
                    embed_size,
                    heads,
                    dropout=dropout,
                    forward_expansion=forward_expansion,
                )
                for _ in range(num_layers)
            ]
        )

        self.dropout = nn.Dropout(dropout)
    def forward(self, x, mask):
            N, seq_length = x.shape
            x = self.dropout(self.position_embedding(self.word_embedding(x)))

            for layer in self.layers:
                x = layer(x, x, x, mask)

            return x


1.编码器模块的实现

这段代码实现了一个Transformer编码器模块(Transformer Block),它是Transformer架构的核心组件之一。Transformer架构是一种基于自注意力机制(Self-Attention)的深度学习模型,广泛应用于自然语言处理(NLP)任务,如机器翻译、文本生成等。以下是对代码的详细解释:


1.1 类定义

class TransformerBlock(nn.Module):

TransformerBlock 是一个继承自 PyTorch 的 nn.Module 的类,表示一个Transformer编码器模块。nn.Module 是 PyTorch 中所有神经网络模块的基类,用于定义和管理神经网络的结构。


2.2 初始化方法

def __init__(self, embed_size, heads, dropout, forward_expansion):
    super(TransformerBlock, self).__init__()
    self.attention = MultiHeadAttention(embed_size, heads)
    self.norm1 = nn.LayerNorm(embed_size)
    self.norm2 = nn.LayerNorm(embed_size)

    self.feed_forward = nn.Sequential(
        nn.Linear(embed_size, forward_expansion * embed_size),
        nn.ReLU(),
        nn.Linear(forward_expansion * embed_size, embed_size),
    )

    self.dropout = nn.Dropout(dropout)
参数解释
  • embed_size: 嵌入向量的维度,表示每个词或标记(token)的特征维度。
  • heads: 多头注意力机制中的头数(Multi-Head Attention)。
  • dropout: Dropout比率,用于防止过拟合。
  • forward_expansion: 前馈网络(Feed-Forward Network, FFN)中隐藏层的扩展因子。
组件解释
  1. 多头注意力机制(MultiHeadAttention

    self.attention = MultiHeadAttention(embed_size, heads)
    

    这是Transformer的核心部分,实现了多头注意力机制。它允许模型在不同的表示子空间中学习信息。MultiHeadAttention 的具体实现没有在这段代码中给出,但通常它会将输入分为多个“头”,分别计算注意力权重,然后将结果拼接起来。

  2. 层归一化(LayerNorm

    self.norm1 = nn.LayerNorm(embed_size)
    self.norm2 = nn.LayerNorm(embed_size)
    

    层归一化(Layer Normalization)是一种归一化方法,用于稳定训练过程并加速收敛。它对每个样本的特征进行归一化,而不是像批量归一化(Batch Normalization)那样对整个批次进行归一化。

  3. 前馈网络(Feed-Forward Network

    self.feed_forward = nn.Sequential(
        nn.Linear(embed_size, forward_expansion * embed_size),
        nn.ReLU(),
        nn.Linear(forward_expansion * embed_size, embed_size),
    )
    

    前馈网络是一个简单的两层全连接网络。它的作用是进一步处理多头注意力机制的输出。forward_expansion 参数控制隐藏层的大小,通常设置为一个较大的值(如4),表示隐藏层的维度是输入维度的4倍。

  4. Dropout

    self.dropout = nn.Dropout(dropout)
    

    Dropout 是一种正则化技术,通过随机丢弃一部分神经元的输出来防止过拟合。dropout 参数表示丢弃的概率。


3. 前向传播方法

def forward(self, value, key, query, mask):
    attention = self.attention(value, key, query, mask)

    x = self.dropout(self.norm1(attention + query))
    forward = self.feed_forward(x)
    out = self.dropout(self.norm2(forward + x))
    return out
参数解释
  • value: 值向量,用于计算注意力权重后的加权求和。
  • key: 键向量,用于计算注意力权重。
  • query: 查询向量,用于计算注意力权重。
  • mask: 掩码,用于防止某些位置的信息泄露(如在自注意力中屏蔽未来信息)。
流程解释
  1. 多头注意力

    attention = self.attention(value, key, query, mask)
    

    首先,使用多头注意力机制计算注意力输出。valuekeyquery 是输入的三个部分,mask 用于控制哪些位置的信息可以被关注。

  2. 残差连接与层归一化

    x = self.dropout(self.norm1(attention + query))
    

    将注意力输出与输入的 query 进行残差连接(attention + query),然后通过层归一化(LayerNorm)。最后,应用 Dropout 防止过拟合。

  3. 前馈网络

    forward = self.feed_forward(x)
    

    将经过归一化的输出传递到前馈网络中进行进一步处理。

  4. 第二次残差连接与层归一化

    out = self.dropout(self.norm2(forward + x))
    

    将前馈网络的输出与之前的输出 x 进行残差连接,再次通过层归一化和 Dropout。

  5. 返回结果

    return out
    

    最终返回处理后的输出。


4. 总结

Transformer编码器模块,其核心包括:

  • 多头注意力机制(MultiHeadAttention)。
  • 残差连接(Residual Connection)。
  • 层归一化(LayerNorm)。
  • 前馈网络(Feed-Forward Network)。
  • Dropout 正则化。

这些组件共同作用,使得Transformer能够高效地处理序列数据,并在许多NLP任务中取得了优异的性能。

2.编码器的实现

这段代码定义了一个完整的 Transformer 编码器(Encoder),它是 Transformer 架构中的一个重要组成部分。编码器的作用是将输入序列(如源语言文本)转换为上下文表示,这些表示可以被解码器(Decoder)用于生成目标序列(如目标语言文本)。以下是对代码的详细解释:


1. 类定义

class Encoder(nn.Module):

Encoder 是一个继承自 PyTorch 的 nn.Module 的类,用于定义 Transformer 编码器的结构。nn.Module 是 PyTorch 中所有神经网络模块的基类,用于定义和管理神经网络的结构。


2. 初始化方法

def __init__(self, src_vocab_size, embed_size, num_layers, heads, device, forward_expansion, dropout, max_length):
    super(Encoder, self).__init__()
    self.embed_size = embed_size
    self.device = device
    self.word_embedding = nn.Embedding(src_vocab_size, embed_size)
    self.position_embedding = PositionalEncoding(embed_size, dropout, max_length)

    self.layers = nn.ModuleList(
        [
            TransformerBlock(
                embed_size,
                heads,
                dropout=dropout,
                forward_expansion=forward_expansion,
            )
            for _ in range(num_layers)
        ]
    )

    self.dropout = nn.Dropout(dropout)
参数解释
  • src_vocab_size: 源语言词汇表的大小,即输入序列中可能的标记(token)数量。
  • embed_size: 嵌入向量的维度,表示每个词或标记的特征维度。
  • num_layers: 编码器中 Transformer 块(TransformerBlock)的数量。
  • heads: 多头注意力机制中的头数。
  • device: 运行设备(如 CPU 或 GPU)。
  • forward_expansion: 前馈网络(FFN)中隐藏层的扩展因子。
  • dropout: Dropout 比率,用于防止过拟合。
  • max_length: 输入序列的最大长度,用于位置编码。
组件解释
  1. 词嵌入(word_embedding

    self.word_embedding = nn.Embedding(src_vocab_size, embed_size)
    

    词嵌入层将输入的标记(token)索引映射为固定维度的嵌入向量。src_vocab_size 是词汇表的大小,embed_size 是嵌入向量的维度。

  2. 位置编码(position_embedding

    self.position_embedding = PositionalEncoding(embed_size, dropout, max_length)
    

    位置编码层用于为每个标记添加位置信息,使得模型能够捕捉序列中的顺序关系。PositionalEncoding 的具体实现没有在这段代码中给出,但通常它会根据标记的位置生成一个固定维度的向量,并将其与词嵌入相加。

  3. Transformer 块(TransformerBlock

    self.layers = nn.ModuleList(
        [
            TransformerBlock(
                embed_size,
                heads,
                dropout=dropout,
                forward_expansion=forward_expansion,
            )
            for _ in range(num_layers)
        ]
    )
    

    编码器由多个 Transformer 块组成。每个 Transformer 块包含多头注意力机制和前馈网络。num_layers 表示 Transformer 块的数量。

  4. Dropout

    self.dropout = nn.Dropout(dropout)
    

    Dropout 是一种正则化技术,通过随机丢弃一部分神经元的输出来防止过拟合。dropout 参数表示丢弃的概率。


3. 前向传播方法

def forward(self, x, mask):
    N, seq_length = x.shape
    x = self.dropout(self.position_embedding(self.word_embedding(x)))

    for layer in self.layers:
        x = layer(x, x, x, mask)

    return x
参数解释
  • x: 输入序列,形状为 (N, seq_length),其中 N 是批次大小,seq_length 是序列长度。
  • mask: 掩码,用于防止某些位置的信息泄露(如在自注意力中屏蔽未来信息)。
流程解释
  1. 词嵌入与位置编码

    x = self.dropout(self.position_embedding(self.word_embedding(x)))
    
    • 首先,将输入序列 x 通过词嵌入层(word_embedding)得到嵌入向量。
    • 然后,将嵌入向量与位置编码(position_embedding)相加,为每个标记添加位置信息。
    • 最后,应用 Dropout 防止过拟合。
  2. 逐层传递

    for layer in self.layers:
        x = layer(x, x, x, mask)
    
    • 输入序列 x 逐层传递到每个 Transformer 块中。在每个块中:
      • valuekeyquery 都是 x,因为这是自注意力机制(Self-Attention)。
      • mask 用于控制哪些位置的信息可以被关注。
    • 每个 Transformer 块的输出会作为下一层的输入。
  3. 返回结果

    return x
    
    • 最终返回编码器的输出,形状为 (N, seq_length, embed_size),表示每个位置的上下文表示。

4. 总结

Transformer 编码器,其主要功能包括:

  1. 词嵌入与位置编码:将输入标记转换为嵌入向量,并添加位置信息。
  2. 多层 Transformer 块:通过多头注意力机制和前馈网络逐层处理输入序列。
  3. 掩码机制:通过掩码控制注意力的范围,避免信息泄露。
  4. Dropout 正则化:防止过拟合。

编码器的输出是一个上下文表示,可以被解码器用于生成目标序列。这种架构在机器翻译、文本生成等任务中表现出色。

作者码字不易,觉得有用的话不妨点个赞吧,关注我,持续为您更新AI的优质内容。

相关文章:

  • 前端高阶面试题·每日一题
  • 【大模型知识点】RMSNorm(Root Mean Square Normalization)均方根归一化
  • linux 命令 ls
  • AI模型的构建过程是怎样的(下)
  • 华为OD机试-乘坐保密电梯-回溯(Java 2024 C卷 200分)
  • 分布式锁技术全景解析:从传统锁机制到MySQL、Redis/Redisson与ZooKeeper实现
  • Python 配置文件管理库Hydra 和 OmegaConf的区别
  • 图形学面试题总结
  • Conda 常规用法指南
  • css 知识点整理
  • Python个人学习笔记(15):模块(time)
  • 司南评测集社区 2 月上新一览!
  • Flutter 小技巧之通过 MediaQuery 优化 App 性能
  • 严格把控K8S集群中的操作权限,为普通用户生成特定的kubeconfig文件
  • C++和标准库速成(一)——HelloWorld和名称空间
  • 【从零开始学习计算机科学】编译原理(二)高级编程语言及其语法描述
  • Go红队开发—web网络编程
  • TCP三次握手
  • 前馈神经网络 - 自动梯度计算
  • Mac 如何在idea集成SVN
  • “南昌航空一号”成功发射,赣江鄱阳湖有了专属卫星守护
  • 经济日报金观平:促进信贷资金畅达小微企业
  • “80后”萍乡市安源区区长邱伟,拟任县(区)委书记
  • 俄乌直接谈判结束
  • 小雨伞保险经纪母公司手回集团通过港交所聆讯
  • 商务部召开全国离境退税工作推进会:提高退税商店覆盖面,扩大入境消费