第 15 章 Transformer
Transformer 由论文《Attention is All You Need》提出,现在是深度学习中最重要的序列建模结构之一。论文相关的 TensorFlow 代码可以从 GitHub 获取,其作为 Tensor2Tensor 包的一部分。哈佛的 NLP 团队也实现了一个基于 PyTorch 的版本,并对论文进行了注释。
在本文中,我们将试图把模型简化一点,并逐一介绍里面的核心概念,希望让普通读者也能轻易理解。
论文:Attention Is All You Need
15.1 Transformer 整体结构
首先介绍 Transformer 的整体结构,下图是 Transformer 用于中英文翻译的整体结构:

Transformer 的整体结构,左图Encoder和右图Decoder
可以看到 Transformer 由 Encoder 和 Decoder 两个部分组成,Encoder 和 Decoder 都包含 6 个 block。Transformer 的工作流程大体如下:
第一步:获取输入句子的每一个单词的表示向量

Transformer 的输入表示
第二步:将得到的单词表示向量矩阵(如上图所示,每一行是一个单词的表示

Transformer Encoder 编码句子信息
第三步:将 Encoder 输出的编码信息矩阵

Transformer Decoder 预测
上图 Decoder 接收了 Encoder 的编码矩阵 <Begin>,预测第一个单词 "I";然后输入翻译开始符 <Begin> 和单词 "I",预测单词 "have",以此类推。这是 Transformer 使用时的大致流程,接下来是各个部分的细节。
15.2 Transformer 的输入
Transformer 中单词的输入表示

Transformer 的输入表示
15.2.1 单词 Embedding
单词的 Embedding 有很多种方式可以获取,例如可以采用 Word2Vec、GloVe 等算法预训练得到,也可以在 Transformer 中训练得到。
15.2.2 位置 Embedding
Transformer 中除了单词的 Embedding,还需要使用位置 Embedding 表示单词出现在句子中的位置。因为 Transformer 不采用 RNN 的结构,而是使用全局信息,不能利用单词的顺序信息,而这部分信息对于 NLP 来说非常重要。所以 Transformer 中使用位置 Embedding 保存单词在序列中的相对或绝对位置。
位置 Embedding 用

其中,
使 PE 能够适应比训练集里面所有句子更长的句子,假设训练集里面最长的句子是有 20 个单词,突然来了一个长度为 21 的句子,则使用公式计算的方法可以计算出第 21 位的 Embedding。
可以让模型容易地计算出相对位置,对于固定长度的间距 k,PE(pos+k) 可以用 PE(pos) 计算得到。因为 Sin(A+B) = Sin(A)Cos(B) + Cos(A)Sin(B), Cos(A+B) = Cos(A)Cos(B) - Sin(A)Sin(B)。
将单词的词 Embedding 和位置 Embedding 相加,就可以得到单词的表示向量
15.3 Self-Attention(自注意力机制)

Transformer Encoder 和 Decoder
上图是论文中 Transformer 的内部结构图,左侧为 Encoder block,右侧为 Decoder block。红色圈中的部分为 Multi-Head Attention,是由多个 Self-Attention 组成的。Encoder block 包含一个 Multi-Head Attention,而 Decoder block 包含两个 Multi-Head Attention(其中有一个用到 Masked)。Multi-Head Attention 上方还包括一个 Add & Norm 层,Add 表示残差连接(Residual Connection),Norm 表示 Layer Normalization,用于对每一层的激活值进行归一化。
因为 Self-Attention是 Transformer 的重点,所以我们重点关注 Multi-Head Attention 以及 Self-Attention,首先详细了解一下 Self-Attention 的内部逻辑。
15.3.1 Self-Attention 结构

Self-Attention 结构
上图是 Self-Attention 的结构,在计算的时候需要用到矩阵
15.3.2 Q, K, V 的计算
Self-Attention 的输入用矩阵
常用写法是:
其中

Q, K, V 的计算
15.3.3 Self-Attention 的输出
得到矩阵

Self-Attention 的输出
公式中计算矩阵

得到

对矩阵的每一行进行 Softmax
得到 Softmax 矩阵之后可以和

Self-Attention 输出
上图中 Softmax 矩阵的第 1 行表示单词 1 与其他所有单词的 attention 系数,最终单词 1 的输出

Zi 的计算方法
15.3.4 Multi-Head Attention
在上一步,我们已经知道怎么通过 Self-Attention 计算得到输出矩阵 Z,而 Multi-Head Attention 是由多个 Self-Attention 组合形成的,下图是论文中 Multi-Head Attention 的结构图。

Multi-Head Attention
从上图可以看到 Multi-Head Attention 包含多个 Self-Attention 层,首先将输入X分别传递到 h 个不同的 Self-Attention 中,计算得到 h 个输出矩阵Z。下图是 h=8 时候的情况,此时会得到 8 个输出矩阵Z。
其中

多个 Self-Attention
得到 8 个输出矩阵

Multi-Head Attention 的输出
可以看到 Multi-Head Attention 输出的矩阵
15.4 Encoder 结构

Transformer Encoder block
上图红色部分是 Transformer 的 Encoder block 结构,可以看到是由 Multi-Head Attention, Add & Norm, Feed Forward, Add & Norm 组成的。刚刚已经了解了 Multi-Head Attention 的计算过程,现在了解一下 Add & Norm 和 Feed Forward 部分。
15.4.1 Add & Norm
Add & Norm 层由 Add 和 Norm 两部分组成,其计算公式如下:

Add & Norm 公式
其中
Add 指

残差连接
Norm 指 Layer Normalization。Layer Normalization 会对每个样本在特征维度上进行归一化,使中间表示的尺度更稳定,从而有利于训练。
Layer Normalization 和 Batch Normalization 都是归一化方法,但统计维度不同。Batch Normalization 通常在一个 mini-batch 上统计均值和方差,因此受 batch size 影响,训练和推理阶段还要区分当前 batch 统计量和历史滑动统计量。Layer Normalization 对单个样本的特征维度做归一化,不依赖 batch 中其他样本,所以训练和推理行为更一致,也更适合 RNN 和 Transformer 这类序列模型。
15.4.2 Feed Forward
Feed Forward 层是一个两层的全连接层,第一层的激活函数为 ReLU,第二层不使用激活函数,对应的公式如下。

Feed Forward
15.4.3 组成 Encoder
通过上面描述的 Multi-Head Attention、Feed Forward、Add & Norm 就可以构造出一个 Encoder block。Encoder block 接收输入矩阵
第一个 Encoder block 的输入为句子单词的表示向量矩阵,后续 Encoder block 的输入是前一个 Encoder block 的输出,最后一个 Encoder block 输出的矩阵就是编码信息矩阵 C,这一矩阵后续会用到 Decoder 中。

Encoder 编码句子信息
15.5 Decoder 结构

Transformer Decoder block
上图红色部分为 Transformer 的 Decoder block 结构,与 Encoder block 相似,但是存在一些区别:
包含两个 Multi-Head Attention 层。
第一个 Multi-Head Attention 层采用了 Masked 操作。
第二个 Multi-Head Attention 层的
最后有一个 Softmax 层计算下一个翻译单词的概率。
15.5.1 第一个 Multi-Head Attention
Decoder block 的第一个 Multi-Head Attention 采用了 Masked 操作,因为在翻译的过程中是顺序翻译的,即翻译完第 i 个单词,才可以翻译第 i+1 个单词。通过 Masked 操作可以防止第 i 个单词知道 i+1 个单词之后的信息。下面以 "我有一只猫" 翻译成 "I have a cat" 为例,了解一下 Masked 操作。
下面的描述中使用了类似 Teacher Forcing 的概念。在 Decoder 的时候,需要根据之前的翻译,求解当前最有可能的翻译,如下图所示。首先根据输入 <Begin> 预测出第一个单词为 "I",然后根据输入 <Begin> I 预测下一个单词 "have"。

Decoder 预测
Decoder 可以在训练的过程中使用 Teacher Forcing 并且并行化训练,即将正确的单词序列 (<Begin> I have a cat) 和对应输出 (I have a cat <end>) 传递到 Decoder。那么在预测第 i 个输出时,就要将第 i+1 之后的单词掩盖住,注意 Mask 操作是在 Self-Attention 的 Softmax 之前使用的,下面用 0 1 2 3 4 5 分别表示 <Begin> I have a cat <end>。
第一步:是 Decoder 的输入矩阵和 Mask 矩阵,输入矩阵包含 <Begin> I have a cat (0, 1, 2, 3, 4) 五个单词的表示向量,Mask 是一个 5×5 的矩阵。在 Mask 可以发现单词 0 只能使用单词 0 的信息,而单词 1 可以使用单词 0, 1 的信息,即只能使用之前的信息。

输入矩阵与 Mask 矩阵
第二步:接下来的操作和之前的 Self-Attention 一样,通过输入矩阵

第三步:在得到

Softmax 之前 Mask
得到带 Mask 的 attention score 之后再进行 Softmax,每一行的和都为 1。但是单词 0 在单词 1、2、3、4 上的 attention score 都为 0。
第四步:使用 Mask 后的 attention 矩阵与矩阵

Mask 之后的输出
第五步:通过上述步骤就可以得到一个 Masked Self-Attention 的输出矩阵,然后和 Encoder 类似,通过 Multi-Head Attention 拼接多个输出,再计算得到第一个 Multi-Head Attention 的输出
15.5.2 第二个 Multi-Head Attention
Decoder block 第二个 Multi-Head Attention 变化不大,主要区别在于其中 Self-Attention 的
根据 Encoder 的输出
这样做的好处是在 Decoder 的时候,每一位单词都可以利用到 Encoder 所有单词的信息 (这些信息无需 Mask)。
15.5.3 Softmax 预测输出单词
Decoder block 最后的部分是利用 Softmax 预测下一个单词。在之前的网络层可以得到一个最终的输出

Decoder Softmax 之前的 Z
Softmax 根据输出矩阵的每一行预测下一个单词:

Decoder Softmax 预测
这就是 Decoder block 的定义,与 Encoder 一样,Decoder 是由多个 Decoder block 组合而成。
15.6 Transformer 总结
Transformer 与 RNN 不同,可以比较好地并行训练。
Transformer 本身是不能利用单词的顺序信息的,因此需要在输入中添加位置 Embedding,否则 Transformer 就是一个词袋模型了。
Transformer 的重点是 Self-Attention 结构,其中用到的
Transformer 中的 Multi-Head Attention 包含多个 Self-Attention,可以从不同子空间捕获词与词之间的相关关系。
15.7 长序列 Transformer
标准 Self-Attention 会计算序列中任意两个位置之间的相关性。若序列长度为
这种全局两两计算让 Transformer 能直接建模长距离依赖,但当序列很长时会成为主要瓶颈。例如长文档、长代码、长时间序列和高分辨率视觉 token 都会让注意力矩阵迅速变大。
改进长序列 Transformer 的思路大致包括:
| 思路 | 代表做法 | 核心想法 |
|---|---|---|
| 稀疏注意力 | Longformer、BigBird | 只计算局部或部分全局注意力 |
| 低秩近似 | Linformer | 用低秩结构近似注意力矩阵 |
| 核方法近似 | Performer | 用核函数近似 Softmax Attention |
| 哈希分桶 | Reformer | 让相似 token 落到同一桶内再计算注意力 |
Reformer 使用局部敏感哈希(Locality-Sensitive Hashing, LSH)注意力。LSH 的目标是让相似向量更可能被分到同一个桶中。这样模型不必对所有 token 做全局两两比较,而是在桶内计算注意力,从而降低长序列注意力的计算成本。
15.8 BERT
BERT 是 Bidirectional Encoder Representations from Transformers 的缩写,是基于 Transformer Encoder 的预训练语言模型。它不使用 Transformer Decoder,而是堆叠多个 Encoder 层来学习文本表示。
传统从左到右语言模型只能利用当前位置左侧上下文。BERT 通过双向上下文建模,让每个位置同时利用左右两侧信息,因此适合理解类任务,例如文本分类、匹配、抽取式问答和序列标注。
BERT 的预训练任务主要包括两个:
| 任务 | 含义 |
|---|---|
| Masked Language Model(MLM) | 随机遮盖输入中的部分 token,让模型根据上下文预测被遮盖的 token |
| Next Sentence Prediction(NSP) | 判断两个句子是否具有上下句关系 |
在下游任务中,常见做法是在 BERT 顶部接一个任务相关的小网络。例如情感分类可以取 [CLS] 位置的表示,接一个线性分类层,再在标注数据上微调。数据量较小时,也可以冻结 BERT 的大部分层,只训练顶部分类层,以降低训练成本和过拟合风险。
[1][2]
参考
^论文:Attention Is All You Need https://arxiv.org/abs/1706.03762
^Transformer 模型详解 https://baijiahao.baidu.com/s?id=1651219987457222196&wfr=spider&for=pc