本内容主要介绍 Transformer 模型的具体实现。
2017 年,Google 在论文 Attention is All you need 中提出了 Transformer 模型,其使用 Self-Attention 结构取代了在 NLP 任务中常用的 RNN 网络结构。相比 RNN 网络结构,其最大的优点是可以并行计算。Transformer 的整体模型架构如图 1.1 所示:
1.1 Transformer 概览
首先,让我们先将 Transformer 模型视为一个黑盒,如图 1.2 所示。在机器翻译任务中,将一种语言的一个句子作为输入,然后将其翻译成另一种语言的一个句子作为输出。
Transformer 本质上是一个 Encoder-Decoder 架构。因此中间部分的 Transformer 可以分为两个部分:编码组件和解码组件。如图 1.3 所示:
其中,编码组件由多层编码器(Encoder)组成(在论文中作者使用了 6 层编码器,在实际使用过程中你可以尝试其他层数)。解码组件也是由相同层数的解码器(Decoder)组成(在论文也使用了 6 层)。如图 1.4 所示:
每个编码器由两个子层组成:Self-Attention 层(自注意力层)和 Position-wise Feed Forward Network(前馈网络,缩写为 FFN)如图 1.5 所示。每个编码器的结构都是相同的,但是它们使用不同的权重参数。
编码器的输入会先流入 Self-Attention 层。它可以让编码器在对特定词进行编码时使用输入句子中的其他词的信息(可以理解为:当我们翻译一个词时,不仅只关注当前的词,而且还会关注其他词的信息)。后面我们将会详细介绍 Self-Attention 的内部结构。然后,Self-Attention 层的输出会流入前馈网络。
解码器也有编码器中这两层,但是它们之间还有一个注意力层(即 Encoder-Decoder Attention),其用来帮忙解码器关注输入句子的相关部分(类似于 seq2seq 模型中的注意力)。
1.2 引入张量
现在我们已经了解了模型的主要组成部分,让我们开始研究各种向量/张量,以及他们在这些组成部分之间是如何流动的,从而将输入经过已训练的模型转换为输出。
和通常的 NLP 任务一样,首先,我们使用词嵌入算法(Embedding)将每个词转换为一个词向量。在 Transformer 论文中,词嵌入向量的维度是 512。
嵌入仅发生在最底层的编码器中。所有编码器都会接收到一个大小为 512 的向量列表——底部编码器接收的是词嵌入向量,其他编码器接收的是上一个编码器的输出。这个列表大小是我们可以设置的超参数——基本上这个参数就是训练数据集中最长句子的长度。
对输入序列完成嵌入操作后,每个词都会流经编码器的两层。
接下来,我们将换一个更短的句子作为示例,来说明在编码器的每个子层中发生了什么。
上面我们提到,编码器会接收一个向量作为输入。编码器首先将这些向量传递到 Self-Attention 层,然后传递到前馈网络,最后将输出传递到下一个编码器。
1.3 Self-Attention(自注意力)
1.3.1 Self-Attention 概览
首先我们通过一个例子,来对 Self-Attention 有一个直观的认识。假如,我们要翻译下面这个句子:
The animal didn’t cross the street because it was too tired
这个句子中的 it
指的是什么?是指 animal
还是 street
?对人来说,这是一个简单的问题,但是算法来说却不那么简单。
当模型在处理 it
时,Self-Attention 机制使其能够将 it
和 animal
关联起来。
当模型处理每个词(输入序列中的每个位置)时,Self-Attention 机制使得模型不仅能够关注当前位置的词,而且能够关注句子中其他位置的词,从而可以更好地编码这个词。
如果你熟悉 RNN,想想如何维护隐状态,使 RNN 将已处理的先前词/向量的表示与当前正在处理的词/向量进行合并。Transformer 使用 Self-Attention 机制将其他词的理解融入到当前词中。
1.3.2 Self-Attention 机制
下面我们来看一下 Self-Attention 的具体机制。其基本结构如图 1.11 所示: