Transformer最早是在论文《Attention is All You Need》中提出的,目前已广泛应用于NLP领域,如语言翻译、文本分类、问答系统等。由于在产品规划中需要使用这样的模型结构,因此花了一些时间对其进行了一些学习理解。
除了阅读论文及配套的代码之外,还参考了Jay Alammar的技术讲解博客The Illustrated Transformer。这篇博客非常推荐Transformer的初学者,像我这样的语言模型菜鸟读起来都没什么压力。
1. Transformer模型结构
在讲Self-Attention之前,我们先来看看Transformer的结构。论文中给出的Transformer结构如下:
不同数量的Encoder和Decoder的堆叠,就可以组成不同的Transformer结构,例如在翻译模型中,可以使用6个Encoder和6个Decoder来组成整个模型:
那么,接下来我们看看每个Encoder和Decoder内部的结构。简单来理解,每个Encoder内部包含两大部分:Self-Attention和Feed-Forward;而Decoder内部结构则略复杂一点,比起Decoder,还多了一层Encoder-Decoder Attention。
2. 数据流
我们关注的第二个议题是,作为文字的输入数据是如何在模型中处理的?答案就是:需要将文字转换为数字,也就是Word Embedding。这是因为机器学习算法通常要求输入为数值向量,网络并不擅长处理字符串。将词汇或短语从文字映射成实数向量,除了易于神经网络处理,另外还有两个重要而有力的特性:(1) 降维, (2) 上下文相似性,这两方面都使得语言能够被更有效地表示。
Word Embedding只在最下面一层的Encoder进行,其他Encoder接收上一个Encoder输出的向量。向量大小为512。对一整个句子中的词语完成Embedding之后,这些vector将会经过每个encoder的Self-attention层和Feed-forward层。
从上图中我们可以看到,每一个位置的词向量按照自己的路径经过Encoder,在Self-attention模块,这些词向量会有交互,在Feed-forward模块,每个词向量是独立传播的,这也有利于它们的并行执行。
3. Self-Attention的实现
论文中对Self-attention的描述为Scaled Dot-Product Attention,并给出了实现公式:
输入为dk维的Queries和Keys,以及dv维的Values,图形化表示如下:
有点抽象对吧?那我们就跟随文章开头提到的那篇博客的脚步,来解释这个结构。
Self-attention的目的是要寻找输入向量(可以理解为输入语句)内部的关联,例如要翻译下面这句话:
“The animal didn't cross the street because it was too tired
”
那么,句子中的it指代什么呢?是指the animal,还是指the street?对于机器学习来说,这就是个问题。那么通过学习句子中不同单词的关联性,就可以知道it指代的是the animal。
3.1 Self-attention的分步理解
对Self-attention的理解可以分为几个步骤:
(1) 首先,我们需要创建三个vector,分别是Query vector、Key vector和Value vector,这几个vectors的获取是通过输入的embedding和三个矩阵WQ、WK和WV相乘,这三个矩阵是网络在训练中学习到的。论文中设计的三个输出vector维度为64。
(2) 接下来,我们要使用计算出来的三个vectors进行打分计算,具体做法是:对每一个单词位置,计算该位置的Query vector和每一个位置的Key vector的点积,以下图为例,第一个单词在整个输入序列(本例中只有两个单词)中对应位置的分数计算分别为:q1·k1,q1·k2;同样的,如果计算第二个单词在整个输入序列对应位置的分数,则应该是:q2·k1,q2·k2。
(3) (4) 我们把第三步和第四步合并,首先,上面的score计算结果要除以8(见上面Attention公式,dk为64,其平方根为8),接下来进行softmax操作,将分数归一化到0~1之间,并使其和为1:
进行以上操作之后,我们就可以看到,每个单词在每个位置上的关注度。在此例中,“Thinking”这个单词在自身位置的关注度最大。当然也会有些句子,当前位置的单词对其他位置的单词关注度比较大,比如我们前面例子中的“it”和“the animal”。
(5) 前面步骤我们已经算出了每个单词处理时,在不同位置上的关注度,相当于权重,那么接下来我们需要将该权重作用在Value vector上,可以理解为对关注位置的单词进行保持,而抑制非相关位置上单词的权重。
(6) 第六步是对第(5)步的加权向量进行求和。该步会产生Self-attention在当前单词位置的输出。
3.2 Self-attention的矩阵实现
上面我们分步骤理解了Self-attention的原理和实现,但在实际应用中,为了快速执行,是通过矩阵的形式来进行的。那么矩阵如何实现呢?
首先,计算Query、Key和Value几个矩阵(在前面讲的分步理解中,是Query vector、Key vector和Value vector),矩阵的计算通过将输入embedding vectors打包成一个Matrix X(相当于把前面的X1、x2...堆叠在一起),再跟训练出来的权重矩阵(WQ、WK和WV)做矩阵乘法。
接下来,通过矩阵运算把3.1中的六个步骤压缩到一步中处理,如下图所示:
以上就是Transformer中Self-Attention的完整解读了。网络结构中还有Multi-Head Attention等结构,为了篇幅简洁,我们放在下一篇中来解读。