是否应该对可变长度序列上的 RNN 注意力权重进行重新归一化以“掩盖”零填充的影响?

Posted

技术标签:

【中文标题】是否应该对可变长度序列上的 RNN 注意力权重进行重新归一化以“掩盖”零填充的影响?【英文标题】:Should RNN attention weights over variable length sequences be re-normalized to "mask" the effects of zero-padding? 【发布时间】:2018-09-06 10:34:00 【问题描述】:

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

Self-attention 基本上只是计算 RNN 隐藏状态的加权平均值(均值池的泛化,即未加权平均值)。当同一批次中有可变长度序列时,通常会将它们补零到批次中最长序列的长度(如果使用动态 RNN)。当为每个序列计算注意力权重时,最后一步是 softmax,因此注意力权重总和为 1。

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

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

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

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

掩码 = [1, 1, 0, 0, 0]

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

权重 = [0.48, 0.52, 0, 0, 0]

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

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

【问题讨论】:

【参考方案1】:

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

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

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

你最后提到了,但我也想强调一下:最终的参与输出是编码器输出的加权和,即相对值实际上事情。以您自己的示例并在这种情况下计算加权和:

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

是的,第二个向量的幅度要大两倍,这不是关键问题,因为它会进入线性层。但对o2 的相对关注度仅比掩蔽时高 7%。

这意味着即使注意力权重在学习忽略零输出方面做得不好,对输出向量的最终效果仍然足以让解码器考虑正确的输出,在这个案例集中在o2

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

【讨论】:

【参考方案2】:

BERT implementation 应用填充掩码来计算注意力分数。 将 0 添加到非填充注意力分数,并将 -10000 添加到填充注意力分数。 e^-10000 与其他注意力得分值相比非常小。

attention_score = [0.1, 0.2, 0, 0, 0]
mask = [0, 0, -10000, -10000] # -10000 is a large negative value 
attention_score += mask
weights = softmax(attention_score)

【讨论】:

以上是关于是否应该对可变长度序列上的 RNN 注意力权重进行重新归一化以“掩盖”零填充的影响?的主要内容,如果未能解决你的问题,请参考以下文章

pytorch对可变长度序列的处理

对最近数据具有更多权重的 RNN

具有可变长度序列的 RNN/LSTM 库,无需分桶或填充

使用元素研究 RNN for Torch Lua 批处理可变长度序列

如何在 TensorFlow 中处理具有可变长度序列的批次?

TensorFlow:如何使用具有可变输入长度的 CudnnLSTM(如 dynamic_rnn)?