1. 注意力机制在Seq2Seq模型中的核心价值
传统Seq2Seq模型在处理长序列时面临一个根本性缺陷:编码器必须将所有输入信息压缩到一个固定长度的上下文向量中。这就像要求你在读完一本300页的小说后,用一句话概括全书内容,然后在写书评时只能参考这句概括——显然会丢失大量细节。
注意力机制的引入彻底改变了这一局面。它允许解码器在生成每个词时,都能动态地"回头看"编码器的全部输出,并决定关注哪些部分。这种机制模拟了人类翻译时的行为:我们不会一次性记住整个句子再翻译,而是在翻译每个词时,会自然地关注原文中与之对应的部分。
从技术角度看,注意力机制解决了三个关键问题:
- 信息瓶颈:不再依赖单一上下文向量
- 长距离依赖:直接建立远距离词对词的关联
- 可解释性:通过注意力权重可视化模型决策过程
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 编码器实现的关键考量
2.1 编码器结构的延续性
虽然引入了注意力机制,但编码器结构通常可以保持与传统Seq2Seq相同。这是因为注意力机制并不要求编码器改变其基本架构,而是要求它提供更丰富的信息输出。
python复制class Seq2SeqEncoder(d2l.Encoder):
def __init__(self, vocab_size, embed_size, num_hiddens, num_layers,
dropout=0, **kwargs):
super(Seq2SeqEncoder, self).__init__(**kwargs)
self.embedding = nn.Embedding(vocab_size, embed_size)
self.rnn = nn.GRU(embed_size, num_hiddens, num_layers,
dropout=dropout)
def forward(self, X, *args):
X = self.embedding(X)
X = X.permute(1, 0, 2) # 转换为(seq_len, batch, embed_size)
output, state = self.rnn(X)
return output, state
这段代码的关键点在于:
- 仍然使用GRU作为循环单元
- 返回两个值:所有时间步的输出和最终状态
- 输出形状为(seq_len, batch, num_hiddens)
提示:虽然编码器结构可以不变,但理解其输出维度对后续实现注意力机制至关重要。编码器的每个时间步输出将成为解码器注意力的keys和values。
2.2 输出张量的维度解析
编码器输出的output张量形状为(seq_len, batch, num_hiddens),这包含了源语言句子中每个词的上下文表示。与传统Seq2Seq不同,这些中间表示不再被丢弃,而是会被完整地传递给解码器。
在实际应用中,我们需要注意:
- 批处理维度通常放在第二位,与PyTorch的默认约定一致
- 序列长度维度在前,方便按时间步迭代
- 隐藏层大小需要与解码器的注意力机
