最近的一些在NLU中可视化实验总结,包括AttentionPooling1D、GlobalMaxPooling1D的物理意义,这里分享一下。

在进行NLU任务时,我们常常通过词(或字)向量序列通过Pooling的方法获得局向量(或文档)的表示。这样的Pooling方法常见有:

  • AveragePooling
  • MaxPooling
  • MinVariancePooling
  • AttentionPooling
  • SIF
  • TF-IDF作为权重对向量序列进行加权平均
  • 等等

以上方法都是无监督,Pooling消耗资源极小。考虑对NLP的序列都是不定长,以上方法都应该支持Mask。以上相关实现和实验可参看sentence-embedding

AttentionPooling1D

然而,我们面临一个疑问,以上Pooling方法是否可理解?这里我们不深入探讨“可理解”是什么?直观点,以上Pooling方法是否真的捕获了对下游任务相关的信息。Pooling过程把词向量序列Aggregation成一个定长向量,这个过程必然有大量的信息丢失,那么Pooling有效必须要保留对下游任务有用的信息而过滤无用的信息。

一种加权平均向量序列来获得背景向量的方法,当然这只是基本思路或者说是启发,那么如何计算加权平均的权重呢?很简单,既然是神经网络,那就让权重也自己学习出来就好了。假设有向量序列,注意是向量序列,即每个元素也是向量,

考虑到不定长的情况存在,如在传感器的多维时序中,不同样本的长度是不一样的。计算权重直接用两个全连接网络,

然后加权平均,

如果序列是不定长,处理好掩码问题。我们可以认为,这也是注意力机制的一种,不过没有query,也就是没有主动聚焦的信息点,因此可以把以上方法理解为一种参数化显著性注意力。为提高信息的整合能力,毕竟把序列变为向量,或多或少会丢失信息。此池化方法甚至可以多头化,即类似于Attention Is All You Need中提到的多头注意力,不过要注意过拟合问题。

实现

AttentionPooling1D的call函数和字词重要性权重的实现如下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class AttentionPooling1D(tf.keras.layers.Layer):

def call(self, inputs, mask=None):
if mask is None:
mask = 1
else:
# 扩展维度便于广播
mask = tf.expand_dims(tf.cast(mask, tf.float32), -1)
x0 = inputs
# 计算每个 time steps 权重
w = self.k_dense(inputs)
w = self.o_dense(w)
# 处理 mask
w = w - (1 - mask) * 1e12
# 权重归一化
w = tf.math.softmax(w, axis=1) # 有mask位置对应的权重变为很小的值
# 加权平均
x = tf.reduce_sum(w * x0, axis=1)
return x, w

分类问题示例

输出的权重$w$作为文本的重要性权重,根据权重的大小渲染文本的颜色深浅,颜色越深越红,重要性越大,

这里可视化使用红色系colormap,颜色越深代表权重越大,反之则越小,如下:

示例一:

新闻标题分类,

示例二:

正负情感分类,

示例三:

四情感分类,

示例四:

长文分类,

示例五:

把分类问题化为文本与标签的匹配问题,

匹配问题示例

示例五:

文本匹配Attentionpooling可视化示例一,

文本匹配Attentionpooling可视化示例二,

文本匹配Attentionpooling可视化示例三,使用triplet loss,

基于交互的匹配示例

示例一,

示例二,

应用于数据扩充

既然以上方法能够定位关键字句,那么它可以作为数据扩充方案:新样本的构造来自原原本中关键字句的替换与删减。甚至是关键词掩码,提升模型的学习难度。

从另外一个角度看,这似乎是对抗样本生成的一种方案。

代码分享

源码可参看:text-attentionpooling-visualization,其中也包括多头Pooling示例。

更多可视化可参看:text-attentionpooling-visualization

类似的实验globalmaxpool源码可参看:text-globalmaxpool-visualization

总结

实验表明,这两种方法都可以捕获句子中的关键信息。然而从可视化角度看,以上方法及其相关改进都是“入侵式”,即为了获得上述可视化效果,模型上强迫你使用GlobalMaxPooling和AttentionPooling等组件。

后续更新一种新方法:integrated-gradients,它是一种比较通用的可视化方法来理解神经网络在具体任务上的表现。

转载请包括本文地址:https://allenwind.github.io/blog/13095
更多文章请参考:https://allenwind.github.io/blog/archives/