深度学习和自然语言处理中的attention和memory机制

Attention 机制是最近深度学习的一个趋势。在一次采访中,OpenAI 的研究总监 Ilya Sutskever 说 attention 机制是最令人兴奋的进步之一,而且已经广为使用。听起来激动人心吧。但 attention 机制究竟是什么呢?

神经网络里的 attention 机制是(非常)松散地基于人类的视觉注意机制。人类的视觉注意机制已经被充分地研究过了,而且提出了多个不同的模型,所有的模型归根结底都是按照“高分辨率”聚焦在图片的某个特定区域并以“低分辨率”感知图像的周边区域的模式,然后不断地调整聚焦点。

Attention 在神经网络领域有着很长的历史,尤其是在图像识别领域。相关的论文有Learning to combine foveal glimpses with a third-order Boltzmann machineLearning where to Attend with Deep Architectures for Image Tracking。但直到最近,attention 机制才被引入 NLP 界常用的(视觉领域也逐步使用的)递归神经网络结构中。这正是我们这篇文章的主要关注点。

attention 解决了什么问题?

我们以神经机器翻译(Neural Machine Translation,NMT)为例,来理解 attention 能为我们做什么。传统的机器翻译系统通常依赖于基于文本统计特性的复杂特征工程。简而言之,这些系统非常复杂,需要投入大量工程来搭建它们。神经机器翻译系统则有所区别。在 NMT 系统里,我们把一句话的意思映射为一个固定长度的表征向量,然后基于此向量生成翻译文本。由于不依赖于类似 n-gram 计数,而是捕捉文本更高层次的含义,NMT 系统生成的翻译语句比大多数其它方法都要好。更重要的是,NMT 系统的搭建和训练过程更方便,它们不需要任何手工的特征工程。事实上,TensorFlow 只需要几百行代码就能实现一个简单版本

大多数 NMT 系统使用递归神经网络(RNN)将源语句(比如,一句德语)编码为一个向量,然后同样用 RNN 将其解码为英语句子。

如上图所示,“Echt”、“Dicke”和“Kiste”依次输入到编码器中,一个特殊字符标志输入结束(图中未显示),然后解码器开始生成翻译的语句。解码器持续逐词地生成,直到生成句子的终止符。这里的 h 向量表示了编码器的内部状态。

如果你仔细观察,你会发现解码器在翻译时仅依赖编码器最后的隐藏状态(上图的 h3)。h3 向量必须对源句子的所有内容都进行编码。它必须充分地捕捉含义。用专业术语来说,这个向量就是一个 sentence embedding。事实上,如果你用 PCA 或者 t-SNE 降维之后将不同句子的 embedding 绘制出来,你将看到语义相近的句子彼此很接近。真是令人觉得神奇。

然而,我们似乎无法把一个很长的句子所包含的所有信息编码成一个向量,然后解码器仅根据这个向量生成完美的翻译,这种假设显得不可理喻。我们假设原文句子长度有 50 个单词。英文译文的第一个单词可能与原文的第一个单词高度相关。但这意味着解码器必须考虑 50 步之前的信息,而且那段信息需要以某种形式已经被编入向量中。众所周知,RNN 在处理这类长距离依赖关系时会出现问题。理论上,LSTM这类结构能够处理这个问题,但在实践中,长距离依赖关系仍旧是个问题。例如,研究人员发现将原文倒序(将其倒序输入编码器)产生了显著改善的结果,因为从解码器到编码器对应部分的路径被缩短了。同样,两次输入同一个序列似乎也有助于网络更好地记忆。

我认为倒序句子这种方法属于“hack”手段。它属于被实践证明有效的方法,而不是有理论依据的解决方法。大多数翻译的基准都是用法语、德语等语种,它们和英语非常相似(即使汉语的词序与英语也极其相似)。但是有些语种(像日语)句子的最后一个词语在英语译文中对第一个词语有高度预言性。那么,倒序输入将使得结果更糟糕。还有其它办法吗?那就是 Attention 机制。

有了 Attention 机制,我们不再需要将完整的原文句子编码为固定长度的向量。相反,我们允许解码器在每一步输出时“参与(attend)”到原文的不同部分。尤为重要的是我们让模型根据输入的句子以及已经产生的内容来决定参与什么。因此,在形式非常相似的语种之间(如英语与德语),解码器可能会选择顺序地参与事情。生成第一个英语词语时参与原文的第一个词语,以此类推。这正是论文Neural Machine Translation by Jointly Learning to Align and Translate的成果,如下图所示:

y’是编码器生成的译文词语,x’是原文的词语。上图使用了双向递归网络,但这并不是重点,你先忽略反向的路径吧。重点在于现在每个解码器输出的词语 yt 取决于所有输入状态的一个权重组合,而不只是最后一个状态。a’是决定每个输入状态对输出状态的权重贡献。因此,如果 a3,2 的值很大,这意味着解码器在生成译文的第三个词语时,会更关注与原文句子的第二个状态。a’求和的结果通常归一化到 1(因此它是输入状态的一个分布)。

Attention 机制的一个主要优势是它让我们能够解释并可视化整个模型。举个例子,通过对 attention 权重矩阵 a 的可视化,我们能够理解模型翻译的过程。

我们注意到当从法语译为英语时,网络模型顺序地关注每个输入状态,但有时输出一个词语时会关注两个原文的词语,比如将“la Syrie”翻译为“Syria”。

Attention 的成本

如果再仔细观察 attention 的等式,我们会发现 attention 机制有一定的成本。我们需要为每个输入输出组合分别计算 attention 值。50 个单词的输入序列和 50 个单词的输出序列需要计算 2500 个 attention 值。这还不算太糟糕,但如果你做字符级别的计算,而且字符序列长达几百个字符,那么 attention 机制将会变得代价昂贵。

其实它和我们的直觉恰恰相反。人类的注意力是节省计算资源的。当专注于一件事时,我们能忽略其它事情。但这并不是我们上一个模型的作法。我们在决定专注于某个方面之前先仔细观察每件事。直观地说,这相当于输出一个翻译后的词语,然后遍历记忆里所有文本再决定下一个输出什么。这似乎是一种浪费,而且没人会这么干。事实上,它更类似于内存访问,不是 attention,在我看来有点儿用词不当(下文会继续讨论)。不过,这并没有阻碍 attention 机制的流行传播。

attention 的另一种替代方法是用强化学习(Reinforcement Learning)来预测关注点的大概位置。这听起来更像是人的注意力,这也是Recurrent Models of Visual Attention文中的作法。然而,强化学习模型不能用反向传播算法端到端训练,因此它在 NLP 的应用不是很广泛。

机器翻译之外领域的 Attention 机制

到目前为止,我们已经见识了 attention 在机器翻译领域的应用。但上述的 attention 机制同样也能应用于递归模型。让我们再来看几个例子。

Show,Attend and Tell一文中,作者将 attention 机制应用于生成图片的描述。他们用卷积神经网络来“编码”图片,并用一个递归神经网络模型和 attention 机制来生成描述。通过对 attention 权重值的可视化(就如之前机器翻译的例子一样),在生成词语的同时我们能解释模型正在关注哪个部分。

Grammar as a Foreign Language论文中,作者用递归神经网络模型和 attention 机制的来生成语法分析树。可视化的 attention 矩阵让人深入地了解网络模型如何生成这些树:

Teaching Machines to Read and Comprehend论文里,作者利用 RNN 模型读入文本,先读入一个(合成的)问题,然后产生一个答案。通过将 attention 可视化,我们可以看到网络模型在试图寻找问题答案的时候关注哪些方面:

ATTENTION = (FUZZY) MEMORY?

attention 机制解决的根本问题是允许网络返回到输入序列,而不是把所有信息编码成固定长度的向量。正如我在上面提到,我认为使用 attention 有点儿用词不当。换句话说,attention 机制只是简单地让网络模型访问它的内部存储器,也就是编码器的隐藏状态。在这种解释中,网络选择从记忆中检索东西,而不是选择“注意”什么。不同于典型的内存,这里的内存访问机制是弹性的,也就是说模型检索到的是所有内存位置的加权组合,而不是某个独立离散位置的值。弹性的内存访问机制好处在于我们可以很容易地用反向传播算法端到端地训练网络模型(虽然有 non-fuzzy 的方法,其中的梯度使用抽样方法计算,而不是反向传播)。

记忆机制本身的历史更久远。标准递归网络模型的隐藏状态本身就是一种内部记忆。RNN 由于存在梯度消失问题而无法从长距离依赖学习。LSTM通过门控机制对此做了改善,它允许显式的记忆删除和更新。

更复杂的内存结构的趋势还在延续。End-To-End Memory Networks一文中的方法允许网络在输出内容前多次读入相同的序列,每一步都更新记忆内容。举个例子,输入一个故事,在经过多步推理之后回答一个问题。然而,当网络参数的权重以某种特定方式被绑定,端到端记忆网络的记忆机制就和这里所介绍的 attention 机制一样了,只是它是多跳的记忆(因为它试图整合多个句子信息)。

神经图灵机器使用类似的记忆机制,但有一个更复杂的解决方案,它同时基于内容(如在这里)和位置,使网络模型通过学习模式来执行简单的计算机程序,比如排序算法。

在将来,我们很可能看到记忆机制和 attention 机制之间有更清晰的区别,也许是沿着Reinforcement Learning Neural Turing Machines,它尝试学习访问模式来处理外部接口。

原文地址:ATTENTION AND MEMORY IN DEEP LEARNING AND NLP(译者 / 赵屹华 审校 / 刘翔宇 责编 / 仲浩)

译者简介:赵屹华,计算广告工程师 @搜狗,前生物医学工程师,关注推荐算法、机器学习领域。