基于自注意力机制的句子表示的理解

基于自注意力机制的句子表示

相关代码实现已放置在 Github: https://github.com/kenjewu/Structured-Self-Attentive-Sentence-Embedding


句子表示的思路

句子由词所组成,所以一般首先将句子切分为连续的词,对词进行表示,然后将每个词的表示以各种组合方式组合起来表示句子。

  • 常见的词的表示方法有:

    1. One-Hot 表示
    2. 词嵌入 (Embedding)

    对于 One-Hot 表示存在的问题是,句子的词矩阵将特别稀疏,每个词的表示向量只有一个值为 1,其余全为0。并且任意两个词的表示向量 w1, w2 都是正交的,即 w1 w2T = 0 ,这样就没法表示词的语义之间的关系。而且当数据特别多的时候,此时词的个数特别大,这时候会出现维度诅咒的问题。

    对于词嵌入表示方式,是将每个词通过相应的技术用低维的稠密的向量表示,如 Word2Vec, Glove, FastText 等。这样表示的词通过求两个词向量之间的余弦距离可以得到它们之间的语义相似度,并且解决了维度爆炸的问题。

    Note: Word2Vec, Glove, FastText 的详细细节可阅读相关论文

  • 词表示组合为句子表示的方法:

    假设 句子 sentence : w1, w2, w3, w4

    1. 拼接, 即将各个词的向量表示拼接起来。
      基于自注意力机制的句子表示的理解_第1张图片
    2. 相加求平均, 即将各个词的向量表示相加后除词的个数。
      基于自注意力机制的句子表示的理解_第2张图片
    3. CNN + GlobalMaxPooling
      基于自注意力机制的句子表示的理解_第3张图片
      通过多个窗口大小的 卷积核抓取信息后,在卷积结果上进行全局最大池化提取特征,并将多个通道的结果拼接起来作为最后句子向量的表示。

    4. Bi-LSTM 取最后一步输出
      基于自注意力机制的句子表示的理解_第4张图片
      将每个词按次序作为双向的 LSTM 神经网络的输入,取网络最后一步的输出作为句子向量的表示。


基于自注意力的句子的表示

  • 注意力 Attention

    可以直观的把注意力想象成我们人类看东西时的过程,如:当你正在和 HR 面试,你的眼睛可以看到我们视野类的所有东西,但是此时我们看的最清楚(或者印象最深) 的是正在和你交流的面试官的脸,而旁边的其他环境如桌椅板凳我们就不是那么在意。再如我们理解英文文章句子意思的时候,我们从头开始读,我们总是对当前句子和它前后的一些句子比较关注,也就是上下文,对离它很有的句子就不是那么在意。这就是注意力的直观感受。在算法设计上,我们用一组带有参数的向量或者矩阵来模拟我们的眼睛,这组参数中,数值更大的部分所对应的位置往往就是在数据相应位置中我们更在意的部分,相对的就是不那么在意的部分。
    基于自注意力机制的句子表示的理解_第5张图片
    如图,0.1 与 0.2 所对应的词 w1, w3, w4 就不在那么重要,w2 最后就变得比较重要,这样在要通过词去表示句子的时候,注意力机制就能把我句子中重要的词而减少一些对句子语义有干扰的干扰词的作用。

  • 基于自注意力机制与 Bi-LSTM 结合表示句子的模型

    基于自注意力机制的句子表示的理解_第6张图片
    在上图的左部分 (a) 中首先将每个词的词词向量放入一个双向的 LSTM 网络中,假定有 n 个词,LSTM 的隐藏单元个数为 u, 那在 LSTM 网络的每个时间步输出可以得到对每个时间步词向量的更高级的抽象表示 Aii,维度为 2u,则所有的词的表示就是一个 n -by-2u 的矩阵。具体计算过程如下:

    wt表示第 t 步的词向量,则:

    ht=LSTM(wt,ht1)ht=LSTM(wt,ht1)ht=htht h t → = L S T M → ( w t , h t − 1 → ) h t ← = L S T M ← ( w t , h t − 1 ← ) h t = h t → ⨁ h t ←

    这样综合所有的时间步可得:
    H=(h1,h2,...,hn) H = ( h 1 , h 2 , . . . , h n )

    接着就可以在 H 上施加注意力机制。

    在图的右部分(b)中解释了如何在 H 上施加注意力,整个 (b) 部分的模型图可以概括为以下公式:

    a=softmax(ws2tanh(Ws1HT)) a = s o f t m a x ( w s 2 t a n h ( W s 1 H T ) )

    在这里 Ws1是个一个权重矩阵,形状为: da-by-2u 。ws2 是一个向量,向量长度为 da, 其中 da是一个超参数。通过上面的公式最后就可以得到注意力向量 a,长度为 n,并且因为使用了 softmax 函数,所以向量 a 的每个元素代表一个概率,所有的元素的和应该为 1。在得到 a 之后,将 H 的每个元素与 a 中对应的元素相乘后相加就可以得到最后句子的表示,这个过程中就对 H 中每个词的表示赋予了不同的权重,也就是施加了不同的注意力。

  • 注意力提升

    当只使用一个注意力 a 的时候可以在句子的某种语义蕴含上对句子的词施加不同的注意力权重,但自然语言的语义往往是复杂的,抽象的,句子通常蕴含着多种子语义。一种语义上的注意力可能只能在这种语义上表现出较为合理的效果,但在其他语义上可能就不那么有效。为了解决这个问题,可以加强注意力的数量,即使用多个 不同的 a, 也就是说此时的 w2不再是一个向量,而应该是一个矩阵 Ws2,形状为 r-by_da,这里 r 就是想使用的不同注意力的个数,这样最后得到的也是一个注意力矩阵 A。

    A=softmax(Ws2tanh(Ws1HT)) A = s o f t m a x ( W s 2 t a n h ( W s 1 H T ) )

    在得到注意力矩阵 A 后,以同样的原理执行 M = AH,这样就可以得到句子的表示为一个 r-by-2u 的矩阵。

  • 注意力提升可能产生的问题和解决方案

    上面解释了试用 r 个注意力可以提高对不同语义混合的句子的表示,但如果最后得到的注意力矩阵 A (r-by-n) 中若每行的值都很接近,也就是说几个注意力没什么区别,那在之后的 M = AH 中,得到的 M 中就会包含很多冗余的信息。

    所以为了解决这个问题,我们应该设法迫使 A 能够保证每行的值具有明显的差异,也就是说尽量去满足注意力的多样性,而不是得到没什么区别的 r 个注意力。因此可以采用一个惩罚项来达到这个目的。

    P=||(AATI)||2F P = | | ( A A T − I ) | | F 2

    从上面的公式中可以得到若 A的每行值越相似,那 P 的结果就会越大,A 的值每行越不相似, P 就越小。这样就可以表示当 A 的 r 个注意力多样性越大时,P越小,反之就越大。所以将这个惩罚项与 模型的 Loss 一起参与训练,就可以尽量去保证 A 的多样性。
    NewLoss=Loss+λP N e w L o s s = L o s s + λ P

    Note: 此处的解决方案的原理有点类似 L2 正则化


注意力机制在句子上的可视化结果

  • 在情感分析的句子上

    1. 正面:
      这里写图片描述

    2. 负面:
      这里写图片描述

  • 施加了 P 惩罚项与没施加惩罚项的区别

    1. 施加了 P:
      这里写图片描述

    2. 未施加 P:
      这里写图片描述


总结

注意力机制在对句子的语义表示上有着明显的提升作用,能帮助模型更有效的去捕获对句子语义有重要作用的词并且消除干扰词的印象。多种注意力的结合能提升句子在复杂语义上的表示,弥补单注意力的不足。合理地使用惩罚项能有效的解决多注意力在最后学的的多样性不足时产生的信息冗余的问题。


代码实现链接

https://github.com/kenjewu/Structured-Self-Attentive-Sentence-Embedding
如果该代码对您的工作学习有帮助,请点个star。欢迎大家指正,提出更好的写法意见,转载请贴上引用。


参考文献

  1. A Structured Self-Attentive Sentence Embedding

  2. Attention Is All You Need

  3. Convolutional Neural Networks for Sentence Classification

你可能感兴趣的:(自然语言处理(NLP),注意力机制,自然语言处理,句子表示,神经网络,词向量)