原文地址
目录
1. 前言
2. Seq2Seq 模型
3. NLP中注意力机制起源
4. NLP中的注意力机制
5. Hierarchical Attention
6. Attention机制的本质
7. Self-Attention
8. Memory-based Attention
9. Soft/Hard Attention
10. Global/Local Attention
11. 评价指标
12. 写在后面
13. 参考文献
近年来,注意力机制一直频繁出现在目之所及的文献或博文中,可见在NLP中算得上是个相当流行的概念,事实也证明其在NLP领域散发出不小得作用。这几年的顶会paper就能看出这一点。本文深入浅出的介绍近些年自然语言处理中的注意力机制包括起源、变体到评价指标方面。
据 Lilian Weng 博主[1]总结以及一些资料显示,Attention机制最早应该在视觉图像领域提出来的,这方面的工作很多,历史也比较悠久。人类视觉注意力虽然存在很多不同的模型,但他们都基本上归结为给予需要重点关注的目标区域(注意力焦点)更重要的注意力,同时给予周围的图像低的注意力,然后随着时间的推移调整焦点。
知道Bahdanau等人[3]发表论文
注意力机制首先从人类直觉中得到,在 NLP 领域的机器翻译任务上首先取得不错的效果。简而言之,深度学习中的注意力可以广义地解释为重要性权重的向量:为了预测一个元素,例如句子中的单词,使用注意力向量来估计它与其他元素的相关程度有多强,并将其值的总和作为目标的近似值。既然注意力机制最早在 NLP 领域应用于机器翻译任务,那在这个之前又是怎么做的呢?
传统的基于短语的翻译系统通过将源句分成多个块然后逐个词地翻译它们来完成它们的任务,这导致了翻译输出的不流畅。不妨先来想想我们人类是如何翻译的?我们首先会阅读整个待翻译的句子,然后结合上下文理解其含义,最后产生翻译。
从某种程度上来说,神经机器翻译(NMT)的提出正是想去模仿这一过程。而在 NMT 的翻译模型中经典的做法是由编码器 - 解码器架构制定(Encoder-Decoder),用作 Encoder 和 Decoder 常用的是循环神经网络。这类模型大概过程是首先将源句子的输入序列送入到编码器中,提取最后隐藏状态的表示并用于解码器的输入,然后一个接一个地生成目标单词,这个过程广义上可以理解为不断地将前一个时刻 t-1 的输出作为后一个时刻 t 的输入,循环解码,直到输出停止符为止。
通过这种方式,NMT 解决了传统的基于短语的方法中的局部翻译问题:它可以捕获语言中的长距离依赖性,并提供更流畅的翻译。
但是这样做也存在很多缺点,譬如,RNN 是健忘的,这意味着前面的信息在经过多个时间步骤传播后会被逐渐消弱乃至消失。其次,在解码期间没有进行对齐操作,因此在解码每个元素的过程中,焦点分散在整个序列中。对于前面那个问题,LSTM、GRU 在一定程度能够缓解健忘问题。而后者正是 Bahdanau 等人重视的问题。
在介绍注意力模型之前,不得不先学习一波 Encoder-Decoder 框架,虽然说注意力模型可以看作一种通用的思想,本身并不依赖于特定框架(比如文章[15]:Learning Sentence Representation with Guidance of Human Attention),但是目前大多数注意力模型都伴随在 Encoder-Decoder 框架下。
Seq2seq 模型最早由 Bengio 等人[17]论文《Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation》。随后 Sutskever 等人[16]在文章《Sequence to Sequence Learning with Neural Networks》中提出改进模型即为目前常说的 Seq2Seq 模型。
从广义上讲,它的目的是将输入序列(源序列)转换为新的输出序列(目标序列),这种方式不会受限于两个序列的长度,换句话说,两个序列的长度可以任意。以 NLP 领域来说,序列可以是句子、段落、篇章等,所以我们也可以把它看作处理由一个句子(段落或篇章)生成另外一个句子(段落或篇章)的通用处理模型。
对于句子对,我们期望输入句子 Source,期待通过 Encoder-Decoder 框架来生成目标句子 Target。Source 和 Target 可以是同一种语言,也可以是两种不同的语言,若是不同语言,就可以处理翻译问题了。若是相同语言,输入序列 Source 长度为篇章,而目标序列 Target 为小段落则可以处理文本摘要问题 (目标序列 Target 为句子则可以处理标题生成问题)等等等。
Seq2Seq 模型通常具有编码器 - 解码器架构:
前面谈到在 Seq2Seq 结构中,Encoder 把所有的输入序列都编码成一个统一的语义向量 context,然后再由 Decoder 解码。而 context 自然也就成了限制模型性能的瓶颈。
譬如机器翻译问题,当要翻译的句子较长时,一个 context 可能存不下那么多信息。除此之外,只用编码器的最后一个隐藏层状态,感觉上都不是很合理。
实际上当我们翻译一个句子的时候,譬如:Source: 机器学习-->Target: machine learning。当 Decoder 要生成"machine"的时候,应该更关注"机器",而生成"learning"的时候,应该给予"学习"更大的权重。所以如果要改进 Seq2Seq 结构,一个不错的想法自然就是利用 Encoder 所有隐藏层状态解决 context 限制问题。
Bahdanau 等人[3]把 Attention 机制用到了神经网络机器翻译(NMT)上。传统的 Encoder-Decoder 模型通过 Encoder 将 Source 序列编码到一个固定维度的中间语义向量 context,然后再使用 Decoder 进行解码翻译到目标语言序列。前面谈到了这种做法的局限性,而且,Bahdanau 等人[3]在其文章的摘要中也说到这个 context 可能是提高这种基本编码器 - 解码器架构性能的瓶颈,那 Bahdanau 等人又是如何尝试缓解这个问题的呢? 别急,让我们来一探究竟。
作者为了缓解中间向量 context 很难将 Source 序列所有重要信息压缩进来的问题,特别是对于那些很长的句子。提出在机器翻译任务上在 Encoder–Decoder 做出了如下扩展:将翻译和对齐联合学习。这个操作在生成 Target 序列的每个词时,用到的中间语义向量 context 是 Source 序列通过 Encoder 的所有隐藏层的加权和,而传统的做法是只用 Encoder 最后一个时刻输出 作为 context,这样就能保证在解码不同词的时候,Source 序列对现在解码词的贡献是不一样的。
想想前面那个例子:Source: 机器学习-->Target: Machine Learning (假如中文按照字切分)。Decoder 在解码"machine"时,"机"和"器"提供的权重要更大一些,同样,在解码"learning"时,"学"和"习"提供的权重相应的会更大一些,这在直觉也和人类翻译也是一致的。
通过这种 Attention 的设计,作者将 Source 序列的每个词(通过 Encoder 的隐藏层输出)和 Target 序列 (当前要翻译的词) 的每个词巧妙的建立了联系。想一想,翻译每个词的时候,都有一个语义向量,而这个语义向量是 Source 序列每个词通过 Encoder 之后的隐藏层的加权和。 由此可以得到一个 Source 序列和 Target 序列的对齐矩阵,通过可视化这个矩阵,可以看出在翻译一个词的时候,Source 序列的每个词对当前要翻译词的重要性分布,这在直觉上也能给人一种可解释性的感觉。
论文中的图也能很好的看出这一点:
更形象的图:
现在让我们从公式层面来看看这个东东 (加粗变量表示它们是向量,这篇文章中的其他地方也一样)。 假设我们有一个长度为 n 的源序列 x,并尝试输出长度为 m 的目标序列 y:
作者采样 Bidirectional RNN 作为 Encoder (实际上这里可以有很多选择),具有前向隐藏状态和后向隐藏状态。为了获得词的上下文信息,作者采用简单串联方式将前向和后向表示拼接作为 Encoder 的隐藏层状态,公式如下:
对于目标(输出)序列的每个词(假设位置为t),Decoder 网络的隐藏层状态:
其中,语义向量是源(输入)序列的隐藏状态的加权和,权重为对齐分数:
(注意:这里的 score 函数为原文的 a 函数,原文的描述为:is an alignment model)
对齐模型基于(在i时刻的输入)和(在t时刻的输出)的匹配程度分配分数。是定义每个目标(输出)单词应该考虑给每个源(输入)隐藏状态的多大的权重(这恰恰反映了对此时解码的目标单词的贡献重要性)。
在 Bahdanau[3] 的论文中,作者采用的对齐模型为前馈神经网络,该网络与所提出的系统的所有其他组件共同训练。因此,score 函数采用以下形式,tanh 用作非线性激活函数,公式如下:
其中,都是在对齐模型中学习的权重矩阵。对齐分数矩阵是一个很好的可解释性的东东,可以明确显示源词和目标词之间的相关性。
而 Decoder 每个词的条件概率为:
g 为非线性的,可能是多层的输出概率的函数,是RNN的隐藏状态, 为语义向量.
随着注意力机制的广泛应用,在某种程度上缓解了源序列和目标序列由于距离限制而难以建模依赖关系的问题。现在已经涌现出了一大批基于基本形式的注意力的不同变体来处理更复杂的任务。让我们一起来看看其在不同 NLP 问题中的注意力机制。
其实我们可能已经意识到了,对齐模型的设计不是唯一的,确实,在某种意义上说,根据不同的任务设计适应于特定任务的对齐模型可以看作设计出了新的 Attention 变体,让我们再回过头来看看这个对齐模型(函数):。再来看看几个代表性的 work。
这种方法的对齐分数仅从目标隐藏状态学习得到。
细心的童鞋可能早就发现了这东东和点积注意力很像,只是加了个 scale factor。当输入较大时,softmax 函数可能具有极小的梯度,难以有效学习,所以作者加入比例因子 .
Hu[7]对此分了个类:
前面谈到的一些 Basic Attention 给人的感觉能够从序列中根据权重分布提取重要元素。而 Multi-dimensional Attention 能够捕获不同表示空间中的 term 之间的多个交互,这一点简单的实现可以通过直接将多个单维表示堆叠在一起构建。Wang[8] 等人提出了 coupled multi-layer attentions,该模型属于多层注意力网络模型。作者称,通过这种多层方式,该模型可以进一步利用术语之间的间接关系,以获得更精确的信息。
再来看看 Hierarchical Attention,Yang[9] 等人提出了 Hierarchical Attention Networks,看下面的图可能会更直观:
这种结构能够反映文档的层次结构。模型在单词和句子级别分别设计了两个不同级别的注意力机制,这样做能够在构建文档表示时区别地对待这些内容。 Hierarchical attention 可以相应地构建分层注意力,自下而上(即,词级到句子级)或自上而下(词级到字符级),以提取全局和本地的重要信息。自下而上的方法上面刚谈完。那么自上而下又是如何做的呢?让我们看看 Ji[10] 等人的模型:
和机器翻译类似,作者依旧采用 Encoder-Decoder 架构,然后用 Word-Level Attention 对全局语法和流畅性纠错,设计 character-level attention 对本地拼写错误纠正。
上述内容就是经典的Soft Attention模型的基本思想,那么怎么理解Attention模型的物理含义呢?一般在自然语言处理应用里会把Attention模型看作是输出Target句子中某个单词和输入Source句子每个单词的对齐模型,这是非常有道理的。
目标句子生成的每个单词对应输入句子单词的概率分布可以理解为输入句子单词和这个目标生成单词的对齐概率,这在机器翻译语境下是非常直观的:传统的统计机器翻译一般在做的过程中会专门有一个短语对齐的步骤,而注意力模型其实起的是相同的作用。
我们可以这样来看待Attention机制:将Source中的构成元素想象成是由一系列的(Key,Value)数据对构成,此时给定Target中的某个元素Query,通过计算Query和各个Key的相似性或者相关性,得到每个Key对应Value的权重系数,然后对Value进行加权求和,即得到了最终的Attention数值。所以本质上Attention机制是对Source中元素的Value值进行加权求和,而Query和Key用来计算对应Value的权重系数。即可以将其本质思想改写为如下公式:
上文所举的Encoder-Decoder框架中,因为在计算Attention的过程中,Source中的Key和Value合二为一成,指向的是同一个东西,也即输入句子中每个单词对应的语义编码(输入序列每个时间步骤上的隐藏状态),所以可能不容易看出这种能够体现本质思想的结构。
从本质上理解,Attention是从大量信息中有选择地筛选出少量重要信息并聚焦到这些重要信息上,忽略大多不重要的信息。聚焦的过程体现在权重系数的计算上,权重越大越聚焦于其对应的Value值上,即权重代表了信息的重要性,而Value是其对应的信息。
Self-Attention (自注意力),也称为 Intra-Attention (内部注意力),是关联单个序列的不同位置的注意力机制,以便计算序列的交互表示。它已被证明在很多领域十分有效比如机器阅读,文本摘要或图像描述生成。
比如 Cheng[11] 等人在机器阅读里面利用了自注意力。当前单词为红色,蓝色阴影的大小表示激活程度,自注意力机制使得能够学习当前单词和句子前一部分词之间的相关性。
比如 Xu[12] 等人利用自注意力在图像描述生成任务。注意力权重的可视化清楚地表明了模型关注图像的哪些区域以便输出某个单词。
我们假设序列元素为,其匹配向量为。让我们再来回顾下前面说的基本注意力的对齐函数,attention score 通过计算得到,由于是通过将外部 u 与每个元素匹配来计算注意力,所以这种形式可以看作是外部注意力。当我们把外部 u 替换成序列本身(或部分本身),这种形式就可以看作为内部注意力(internal attention)。
我们根据文章[7]中的例子来看看这个过程,例如句子:"Volleyball match is in progress between ladies"。句子中其它单词都依赖着"match",理想情况下,我们希望使用自注意力来自动捕获这种内在依赖。换句话说,自注意力可以解释为,每个单词去和V序列中的内部模式匹配,匹配函数。很自然的选择为V中其它单词 ,这样便可以计算成对注意力得分。为了完全捕捉序列中单词之间的复杂相互作用,我们可以进一步扩展它以计算序列中每对单词之间的注意力。这种方式让每个单词和序列中其它单词交互了关系。
另一方面,自注意力还可以自适应方式学习复杂的上下文单词表示。譬如经典文章[14]:A structured self-attentive sentence embedding。这篇文章提出了一种通过引入自关注力机制来提取可解释句子嵌入的新模型。 使用二维矩阵而不是向量来代表嵌入,矩阵的每一行都在句子的不同部分,想深入了解的可以去看看这篇文章,另外,文章的公式感觉真的很漂亮。
值得一提还有2017年谷歌提出的 Transformer[6],这是一种新颖的基于注意力的机器翻译架构,也是一个混合神经网络,具有前馈层和自注意层。论文的题目挺霸气:Attention is All you Need,毫无疑问,它是2017年最具影响力和最有趣的论文之一。那这篇文章的 Transformer 的庐山真面目到底是怎样的呢?
这篇文章提出许多改进,在完全抛弃了 RNN 的情况下进行 Seq2Seq 建模。接下来一起来详细看看吧。
众所周知,在 NLP 任务中,通常的处理方法是先分词,然后每个词转化为对应的词向量。接着一般最常见的有二类操作,第一类是接 RNN(变体 LSTM、GRU、SRU 等),但是这一类方法没有摆脱时序这个局限,也就是说无法并行,也导致了在大数据集上的速度效率问题。第二类是接 CNN,CNN 方便并行,而且容易捕捉到一些全局的结构信息。很长一段时间都是以上二种的抉择以及改造,直到谷歌提供了第三类思路:纯靠注意力,也就是现在要讲的这个东东。
将输入序列编码表示视为一组键值对(K,V)以及查询 Q,因为文章[6]取K=V=Q,所以也自然称为 Self Attention。
K, V 像是 key-value 的关系从而是一一对应的,那么上式的意思就是通过 Q 中每个元素 query,与K中各个元素求内积然后 softmax 的方式,来得到 Q 中元素与 V 中元素的相似度,然后加权求和,得到一个新的向量。其中因子为了使得内积不至于太大。以上公式在文中也称为点积注意力(scaled dot-product attention):输出是值的加权和,其中分配给每个值的权重由查询的点积与所有键确定。
而 Transformer 主要由多头自注意力(Multi-Head Self-Attention)单元组成。那么 Multi-Head Self-Attention 又是什么呢?以下为论文中的图:
Multi-Head Self-Attention 不是仅仅计算一次注意力,而是多次并行地通过缩放的点积注意力。 独立的注意力输出被简单地连接并线性地转换成预期的维度。论文[6]表示,多头注意力允许模型共同关注来自不同位置的不同表示子空间的信息。 只有一个注意力的头,平均值就会抑制这一点。
是需要学习的参数矩阵。既然为 Seq2Seq 模式,自然也包括 Encoder 和 Decoder,那这篇文章又是如何构建这些的呢?莫急,请继续往下看。
编码器生成基于自注意力的表示,其能够从可能无限大的上下文中定位特定信息。值得一提的是,上面的结构文章堆了六个。
1. 每层都有一个多头自注意力层
2. 每层都有一个简单的全连接的前馈网络
3. 每个子层采用残差连接和层规范化。 所有子层输出相同维度 dmodel = 512。
解码器能够从编码表示中检索。上面的结构也堆了六个。
1. 每层有两个多头注意机制子层。
2. 每层有一个完全连接的前馈网络子层。
3. 与编码器类似,每个子层采用残差连接和层规范化。
与 Encoder 不同的是,第一个多头注意子层被设计成防止关注后续位置,因为我们不希望在预测当前位置时查看目标序列的未来。最后来看一看整体架构:
transformer这部分如果没看懂,没有关系,我们之后还会整理几篇博客进行详细介绍。
那 Memory-based Attention 又是什么呢?我们先换种方式来看前面的注意力,假设有一系列的键值对 存在内存中和查询向量q,这样便能重写为以下过程:
这种解释是把注意力作为使用查询q的寻址过程,这个过程基于注意力分数从 memory 中读取内容。聪明的童鞋肯定已经发现了,如果我们假设(encoder 每一个时间步骤上的隐藏状态),这不就是前面谈到的基础注意力么?然而,由于结合了额外的函数,可以实现可重用性和增加灵活性,所以 Memory-based Attention Mechanism 可以设计得更加强大。
那为什么又要这样做呢?在 NLP 的一些任务上比如问答匹配任务,答案往往与问题间接相关,因此基本的注意力技术就显得很无力了。那处理这一任务该如何做才好呢?这个时候就体现了 Memory-based Attention Mechanism 的强大了,譬如 Sukhbaatar[19] 等人通过迭代内存更新(也称为多跳)来模拟时间推理过程,以逐步引导注意到答案的正确位置:
在每次迭代中,使用新内容更新查询,并且使用更新的查询来检索相关内容。一种简单的更新方法为相加。那么还有其它更新方法么?
当然有,直觉敏感的童鞋肯定想到了,光是这一点,就可以根据特定任务去设计,比如 Kuma[13] 等人的工作。这种方式的灵活度也体现在 key 和 value 可以自由的被设计,比如我们可以自由地将先验知识结合到 key 和 value 嵌入中,以允许它们分别更好地捕获相关信息。看到这里是不是觉得文章灌水其实也不是什么难事了。
最后想再谈谈 Soft/Hard Attention,是因为在很多地方都看到了这个名词。
据我所知,这个概念由《Show, Attend and Tell: Neural Image Caption Generation with Visual Attention》提出,这是对 attention 另一种分类。Soft Attention 本质上和 Bahdanau 等人[3]很相似,其权重取值在0到1之间(连续值),而 Hard Attention 取值为0或者1(离散值)。
Luong 等人[4]提出了 Global Attention 和 Local Attention。Global Attention 本质上和 Bahdanau 等人[3]很相似。Global 方法顾名思义就是会关注源句子序列的所有词,具体地说,在计算语义向量时,会考虑编码器所有的隐藏状态。而在 Local Attention 中,计算语义向量时只关注每个目标词的一部分编码器隐藏状态。由于 Global 方法必须计算源句子序列所有隐藏状态,当句子长度过长会使得计算代价昂贵并使得翻译变得不太实际,比如在翻译段落和文档的时候。
在看一些带有 Attention 的 paper 时,常常会伴随着为了说明自己文章 attention 是 work 的实验,但实际上尝试提供严格数学证明的文章极少。
Hu[7]把 Attention 的评价方式分为两类,Quantitative(定量指标)和Qualitative(定性指标)。定量指标顾名思义就是对 Attention 的贡献就行量化,这一方面一般会结合下游任务,最常见的当属机器翻译,我们都知道机器翻译的最流行评价指标之一是 BLEU,我们可以在翻译任务设计 Attention 和不加 Attention 进行对比,对比的指标就是 BLEU,设置我们可以设计多种不同的 Attention 进行对比。
定性指标评价是目前应用最广泛的评价技术,因为它简单易行,便于可视化。具体做法一般都是为整个句子构建一个热力图,其热力图强度与每个单词接收到的标准化注意力得分成正比。也就是说,词的贡献越大,颜色越深。其实这在直觉上也是能够接收的,因为往往相关任务的关键词的 Attention 权值肯定要比其它词重要。比如 Hu[7] 文中的图:
本文参考了众多文献,对近些年的自然语言中的注意力机制从起源、变体到评价方面都进行了简要介绍,但是要明白的是,实际上注意力机制在 NLP 上的研究特别多,为此,我仅仅对18、19年的文献进行了简单的调研(AAAI、IJCAI、ACL、EMNLP、NAACL等顶会),就至少有一百篇之多,足见 Attention 还是很潮的,所以我也把链接放到了我的 GitHub 上。方便查阅。以后慢慢补充~~
github地址
如果没有梯子或者嫌下载麻烦又需要论文集的童鞋,可以关注我的公众号:AI小白入门,后台回复“Attention”获取资源,以下是部分截图~~
[1] Attention? Attention!.
[2] Neural Machine Translation (seq2seq) Tutorial.
[3] Neural Machine Translation by Jointly Learning to Align and Translate. Dzmitry Bahdanau, Kyunghyun Cho, and Yoshua Bengio. ICLR, 2015.
[4] Effective approaches to attention-based neural machine translation. Minh-Thang Luong, Hieu Pham, and Christopher D Manning. EMNLP, 2015.
[5] Neural Turing Machines. Alex Graves, Greg Wayne and Ivo Danihelka. 2014.
[6] Attention Is All You Need. Ashish Vaswani, et al. NIPS, 2017.
[7] An Introductory Survey on Attention Mechanisms in NLP Problems. Dichao Hu, 2018.
[8] Coupled Multi-Layer Attentions for Co-Extraction of Aspect and Opinion. Terms Wenya Wang,Sinno Jialin Pan, Daniel Dahlmeier and Xiaokui Xiao. AAAI, 2017.
[9] Hierarchical attention networks for document classification. Zichao Yang et al. ACL, 2016.
[10] A Nested Attention Neural Hybrid Model for Grammatical Error Correction. Jianshu Ji et al. 2017.
[11] Long Short-Term Memory-Networks for Machine Reading. Jianpeng Cheng, Li Dong and Mirella Lapata. EMNLP, 2016.
[12] Show, Attend and Tell: Neural Image Caption Generation with Visual Attention. Kelvin Xu et al. JMLR, 2015.
[13] Ask me anything: Dynamic memory networks for natural language processing. Zhouhan Lin al. JMLR, 2016.
[14] A structured self-attentive sentence embedding. Zhouhan Lin al. ICLR, 2017.
[15] Learning Sentence Representation with Guidance of Human Attention. Shaonan Wang , Jiajun Zhang, Chengqing Zong. IJCAI, 2017.
[16] Sequence to Sequence Learning with Neural Networks. Ilya Sutskever et al. 2014.
[17] Learning Phrase Representations using RNN Encoder–Decoder for Statistical Machine Translation. Kyunghyun Cho, Yoshua Bengio et al. EMNLP, 2014.
[18] End-To-End Memory Networks Sainbayar Sukhbaatar et al. NIPS, 2015.
[19] 《Attention is All You Need》浅读(简介+代码)