tensorflow - 可变长度序列上的 RNN 注意力权重是否应该重新归一化为 "mask"零填充的影响?

标签 tensorflow machine-learning deep-learning recurrent-neural-network attention-model

需要明确的是,我指的是 Hierarchical Attention Networks for Document Classification 中描述的类型的“ self 关注”并在很多地方实现,例如:here 。我不是指的是编码器-解码器模型(即 Bahdanau)中使用的 seq2seq 类型的注意力,尽管我的问题也可能适用于此......我只是不太熟悉它。

自注意力基本上只是计算 RNN 隐藏状态的加权平均值(均值池的推广,即非加权平均值)。当同一批处理中存在可变长度序列时,它们通常会用零填充到批处理中最长序列的长度(如果使用动态 RNN)。当计算每个序列的注意力权重时,最后一步是 softmax,因此注意力权重总和为 1。

但是,在我见过的每一个注意力实现中,都没有注意掩盖或以其他方式取消零填充对注意力权重的影响。这对我来说似乎是错误的,但我担心我可能错过了一些东西,因为似乎没有人对此感到困扰。

例如,考虑一个长度为 2 的序列,用零填充到长度 5。最终,这会导致注意力权重被计算为类似的 0 填充向量的 softmax,例如:

weights = softmax([0.1, 0.2, 0, 0, 0]) = [0.20, 0.23, 0.19, 0.19, 0.19]

并且因为 exp(0)=1,零填充实际上“淡化”了注意力权重。在 softmax 操作之后,通过将权重与二进制掩码相乘,可以很容易地解决这个问题,即

mask = [1, 1, 0, 0, 0]

然后重新将权重归一化为 1。这将导致:

weights = [0.48, 0.52, 0, 0, 0]

当我这样做时,我几乎总是看到性能提升(在我的模型的准确性方面 - 我正在做文档分类/回归)。那么为什么没有人这样做呢?

有一段时间,我认为也许最重要的是注意力权重的相对值(即比率),因为无论如何梯度都不会通过零填充。但是,如果归一化并不重要,为什么我们要使用 softmax,而不是仅仅使用 exp(.)呢? (另外,这并不能解释性能的提升......)

最佳答案

问得好!我相信您的担忧是有效的,填充编码器输出的零注意力分数确实会影响注意力。但是,您必须牢记以下几个方面:

  • 有不同的评分函数,tf-rnn-attention 中的一个。使用简单的线性+ tanh + 线性变换。但即使是这个分数函数也可以学习输出负分数。如果您查看代码并想象 inputs 由零组成,则向量 v 由于偏差不一定为零,并且与 u_omega 的点积可以将其进一步提升到较低的负数(换句话说,具有非线性的简单神经网络可以做出正预测和负预测)。低负分数不会淡化 softmax 中的高分数。

  • 由于分桶技术,桶内的序列通常具有大致相同的长度,因此不太可能有一半的输入序列用零填充。当然,它并不能解决任何问题,它只是意味着在实际应用中,填充的负面影响自然是有限的。

  • 你最后提到了这一点,但我也想强调一下:最终的参与输出是编码器输出的加权和,即相对> 值(value)观实际上很重要。以您自己的示例为例,计算本例中的加权和:

    • 第一个是0.2 * o1 + 0.23 * o2(其余为零)
    • 第二个是0.48 * o1 + 0.52 * o2(其余的也为零)


    是的,第二个向量的大小是原来的两倍,这不是一个关键问题,因为它随后进入线性层。但与屏蔽相比,o2 的相对关注度仅高出 7%。

    这意味着,即使注意力权重不能很好地学习忽略零输出,输出向量的最终效果仍然足以让解码器考虑正确的输出,在本案例重点关注 o2

希望这能让您相信重新规范化并不那么重要,尽管如果实际应用,可能会加快学习速度。

关于tensorflow - 可变长度序列上的 RNN 注意力权重是否应该重新归一化为 "mask"零填充的影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49522673/

相关文章:

tensorflow - 尝试使用 tf.scan() 实现循环网络

arrays - 了解 word2vec (TensorFlow) 中的输入和标签

ios - 我们如何在 iOS 11 中使用 CoreML 框架进行手写检测

machine-learning - 使用带注释的文档创建注释任务

python - Tensorflow 中何时需要 watch() 函数来启用梯度跟踪?

python - tensorflow.contrib 中的 KMeans 与 KMeansClustering

machine-learning - 进行 PCA 分解后,所有分类器都给出完全相同的精度

machine-learning - 神经网络模型不学习?

python - 如何在 Tensorflow 中设置分层学习率?

machine-learning - 如何使用 deeplearning4j 将混合类型输入连接到多层网络中?