教程是来自https://github.com/datawhalechina/learn-nlp-with-transformers/blob/main/docs/
图解Attention
Attention出现的原因是:基于循环神经网络(RNN)一类的seq2seq模型,在处理长文本时遇到了挑战,而对长文本中不同位置的信息进行attention有助于提升RNN的模型效果。
seq2seq框架
seq2seq(sequence to sequence)是一种常见的NLP模型结构,也就是从一个文本序列得到一个新的文本序列,其典型的任务是机器翻译任务、文本摘要任务。
seq2seq模型的输入可以是一个单词、字母或者图像特征序列,输出是另外一个单词、字母或图像特征序列,以机器翻译任务为例,序列指的是一连串的单词。
seq2seq模型由编码器(Encoder)和解码器(Decoder)组成,绿色的编码器会处理输入序列中的每个元素并获得输入信息,这些信息会被转换成为一个黄色的向量(称为context向量),当我们处理完整个输入序列后,编码器把context向量发送给紫色的解码器,解码器通过context向量中的信息,逐个元素输出新的序列。
以机器翻译任务为例,seq2seq在Transformer还没出现的时候,编码器和解码器一般采用的是循环神经网络RNN,编码器将输入的法语单词序列编码成context向量,然后解码器根据context向量解码出英语单词序列。
context向量本质是一组浮点数,而context的数组长度是基于编码器RNN的隐藏层神经元数量,上图是长度为4的context向量,但在实际应用中,context向量的长度是自定义的,比如可能是256,512或1024。
RNN具体处理输入序列的过程如下:
- 假设输入是一个句子,这个句子可以由 n n n个词表示: s e n t e n c e = w 1 , w 2 , . . . , w n sentence={w_1,w_2,...,w_n} sentence=w1,w2,...,wn。
- RNN首先将句子中的每一个词映射成为一个向量,得到一个向量序列: X = x 1 , x 2 , . . . , x n X={x_1,x_2,...,x_n} X=x1,x2,...,xn,每个单词映射得到的向量通常又叫做
word embedding
。 - 然后在处理第 t ∈ [ 1 , n ] t\in [1,n] t∈[1,n]个时间步的序列输入 x t x_t xt时,RNN网络的输入和输出可以表示为: h t = R N N ( x t , h t − 1 ) h_t=RNN(x_t,h_{t-1}) ht=RNN(xt,ht−1)
- 输入:RNN在时间步 t t t的输入之一为单词 w t w_t wt经过映射得到的向量 x t x_t xt,另一个输入是上一个时间步 t − 1 t-1 t−1得到的
hidden state
向量 h t − 1 h_{t-1} ht−1,同样是一个向量。 - 输出:RNN在时间步 t t t的输出为 h t h_t ht
hidden state
向量。
下图是word embedding的例子,为了简单起见,每个单词被映射成一个长度为4的向量。
看上面的动态图,相当于第一步 t 1 t_1 t1先把一个单词输入(转化为嵌入向量 x 1 x_1 x1),得到其对应的hidden state #1
,然后根据hidden state #1
和 x 2 x_2 x2得到hidden state #2
,以此类推,最终编码器输出的是最后一个hidden state
,将其作为输入传给解码器,和编码器相同,解码器也是在每个时间步得到隐藏层状态,并传递到下一个时间步,一步步输出得到序列。
Attention
基于RNN的seq2seq模型编码器所有信息都编码到了一个context向量中,单个向量很难包含所有文本序列的信息,在处理长文本的时候,有长程依赖问题,因此Attention(注意力)机制被提出,这使得seq2seq模型可以有区分度、有重点的关注输入序列。
带有注意力的seq2seq模型结构有两点不同:
- A. 编码器会把更多的数据传递给解码器。编码器把所有时间步的
hidden state
传递给解码器,而不是只传递最后一个hidden state
,如图
- B. 注意力模型的解码器在输出之前,做了一个额外的attention处理。具体为:
- a. 由于编码器中每个
hidden state
都对应到输入句子中的一个单词,那么解码器要查看所有接收到的编码器的hidden state
。 - b. 给每个
hidden state
计算出一个分数。 - c. 所有
hidden state
的分数经过softmax归一化。 - d. 将每个
hidden state
乘以所对应的分数,从而能够让高分对应的hidden state
会被放大,而低分对应的hidden state
会被缩小。 - e. 将所有
hidden state
根据对应分数进行加权求和,得到对应时间步的context
向量。(下图的前三个时间步是编码器编码过程,第四个时间步是解码器开始解码)
以第四个时间步(解码器开始解码)为例:
- 注意力模型的解码器RNN的输入包括:一个
word embedding
向量,和一个初始化好的解码器hidden state
,图中是 h i n i t h_{init} hinit。 - RNN处理上述的两个输入,产生一个新的输出和一个新的
hidden state
(这里和之前一样),图中为 h 4 h_4 h4。 - 注意力机制的步骤:使用编码器的所有
hidden state
向量和h4
向量来计算这个时间步的context
向量(C4
). - 把
h4
和C4
拼接起来,得到一个橙色向量。 - 把橙色向量输入一个前馈神经网络(这个网络是和整个模型一起训练的)。
- 根据前馈神经网络的输出向量得到输出单词:假设输出序列可能的单词有N个,那么这个前馈神经网络的输出向量通常是N维的,每个维度的下标对应一个输出单词,每个维度的数值对应的是该单词的输出概率。(编码器是把词进行词嵌入,将词汇表中的词映射为嵌入向量,解码器的输出是词汇表上每个词的概率,比如通过softmax层将该时间步的隐藏状态转换为词汇表上的概率,然后argmax取出概率最高的作为输出的单词)
- 在下一个时间步重复1-6步骤。
上图是解码器结合attention的全过程,最后是一段注意力机制的可视化,看看解码器在每个时间步关注了输入序列的哪些部分:
注意力模型不是无意识的将输出的第一个单词对应到输入的第一个单词,是在训练阶段学习到如何对两种语言的单词进行对应,例子中是法语和英语。
由上图可以看出,模型在输出"European Economic Area"时,注意力分布情况,法语和英语单词的顺序是颠倒的,注意力分布反映出了这一点。