1

我正在 Pytorch 中编写一个序列来序列神经网络。在官方 Pytorch seq2seq 教程中,有一个我无法理解/认为可能包含错误的注意力解码器代码。

它通过连接此时的输出和隐藏状态来计算每个时间步的注意力权重,然后乘以一个矩阵,得到一个大小等于输出序列长度的向量。请注意,这些注意力权重不依赖于编码器序列(在代码中命名为 encoder_outputs),我认为它应该如此。

此外,本教程中引用的论文列出了三种不同的得分函数,可用于计算注意力权重(论文第 3.1 节)。这些函数都不是仅仅连接矩阵并乘以矩阵。

所以在我看来,教程中的代码在它应用的函数和传递给这个函数的参数中都是错误的。我错过了什么吗?

4

2 回答 2

0

本教程在您提到的 Luong 论文中提供了这些注意事项的简化版本。

它只是使用一个线性层来组合输入嵌入和解码器 RNN 隐藏状态。这有时被称为“基于位置的”注意力,因为它不依赖于编码器的输出。然后它应用 softmax 并计算注意力权重,这个过程就像往常一样进行。

这并不总是坏事,因为从编码器输出来看,注意力机制可能会关注前一个令牌,然后注意力不会是单调的,所以你的模型会失败。

为了实现 Luong 论文中的注意力,我建议在将线性层应用于解码器隐藏状态和编码器输出之后,使用“concat”注意力。然后矩阵W_a会将这些连接的结果转换为您选择的任意维度,最后v_a是一个向量,它将转换为所需的上下文向量维度。

于 2019-12-05T09:33:54.830 回答
0

在算法中,attn_weights 取决于解码参数。然后我们得到一个线性层的输出(这里是 10)。这是注意力向量。然后我们将它与encoder_outputs 相乘。因此,在每个 epoch,我们通过反向传播更新 attn_weights。口头上,在每次迭代中,它都在反向学习。让我举个例子:

我们的任务是从英语翻译成德语。

我想唱一首歌。-> Ich möchte ein Lied singen。

在解码器处,singen 动词在结尾。所以我们的解码器 attn_weights 看到解码器的输出,并学习应用输入编码的哪些部分。当你将此值与 encoder_outputs 相乘时,你会得到一个矩阵,它在必要的点上有很高的值。所以实际上这样,当解码器看到德语的句型时,它就是在学习,它必须注意输入的哪些部分。所以学习的方向是正确的,我认为。

于 2020-11-25T12:15:25.533 回答