理解 Transformer 中的编码器-解码器注意力层(Encoder-Decoder Attention Layer)

12. Encoder-Decoder Attention Layer

理解 Transformer 中的编码器-解码器注意力层(Encoder-Decoder Attention Layer)

在 Transformer 模型中,编码器-解码器注意力层的作用就像翻译过程中译员不断参考原文来生成准确的译文。这个过程在机器翻译任务中尤为重要,因为解码器需要时刻“回头”检查编码器生成的信息,从而生成正确的目标语句。


编码器-解码器注意力层的作用是什么?

在翻译任务中,解码器在生成每个词时都需要参考原句的上下文。这个层的作用就是帮助解码器根据编码器的结果找到与当前词最相关的原句信息。

可以把它想象成翻译人员在翻译过程中不断看回原文。例如在翻译“我在吃苹果”时,解码器在生成每个中文词(如“我”或“吃”)时,都需要回看编码器的输出,看它对应的是英文原文中的哪个词。

  • 编码器:负责处理输入句子的所有词,将它们变成包含信息的向量表示。
  • 编码器-解码器注意力层:解码每个词时,会查看编码器的结果,找出当前词最相关的信息。

工作原理:如何进行计算?

编码器-解码器注意力层的计算过程与自注意力机制类似,但来源略有不同:

  • Query:来自解码器当前步骤的向量。
  • Key 和 Value:来自编码器处理后的所有词的向量。

公式如下:

Attention ( Q , K , V ) = softmax ( Q ⋅ K T d k ) ⋅ V \text{Attention}(Q, K, V) = \text{softmax}\left(\frac{Q \cdot K^T}{\sqrt{d_k}}\right) \cdot V Attention(Q,K,V)=softmax(dk QKT)V

  • Query:解码器的输出,用来询问“我当前的翻译需要关注什么?”。
  • Key 和 Value:来自编码器的输出,表示输入句子的全部信息。
  • Softmax:将注意力权重转化为概率分布,让模型专注于当前需要的关键词。

类比:在课本中查找答案

想象你在做测验时允许参考课本。当遇到问题“地球为什么会有四季?”时,你不需要翻阅整本书,而会找到与“地理、季节”相关的章节。这种查找过程就像是解码器根据编码器的输出选择性参考信息:

  • 课本的内容(Key 和 Value):是编码器处理后的输入信息。
  • 你的问题(Query):是解码器当前翻译词的需求。
  • 查阅过程:通过计算相似度,找出最相关的信息并重点关注。

代码实现:编码器-解码器注意力层

以下代码展示了如何使用 PyTorch 实现编码器-解码器注意力层:

import torch
import torch.nn as nn

class EncoderDecoderAttention(nn.Module):
    def __init__(self, embed_size, heads):
        super(EncoderDecoderAttention, self).__init__()
        self.heads = heads
        self.embed_size = embed_size
        self.head_dim = embed_size // heads

        assert self.head_dim * heads == embed_size, "Embedding size must be divisible by heads"

        self.values = nn.Linear(self.embed_size, self.embed_size, bias=False)
        self.keys = nn.Linear(self.embed_size, self.embed_size, bias=False)
        self.queries = nn.Linear(self.embed_size, self.embed_size, bias=False)
        self.fc_out = nn.Linear(self.embed_size, self.embed_size)

    def forward(self, query, key, value, mask):
        N = query.shape[0]
        query_len, key_len = query.shape[1], key.shape[1]

        queries = self.queries(query).view(N, query_len, self.heads, self.head_dim)
        keys = self.keys(key).view(N, key_len, self.heads, self.head_dim)
        values = self.values(value).view(N, key_len, self.heads, self.head_dim)

        energy = torch.einsum("nqhd,nkhd->nhqk", [queries, keys])  # (N, heads, query_len, key_len)

        if mask is not None:
            energy = energy.masked_fill(mask == 0, float("-1e20"))

        attention = torch.softmax(energy / (self.embed_size ** (1/2)), dim=3)

        out = torch.einsum("nhql,nlhd->nqhd", [attention, values]).reshape(
            N, query_len, self.embed_size
        )

        out = self.fc_out(out)
        return out

# 测试编码器-解码器注意力层
embed_size = 256
heads = 8
attention_layer = EncoderDecoderAttention(embed_size, heads)

query = torch.rand(64, 10, embed_size)
key = torch.rand(64, 15, embed_size)
value = torch.rand(64, 15, embed_size)
mask = None

out = attention_layer(query, key, value, mask)
print(out.shape)  # 输出应为 (64, 10, 256)


代码解析

  1. EncoderDecoderAttention 类:定义了编码器-解码器注意力层,接受来自解码器的 Query 和编码器的 Key、Value。
  2. forward() 方法:计算 Query 和 Key 的相似度,使用 Softmax 得到注意力权重,再加权 Value。
  3. einsum 函数:高效地进行矩阵乘法,生成注意力权重和加权输出。

总结

编码器-解码器注意力层在 Transformer 中的核心作用是让解码器在生成每个词时都能“回看”编码器的输出,从而确保输出内容准确、连贯。这种结构在机器翻译中尤为关键,因为它帮助模型根据输入语句的上下文生成合理的输出。

希望这篇文章帮你更好地理解了编码器-解码器注意力层的工作原理和代码实现!如果有疑问,欢迎留言讨论!

### Transformer架构中的编码-解码工作原理 Transformer是一种基于注意力机制的神经网络模型,它通过编码器Encoder)和解码器Decoder)来实现输入序列到目标序列的转换。其核心在于自注意力机制(Self-Attention Mechanism),这使得模型能够并行处理整个输入序列而无需依赖于循环结构。 #### 编码器部分 编码器由多个相同的层堆叠而成,每一层主要包含两个子层:多头自注意力机制(Multi-head Self-Attention)和前馈全连接网络(Feed Forward Neural Network)。 - **多头自注意力机制**允许模型关注输入序列的不同位置,从而捕获全局上下文信息[^1]。 - **残差连接(Residual Connection)**被应用于每个子层之后,并配合层归一化(Layer Normalization)以稳定训练过程[^2]。 以下是编码器的主要操作流程: 1. 输入嵌入向量经过位置编码(Positional Encoding)后送入第一个编码器层。 2. 多头自注意力机制计算当前词与其他词之间的关系权重。 3. 前馈全连接网络进一步提取特征。 4. 输出作为下一层编码器的输入,直到最后一层完成编码。 #### 解码器部分 解码器同样由多个相同层组成,每层除了具有与编码器类似的两种子层外,还额外增加了一个“编码器-解码器注意力”子层。该子层用于捕捉源序列和目标序列之间跨语言的信息关联[^3]。 具体来说: - 首先,在解码过程中应用掩码多头自注意力机制(Masked Multi-head Self-Attention),防止当前位置看到后续单词的内容。 - 接着,“编码器-解码器注意力”利用来自编码器的最后一层表示生成加权平均值。 - 最终,通过线性变换和Softmax函数预测下一个可能的目标词概率分布。 #### 架构图解说明 下面是一个简单的代码示例展示如何构建基本的Transformer模块: ```python import torch.nn as nn from transformers import BertTokenizer, BertModel class SimpleTransformer(nn.Module): def __init__(self, vocab_size, d_model=512, num_heads=8, num_layers=6): super(SimpleTransformer, self).__init__() self.embedding = nn.Embedding(vocab_size, d_model) encoder_layer = nn.TransformerEncoderLayer(d_model=d_model, nhead=num_heads) self.encoder = nn.TransformerEncoder(encoder_layer, num_layers=num_layers) def forward(self, src): embedded_src = self.embedding(src) # (batch_size, seq_len, d_model) encoded_output = self.encoder(embedded_src) # Encoder processing return encoded_output ``` 此代码片段仅展示了编码器的部分功能;完整的Transformer还需要加入解码器以及相应的交叉注意机制。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值