基于注意力机制的Seq2Seq模型
题目描述
我们需要构建一个基于注意力机制的序列到序列(Seq2Seq)模型,用于机器翻译任务。给定一个源语言句子(如英文“I am a student”),模型需要生成对应的目标语言句子(如中文“我是一个学生”)。基本的Seq2Seq模型使用编码器(Encoder)将输入序列编码为一个固定长度的上下文向量,然后解码器(Decoder)基于该向量生成输出序列。但这种方法在处理长句子时,上下文向量会成为信息瓶颈,导致性能下降。注意力机制通过允许解码器在生成每个词时“关注”输入序列的不同部分来解决这个问题。
解题过程
第一步:理解基础Seq2Seq模型的结构
- 编码器:通常是一个循环神经网络(RNN),如LSTM或GRU。它按顺序读取输入序列的每个词(如“I", "am", "a", "student”)。在每个时间步,RNN会更新其隐藏状态。处理完最后一个词后,最终的隐藏状态就被视为代表了整个输入句子的“上下文向量”(C)。
- 解码器:是另一个RNN。它以上下文向量(C)作为其初始隐藏状态,并开始生成输出序列。在每一步,解码器生成一个词,并将该步的隐藏状态和生成的词作为下一步的输入,直到产生序列结束符。
问题:这个固定的上下文向量(C)必须包含输入序列的所有信息,这对于长句子来说非常困难,信息会被压缩和丢失。
第二步:引入注意力机制的核心思想
注意力机制不再强迫编码器将整个输入序列的信息压缩进一个固定长度的向量中。相反,它在解码器的每一个时间步,都动态地为其创建一个新的上下文向量。
- 关键概念:在解码器生成第
t个目标词时(例如生成“学生”时),它会“回头去看”编码器在所有输入时间步的隐藏状态,并给每一个编码器隐藏状态分配一个“注意力权重”。这个权重表示在生成当前目标词时,每个输入词的重要性有多大。 - 举例:在生成中文“学生”时,模型应该给输入英文“student”对应的编码器隐藏状态分配非常高的权重,而给“I", "am", "a”分配的权重则很低。
第三步:计算注意力权重的详细步骤
假设编码器有m个隐藏状态(h1, h2, ..., hm),分别对应m个输入词。解码器在当前时间步t的隐藏状态是st。
-
计算注意力分数(Score):首先,我们需要计算解码器当前状态
st与每一个编码器隐藏状态hi的关联程度(分数)。常用的评分函数有:- 点积(Dot):
Score(hi, st) = hi · st(最简单,要求hi和st维度相同) - 加性(Additive):
Score(hi, st) = vᵀ tanh(W1 * hi + W2 * st)(v,W1,W2是可学习参数,更灵活)
- 点积(Dot):
-
转化为注意力权重(Alignment):将所有编码器状态的分数通过一个Softmax函数进行归一化,得到权重分布
α。这使得所有权重相加为1,且每个权重都在0到1之间。α_ti = exp(Score(hi, st)) / Σⱼ exp(Score(hj, st))α_ti就是在生成第t个目标词时,第i个输入词的注意力权重。
第四步:生成当前时间步的上下文向量
- 加权求和:将上一步得到的所有注意力权重
α_ti与对应的编码器隐藏状态hi相乘并求和,得到当前时间步专属的上下文向量Ct。Ct = Σᵢ (α_ti * hi)
- 理解:这个向量
Ct不再是固定的,而是解码器在生成第t个词时,对输入序列所有信息的一个“选择性摘要”。它重点关注了与当前生成步骤最相关的输入部分。
第五步:解码器利用上下文向量生成词
现在,解码器在时间步t拥有两个关键信息:
-
它自身的隐藏状态
st。 -
新计算出的、包含相关输入信息的上下文向量
Ct。 -
拼接(Concatenate):将
st和Ct连接在一起,形成一个更丰富的向量[st; Ct]。 -
全连接层与Softmax:将这个拼接后的向量通过一个全连接层和一个Softmax层,来预测当前时间步最可能输出的词的概率分布。
输出概率 = Softmax(W * [st; Ct] + b)
-
迭代:解码器将预测出的词作为下一时间步的输入(或在推理时,使用上一步的预测结果),并更新其隐藏状态,然后重复第三步到第五步,直到生成序列结束符。
总结
通过引入注意力机制,Seq2Seq模型摆脱了固定长度上下文向量的束缚。它允许解码器在每一步生成时直接“访问”整个输入序列,并动态地选择最相关的信息。这极大地改善了对长序列的处理能力,并成为了现代NLP模型(如Transformer,其核心就是自注意力机制)的基石。