实施注意力

Implementing Attention

我正在 PyTorch 中实现 Attention。我在实施注意力机制的过程中遇到了问题。

  1. 解码器$s_0$的初始状态是什么?一些 post 将其表示为零向量,而 some 将其实现为编码器的最终隐藏状态。那么什么是真正的$s_0$?原论文没有提到

  2. 我是否交替使用 maxout 层和 dropout 层?原论文使用了Goodfellow的maxout层。

  3. encoder和decoder的dropout概率有区别吗? Some implementation 为编码器和解码器设置不同的丢失概率。

  4. 在对齐模型(concat)中计算$a_{ij}$时,有两个可训练的权重$W$和$U$。我认为更好的实现方式是使用两个线性层。如果我使用线性层,是否应该删除线性层中的偏置项?

  5. 编码器输出的维度(=$H$) 不适合解码器的隐藏状态。 $H$ 是串联的,所以它必须是 2000(对于原始论文)。但是decoder的hidden dimension也是1000,是否需要在encoder之后加一个linear layer来适配encoder的维度和decoder的维度?

总的来说,很多答案是:在不同的实现中是不同的。该论文的原始实现位于 https://github.com/lisa-groundhog/GroundHog/tree/master/experiments/nmt。后期翻译质量更好的实现,您可以查看:

现在谈谈你的观点:

  1. 原论文中是零向量。后来的实现使用编码器最终状态或编码器状态平均值的投影。使用平均值的论点是它将梯度更直接地传播到编码器状态。不过这个决定好像对翻译质量影响不大。

  2. Maxout 层是非线性层的变体。它有点像两个 ReLU 层合二为一:你做两个独立的线性投影并取其中的最大值。您可以愉快地将 Maxout 替换为 ReLU(现代实现是这样做的),但您仍然应该使用 dropout。

  3. 当我设置不同的辍学率时,我不知道在 MT 中有任何有意义的用例。但是请注意,seq2seq 模型在可能有意义的情况下用于许多野外场景。

  4. 大多数实现在计算注意力能量时确实使用偏差。如果你使用两个线性层,你将把偏差分成两个变量。偏差通常是零初始化的,因此它们将获得相同的梯度和相同的更新。但是,您始终可以在线性层中禁用偏置

  5. 是的,如果你想用解码器状态初始化s0。在attention机制中,矩阵U负责处理。