首页 > 其他分享 >TransformerEncoder 类

TransformerEncoder 类

时间:2024-12-08 23:30:16浏览次数:8  
标签:编码器 嵌入 positions self TransformerEncoder embed dropout

定义一个 TransformerEncoder 类,它是一个标准的 Transformer 编码器的实现,通常用于自然语言处理(NLP)任务中。Transformer 是由 Vaswani 等人提出的模型,广泛用于许多序列到序列的任务,如机器翻译、文本生成、图像处理等:

1. 类说明

TransformerEncoder 是一个 nn.Module 的子类,表示 Transformer 的编码器部分。它由多个 TransformerEncoderLayer 组成,每个 EncoderLayer 都包括多头自注意力(Multi-Head Self-Attention)和前馈神经网络(Feed-Forward Network)。

2. 初始化方法 (__init__)

def __init__(self, embed_dim, num_heads, layers, attn_dropout=0.0, relu_dropout=0.0, res_dropout=0.0,
             embed_dropout=0.0, attn_mask=False):
参数:
  • embed_dim:表示输入嵌入的维度(例如每个 token 的向量表示的维度)。
  • num_heads:多头自注意力机制中的头数,即 MultiHeadAttention 中的注意力头数。
  • layers:Transformer 编码器层的数量。
  • attn_dropout:应用于注意力权重的 dropout 比例。
  • relu_dropout:应用于前馈网络的 ReLU 层的 dropout 比例。
  • res_dropout:应用于残差连接的 dropout 比例。
  • embed_dropout:应用于嵌入层的 dropout 比例。
  • attn_mask:是否使用注意力遮罩(通常用于屏蔽未来的单词)。

  • 初始化嵌入层

    • self.embed_dim 设置了嵌入维度。
    • self.embed_scale = math.sqrt(embed_dim) 用来对输入进行缩放,通常是为了避免初始化时的值过大。
    • self.embed_positions = SinusoidalPositionalEmbedding(embed_dim) 用于位置编码,增强模型对序列顺序的感知。
  • 构建编码器层

    • self.layers = nn.ModuleList([]) 定义了一个空的 ModuleList 用于存储多个 Transformer 编码器层。
    • TransformerEncoderLayer 是每层编码器的实现,包含多头自注意力和前馈网络。
    • 每个编码器层的超参数(如 embed_dim, num_heads, attn_dropout)从初始化方法传入。
  • 规范化(LayerNorm)

    • self.layer_norm = LayerNorm(embed_dim) 定义了一个可选的 LayerNorm 层,通常用在网络的输出层,以稳定训练过程。

3. 前向传播方法 (forward)

def forward(self, x_in, x_in_k = None, x_in_v = None):
参数:
  • x_in:输入的嵌入张量,形状为 (src_len, batch, embed_dim),即输入的序列长度、批次大小和嵌入维度。
  • x_in_kx_in_v:可选的键和值张量,通常用于交叉注意力(cross-attention)机制,这在多模态学习(例如图像与文本结合)中较为常见。

  1. 嵌入和位置编码

    • x = self.embed_scale * x_in:输入的嵌入张量会进行缩放,embed_scale 是为了对嵌入进行归一化,使其适应模型训练。
    • x += self.embed_positions(x_in.transpose(0, 1)[:, :, 0]).transpose(0, 1):对输入 x_in 加上位置编码,通过 SinusoidalPositionalEmbedding 添加位置信息。transpose(0, 1) 交换序列和批次维度,以便位置编码可以正确应用。
  2. Dropout

    • x = F.dropout(x, p=self.dropout, training=self.training):对输入应用 dropout,以防止过拟合。
  3. 处理键(Key)和值(Value)(如果有):

    • x_kx_v 是可选的键和值,分别代表自注意力机制中的键和值部分。
    • 对于 x_in_kx_in_v,同样进行嵌入和位置编码操作。
  4. 编码器层的堆叠

    • for layer in self.layers:对每一层 TransformerEncoderLayer 进行迭代。
    • x = layer(x, x_k, x_v):如果 x_in_kx_in_v 不为空,则传入这些值执行交叉注意力操作。否则,使用普通的自注意力机制。
  5. 归一化(可选)

    • 如果 self.normalizeTrue,在最后应用 LayerNorm。
    • x = self.layer_norm(x):通过 LayerNorm 规范化输出。
  6. 返回值

    • 返回处理后的输入 x

4. 最大支持的输入长度 (max_positions)

def max_positions(self):
    """Maximum input length supported by the encoder."""
    if self.embed_positions is None:
        return self.max_source_positions
    return min(self.max_source_positions, self.embed_positions.max_positions())

该方法返回编码器支持的最大输入长度。如果有位置编码(embed_positions),则返回位置编码支持的最大长度。否则,返回 max_source_positions

小结

TransformerEncoder 类实现了一个标准的 Transformer 编码器模块,可以通过堆叠多个 TransformerEncoderLayer 来处理序列数据。它包括:

  • 输入嵌入和位置编码。
  • 对输入应用 dropout。
  • 通过多个编码器层(每层包含多头自注意力和前馈网络)处理输入数据。
  • 可选的归一化层(LayerNorm)以稳定训练过程。

这种结构非常适合用于序列到序列的任务,如自然语言处理任务、机器翻译、图像处理等。

标签:编码器,嵌入,positions,self,TransformerEncoder,embed,dropout
From: https://blog.csdn.net/weixin_44012667/article/details/144291053

相关文章