This commit is contained in:
erenup 2021-08-26 22:37:28 +08:00
parent ab21219f3d
commit eb7f458c29
1 changed files with 83 additions and 64 deletions

View File

@ -1,106 +1,125 @@
## 图解Attention
篇章1中我们对Transformers在NLP中的兴起做了概述本篇章将从attention开始逐步对Transformer结构所涉及的知识进行深入讲解希望能给读者以形象生动的描述。本小节主要对attention进行解析。
篇章1中我们对Transformers在NLP中的兴起做了概述。本教程的学习路径是Attention->Transformer->BERT->NLP应用。因此本篇章将从attention开始逐步对Transformer结构所涉及的知识进行深入讲解希望能给读者以形象生动的描述。
## seq2seq模型
首先谈一下NLP常用于生成任务的seq2seq结构。seq2seq模型结构在很多任务上都取得了成功机器翻译、文本摘要、图像描述生成。谷歌翻译在 2016 年年末开始使用这种模型。有2篇开创性的论文[Sutskever等2014年发表的Sequence to Sequence Learning
问题Attention出现的原因是什么
潜在的答案基于循环神经网络RNN一类的seq2seq模型在处理长文本时遇到了挑战而对长文本中不同位置的信息进行attention有助于提升RNN的模型效果。
于是学习的问题就拆解为1. 什么是seq2seq模型2. 基于RNN的seq2seq模型如何处理文本/长文本序列3. seq2seq模型处理长文本序列时遇到了什么问题4.基于RNN的seq2seq模型如何结合attention来改善模型效果
## seq2seq框架
seq2seq是一种常见的NLP模型结构全称是sequence to sequence翻译为“序列到序列”。顾名思义从一个文本序列得到一个新的文本序列。典型的任务有机器翻译任务文本摘要任务。谷歌翻译在2016年末开始使用seq2seq模型并发表了2篇开创性的论文[Sutskever等2014年发表的Sequence to Sequence Learning
with Neural Networks](https://papers.nips.cc/paper/5346-sequence-to-sequence-learning-with-neural-networks.pdf)和[Cho等2014年发表的Learning Phrase Representations using RNN EncoderDecoder
for Statistical Machine Translation](http://emnlp2014.org/papers/pdf/EMNLP2014179.pdf)都对这些模型进行了解释。
for Statistical Machine Translation](http://emnlp2014.org/papers/pdf/EMNLP2014179.pdf),感兴趣的读者可以阅读原文进行学习
然而大家可以发现,想要充分理解模型并实现它,需要拆解一系列概念,而这些概念是层层递进的。如果能够把这些概念进行可视化,会更加容易理解。这就是这篇文章的目标。读者需要先了解一些深度学习的知识,才能读完这篇文章。笔者希望这篇文章,可以帮助读者阅读上面提到的 2 篇论文并且深入理解Attention。
无论读者是否读过上述两篇谷歌的文章NLP初学者想要充分理解并实现seq2seq模型很不容易。因为我们需要拆解一系列相关的NLP概念而这些NLP概念又是是层层递进的所以想要清晰的对seq2seq模型有一个清晰的认识并不容易。但是如果能够把这些复杂生涩的NLP概念可视化理解起来其实就更简单了。因此本文希望通过一系列图片、动态图帮助NLP初学者学习seq2seq以及attention相关的概念和知识
一个序列到序列seq2seq模型接收的输入是一个单词、字母、图像特征序列输出是另外一个序列。一个训练好的模型如下图所示将鼠标放在图上图就会动起来
首先看seq2seq干了什么事情seq2seq模型的输入可以是一个单词、字母或者图像特征序列输出是另外一个单词、字母或者图像特征序列。一个训练好的seq2seq模型如下图所示注释将鼠标放在图上,图就会动起来):
![seq2seq](./pictures/1-seq2seq.gif)动态图seq2seq
在神经机器翻译中,一个序列是指一连串的单词。类似地,输出也是一连串单词。
如下图所示以NLP中的机器翻译任务为例序列指的是一连串的单词,输出也是一连串单词。
![translation](./pictures/1-2-translation.gif)动态图translation
## 进一步理解细节
seq2seq模型是由编码器Encoder和解码器Decoder组成的。其中编码器会处理输入序列中的每个元素把这些信息转换为一个向量称为上下文context。当我们处理完整个输入序列后编码器把上下文context发送给解码器解码器开始逐项生成输出序列中的元素
## seq2seq细节
将上图中蓝色的seq2seq模型进行拆解如下图所示seq2seq模型由编码器Encoder和解码器Decoder组成。绿色的编码器会处理输入序列中的每个元素并获得输入信息这些信息会被转换成为一个黄色的向量称为context向量。当我们处理完整个输入序列后编码器把 context向量 发送给紫色的解码器解码器通过context向量中的信息逐个元素输出新的序列
![encoder-decode](./pictures/1-3-encoder-decoder.gif)动态图encoder-decoder
![encoder-decode](./pictures/1-3-encoder-decoder.gif)动态图:seq2seq中的encoder-decoder
![encoder-decoder](./pictures/1-3-mt.gif)动态图encoder-decoder
由于seq2seq模型可以用来解决机器翻译任务因此机器翻译被任务seq2seq模型解决过程如下图所示当作seq2seq模型的一个具体例子来学习。
这种机制,同样适用于机器翻译。
![encoder-decoder](./pictures/1-3-mt.gif)动态图seq2seq中的encoder-decoder机器翻译的例子
在机器翻译任务中上下文context是一个向量基本上是一个数字数组)。编码器和解码器在Transformer出现之前一般采用的是循环神经网络。关于循环神经网络建议阅读 [Luis Serrano写的一篇关于循环神经网络](https://www.youtube.com/watch?v=UNmqTiOnRfg)的精彩介绍.
深入学习机器翻译任务中的seq2seq模型如下图所示。seq2seq模型中的编码器和解码器一般采用的是循环神经网络RNNTransformer模型还没出现的过去时代。编码器将输入的法语单词序列编码成context向量在绿色encoder和紫色decoder中间出现然后解码器根据context向量解码出英语单词序列。*关于循环神经网络,本文建议阅读 [Luis Serrano写的循环神经网络精彩介绍](https://www.youtube.com/watch?v=UNmqTiOnRfg).*
![上下文context对应图里中间一个浮点数向量。在下文中我们会可视化这些向量使用更明亮的色彩来表示更高的值如上图右边所示](./pictures/1-4-context-example.png)
![context向量对应图里中间一个浮点数向量。在下文中,我们会可视化这些向量,使用更明亮的色彩来表示更高的值,如上图右边所示](./pictures/1-4-context-example.png)
图:上下文context对应图中间一个浮点数向量。在下文中,我们会可视化这些向量,使用更明亮的色彩来表示更高的值,如上图右边所示
context向量对应图中间浮点数向量。在下文中,我们会可视化这些数字向量,使用更明亮的色彩来表示更高的值,如上图右边所示
你可以在编写seq2seq模型的时候设置上下文向量的长度。这个长度是基于编码器 RNN 的隐藏层神经元的数量。上图展示了长度为 4 的向量,但在实际应用中,上下文向量的长度可能是 256512 或者 1024。
如上图所示我们来看一下黄色的context向量是什么本质上是一组浮点数。而这个context的数组长度是基于编码器RNN的隐藏层神经元数量的。上图展示了长度为4的context向量但在实际应用中context向量的长度是自定义的比如可能是256512或者1024。
根据设计RNN 在每个时间步接受 2 个输入:
- 输入序列中的一个元素(在解码器的例子中,输入是指句子中的一个单词,最终被转化成一个向量)
- 一个 hidden state隐藏层状态也对应一个向量
那么RNN是如何具体地处理输入序列的呢
如何把每个单词都转化为一个向量呢?我们使用一类称为 "word embedding" 的方法。这类方法把单词转换到一个向量空间这种表示能够捕捉大量单词之间的语义信息例如king - man + woman = queen[例子来源](http://p.migdal.pl/2017/01/06/king-man-woman-queen-why.html))。
1. 假设序列输入是一个句子,这个句子可以由$n$个词表示:$sentence = \{w_1, w_2,...,w_n\}$。
2. RNN首先将句子中的每一个词映射成为一个向量得到一个向量序列$X = \{x_1, x_2,...,x_n\}$每个单词映射得到的向量通常又叫做word embedding。
3. 然后在处理第$t \in [1,n]$个时间步的序列输入$x_t$时RNN网络的输入和输出可以表示为$h_{t} = RNN(x_t, h_{t-1})$
![我们在处理单词之前,需要把他们转换为向量。这个转换是使用 word embedding 算法来完成的。我们可以使用预训练好的 embeddings或者在我们的数据集上训练自己的 embedding。通常 embedding 向量大小是 200 或者 300为了简单起见我们这里展示的向量长度是4](./pictures/1-5-word-vector.png) 图:我们在处理单词之前,需要把他们转换为向量。这个转换是使用 word embedding 算法来完成的。我们可以使用预训练好的 embeddings或者在我们的数据集上训练自己的 embedding。通常 embedding 向量大小是 200 或者 300为了简单起见我们这里展示的向量长度是4。上图左边每个单词对应中间一个4维的向量。
- 输入RNN在时间步$t$的输入之一为单词$w_t$经过映射得到的向量$x_t$。
- 输入RNN另一个输入为上一个时间步$t-1$得到的hidden state向量$h_{t-1}$,同样是一个向量。
- 输出RNN在时间步$t$的输出为$h_t$ hidden state向量。
介绍完了单词向量/张量的基础知识,让我们回顾一下 RNN 的机制,并可视化这些 RNN 模型:
![rnn](./pictures/1-6-rnn.gif) 动态图RNN 在第 2 个时间步,采用第 1 个时间步的 hidden state隐藏层状态 和第 2 个时间步的输入向量,来得到输出。在下文,我们会使用类似这种动画,来描述神经机器翻译模型里的所有向量。
在下面的可视化图形中,编码器和解码器在每个时间步处理输入,并得到输出。由于编码器和解码器都是 RNNRNN 会根据当前时间步的输入,和前一个时间步的 hidden state隐藏层状态更新当前时间步的 hidden state隐藏层状态
让我们看下编码器的 hidden state隐藏层状态。注意最后一个 hidden state隐藏层状态实际上是我们传给解码器的上下文context
![](./pictures/1-6-seq2seq.gif) 动态图:编码器相关
解码器也持有 hidden state隐藏层状态而且也需要把 hidden state隐藏层状态从一个时间步传递到下一个时间步。我们没有在上图中可视化解码器的 hidden state是因为这个过程和解码器是类似的我们现在关注的是 RNN 的主要处理过程。
现在让我们用另一种方式来可视化序列到序列seq2seq模型。下面的动画会让我们更加容易理解模型。这种方法称为展开视图。其中我们不只是显示一个解码器而是在时间上展开每个时间步都显示一个解码器。通过这种方式我们可以看到每个时间步的输入和输出。
![](./pictures/1-6-seq2seq-decoder.gif) 动态图:解码器相关
## Attention 讲解
事实证明上下文context向量是这类模型的瓶颈。这使得模型在处理长文本时面临非常大的挑战。
在 Bahdanau等2014发布的[Neural Machine Translation by Jointly Learning to Align and Translate](https://arxiv.org/abs/1409.0473) 和 Luong等2015年发布的[Effective Approaches to Attention-based Neural Machine Translation
](https://arxiv.org/abs/1508.04025)两篇论文中,提出了一种解决方法。这 2 篇论文提出并改进了一种叫做注意力**attetion**的技术,它极大地提高了机器翻译的质量。注意力使得模型可以根据需要,关注到输入序列的相关部分。
![在第7个时间步注意力机制使得解码器在产生英语翻译之前可以将注意力集中在 "student" 这个词(在法语里,是 "student" 的意思)。这种从输入序列放大相关信号的能力,使得注意力模型,比没有注意力的模型,产生更好的结果。](./pictures/1-7-attetion.png) 图:在第 7 个时间步,注意力机制使得解码器在产生英语翻译之前,可以将注意力集中在 "student" 这个词(在法语里,是 "student" 的意思)。这种从输入序列放大相关信号的能力,使得注意力模型,比没有注意力的模型,产生更好的结果。
让我们继续从高层次来理解注意力模型。一个注意力模型不同于经典的序列到序列seq2seq模型主要体现在 2 个方面:
![我们在处理单词之前,需要把他们转换为向量。这个转换是使用 word embedding 算法来完成的。我们可以使用预训练好的 embeddings或者在我们的数据集上训练自己的 embedding。通常 embedding 向量大小是 200 或者 300为了简单起见我们这里展示的向量长度是4](./pictures/1-5-word-vector.png) 图word embedding例子。我们在处理单词之前需要将单词映射成为向量通常使用 word embedding 算法来完成。一般来说,我们可以使用提前训练好的 word embeddings或者在自有的数据集上训练word embedding。为了简单起见上图展示的word embedding维度是4。上图左边每个单词经过word embedding算法之后得到中间一个对应的4维的向量。
首先,编码器会把更多的数据传递给解码器。编码器把所有时间步的 hidden state隐藏层状态传递给解码器而不是只传递最后一个 hidden state隐藏层状态:
让我们来进一步可视化一下基于RNN的seq2seq模型中的编码器在第1个时间步是如何工作
![rnn](./pictures/1-6-rnn.gif) 动态图如图所示RNN在第2个时间步采用第1个时间步得到hidden state#10隐藏层状态和第2个时间步的输入向量input#1来得到新的输出hidden state#1。
看下面的动态图让我们详细观察一下编码器如何在每个时间步得到hidden sate并将最终的hidden state传输给解码器解码器根据编码器所给予的最后一个hidden state信息解码处输出序列。注意最后一个 hidden state实际上是我们上文提到的context向量。
![](./pictures/1-6-seq2seq.gif) 动态图编码器逐步得到hidden state并传输最后一个hidden state给解码器。
接着结合编码器处理输入序列一起来看下解码器如何一步步得到输出序列的l。与编码器类似解码器在每个时间步也会得到 hidden state隐藏层状态而且也需要把 hidden state隐藏层状态从一个时间步传递到下一个时间步。
![](./pictures/1-6-seq2seq-decoder.gif) 动态图编码器首先按照时间步依次编码每个法语单词最终将最后一个hidden state也就是context向量传递给解码器解码器根据context向量逐步解码得到英文输出。
目前为止希望你已经明白了本文开头提出的前两个问题1. 什么是seq2seq模型2. seq2seq模型如何处理文本/长文本序列那么请思考第3、4个问题3. seq2seq模型处理文本序列特别是长文本序列时会遇到什么问题4.基于RNN的seq2seq模型如何结合attention来解决问题3并提升模型效果
## Attention
基于RNN的seq2seq模型编码器所有信息都编码到了一个context向量中便是这类模型的瓶颈。一方面单个向量很难包含所有文本序列的信息另一方面RNN递归地编码文本序列使得模型在处理长文本时面临非常大的挑战比如RNN处理到第500个单词的时候很难再包含1-499个单词中的所有信息了
面对以上问题Bahdanau等2014发布的[Neural Machine Translation by Jointly Learning to Align and Translate](https://arxiv.org/abs/1409.0473) 和 Luong等2015年发布的[Effective Approaches to Attention-based Neural Machine Translation
](https://arxiv.org/abs/1508.04025)两篇论文中,提出了一种叫做注意力**attetion**的技术。通过attention技术seq2seq模型极大地提高了机器翻译的质量。归其原因是attention注意力机制使得seq2seq模型可以有区分度、有重点地关注输入序列。
下图依旧是机器翻译的例子:
![在第7个时间步注意力机制使得解码器在产生英语翻译之前可以将注意力集中在 "student" 这个词(在法语里,是 "student" 的意思)。这种从输入序列放大相关信号的能力,使得注意力模型,比没有注意力的模型,产生更好的结果。](./pictures/1-7-attetion.png) 图:在第 7 个时间步注意力机制使得解码器在产生英语翻译student英文翻译之前可以将注意力集中在法语输入序列的étudiant。这种有区分度得attention到输入序列的重要信息使得模型有更好的效果。
让我们继续来理解带有注意力的seq2seq模型一个注意力模型与经典的seq2seq模型主要有2点不同
- A. 首先,编码器会把更多的数据传递给解码器。编码器把所有时间步的 hidden state隐藏层状态传递给解码器而不是只传递最后一个 hidden state隐藏层状态如下面的动态图所示:
![](./pictures/1-6-mt-1.gif) 动态图: 更多的信息传递给decoder
第二,注意力模型的解码器在产生输出之前,做了一个额外的处理。为了把注意力集中在与该时间步相关的输入部分。解码器做了如下的处理:
- B. 注意力模型的解码器在产生输出之前做了一个额外的attention处理。如下图所示具体为
1. 查看所有接收到的编码器的 hidden state隐藏层状态。其中编码器中每个 hidden state隐藏层状态都对应到输入句子中一个单词。
2. 给每个 hidden state隐藏层状态一个分数我们先忽略这个分数的计算过程
3. 将每个 hidden state隐藏层状态乘以经过 softmax 的对应的分数,从而,高分对应的 hidden state隐藏层状态会被放大而低分对应的 hidden state隐藏层状态会被缩小。
- 1. 由于编码器中每个 hidden state隐藏层状态都对应到输入句子中一个单词那么解码器要查看所有接收到的编码器的 hidden state隐藏层状态
- 2. 给每个 hidden state隐藏层状态计算出一个分数我们先忽略这个分数的计算过程
- 3. 所有hidden state隐藏层状态的分数经过softmax进行归一化。
- 4. 将每个 hidden state隐藏层状态乘以所对应的分数从而能够让高分对应的 hidden state隐藏层状态会被放大而低分对应的 hidden state隐藏层状态会被缩小。
- 5. 将所有hidden state根据对应分数进行加权求和得到对应时间步的context向量。
![](./pictures/1-7-attention-dec.gif) 动态图在第4个时间步编码器结合attention得到context向量的5个步骤。
![](./pictures/1-7-attention-dec.gif) 动态图解决码器attention
所以attention可以简单理解为一种有效的加权求和技术其艺术在于如何获得权重。
这个加权平均的步骤是在解码器的每个时间步做的。
现在,让我们把所有内容都融合到下面的图中,来看看注意力模型的整个过程:
现在让我们把所有内容都融合到下面的图中来看看结合注意力的seq2seq模型解码器全流程动态图展示的是第4个时间步
1. 注意力模型的解码器 RNN 的输入包括一个embedding 向量,和一个初始化好的解码器 hidden state隐藏层状态
2. RNN 处理上述的 2 个输入,产生一个输出和一个新的 hidden state隐藏层状态 h4 向量),其中输出会被忽略。
3. 注意力的步骤:我们使用编码器的 hidden state隐藏层状态和 h4 向量来计算这个时间步的上下文向量C4
4. 我们把 h4 和 C4 拼接起来,得到一个向量。
5. 我们把这个向量输入一个前馈神经网络(这个网络是和整个模型一起训练的)。
6. 前馈神经网络的输出表示这个时间步输出的单词。
1. 注意力模型的解码器 RNN 的输入包括:一个word embedding 向量,和一个初始化好的解码器 hidden state,图中是$h_{init}$
2. RNN 处理上述的 2 个输入,产生一个输出和一个新的 hidden state图中为h4
3. 注意力的步骤:我们使用编码器的所有 hidden state向量和 h4 向量来计算这个时间步的context向量C4
4. 我们把 h4 和 C4 拼接起来,得到一个橙色向量。
5. 我们把这个橙色向量输入一个前馈神经网络(这个网络是和整个模型一起训练的)。
6. 根据前馈神经网络的输出向量得到输出单词假设输出序列可能的单词有N个那么这个前馈神经网络的输出向量通常是N维的每个维度的下标对应一个输出单词每个维度的数值对应的是该单词的输出概率
7. 在下一个时间步重复1-6步骤。
![](./pictures/1-7-attention-pro.gif) 动态图attention过程
![](./pictures/1-7-attention-pro.gif) 动态图:解码器结合attention过程
下图,我们使用另一种方式来可视化注意力,看看在每个解码的时间步中关注输入句子的哪些部分:
![](./pictures/1-7-attention.gif) 动态图attention关注的词
到目前为止希望你已经知道本文开头提出的3、4问题的答案啦3、seq2seq处理长文本序列的挑战是什么4、seq2seq是如何结合attention来解决问题3中的挑战的
请注意,注意力模型不是无意识地把输出的第一个单词对应到输入的第一个单词。实际上,它从训练阶段学习到了如何在两种语言中对应单词的关系(在我们的例子中,是法语和英语)。下图展示了注意力机制的准确程度(图片来自于上面提到的论文):
![你可以看到模型在输出 "European Economic Area" 时,注意力分布情况。在法语中,这些单词的顺序,相对于英语,是颠倒的("européenne économique zone")。而其他词的顺序是类似的。](./pictures/1-8-attention-vis.png)
最后,我们可视化一下注意力机制,看看在解码器在每个时间步关注了输入序列的哪些部分
![](./pictures/1-7-attention.gif) 动态图解码步骤时候attention关注的词
如果你觉得你准备好了学习注意力机制的代码实现,一定要看看基于 TensorFlow 的 神经机器翻译 (seq2seq) [指南](https://github.com/tensorflow/nmt)。
需要注意的是:注意力模型不是无意识地把输出的第一个单词对应到输入的第一个单词,它是在训练阶段学习到如何对两种语言的单词进行对应(在我们的例子中,是法语和英语)。
下图还展示了注意力机制的准确程度(图片来自于上面提到的论文):
![你可以看到模型在输出 "European Economic Area" 时,注意力分布情况。在法语中,这些单词的顺序,相对于英语,是颠倒的("européenne économique zone")。而其他词的顺序是类似的。](./pictures/1-8-attention-vis.png) 图:可以看到模型在输出 "European Economic Area" 时,注意力分布情况。在法语中,这些单词的顺序,相对于英语,是颠倒的("européenne économique zone")。而其他词的顺序是类似的。
读懂了attention和seq2seq模型就去github点个**star**打卡一下吧~~
## 致谢
主要由哈尔滨工业大学张贤同学翻译(经原作者 [@JayAlammmar](https://twitter.com/JayAlammar) 授权撰写由本项目同学组织和整理。最后期待您的阅读反馈和star哦谢谢。
主要由哈尔滨工业大学张贤同学翻译(经原作者 [@JayAlammmar](https://twitter.com/JayAlammar) 授权)撰写,由多多同学、datawhlae学习者重新组织和整理。最后期待您的阅读反馈和star哦。