系列文章目录
第七章 Transformer概述
文章目录
前言
2017 年 Google 在《Attention Is All You Need》中提出了 Transformer 结构用于序列标注,在翻译任务上超过了之前最优秀的循环神经网络模型;与此同时,Fast AI 在《Universal Language Model Fine-tuning for Text Classification》中提出了一种名为 ULMFiT 的迁移学习方法,将在大规模数据上预训练好的 LSTM 模型迁移用于文本分类,只用很少的标注数据就达到了最佳性能。
这些具有开创性的工作促成了两个著名 Transformer 模型的出现:
- GPT (the Generative Pretrained Transformer);
- BERT (Bidirectional Encoder Representations from Transformers)。
自从 BERT 和 GPT 模型取得重大成功之后, Transformer 结构已经替代了循环神经网络 (RNN) 和卷积神经网络 (CNN),成为了当前 NLP 模型的标配。通过将 Transformer 结构与无监督学习相结合,我们不再需要对每一个任务都从头开始训练模型,并且几乎在所有 NLP 任务上都远远超过先前的最强基准。
GPT 和 BERT 被提出之后,NLP 领域出现了越来越多基于 Transformer 结构的模型,其中比较有名有:
基于 Transformer结构的模型在计算机视觉领域也成为了热门研究方向,并刷新了各种计算机视觉任务的最新记录。
一、Transformer的结构
《Attention Is All You Need》是一篇Google的研究工作者在2017年提出的将Attention思想发挥到极致的论文。这篇论文中提出一个与CNN和RNN不同的全新模型,叫 Transformer。Transformer完全依赖于注意力机制,并摒弃了循环。它使用的是一种特殊的注意力机制,称为自注意力(self-attention)。
1.整体结构
Transformer主要分为两个部分,分别为编码器和解码器:
编码器由多层编码器模块组成(Transformer论文中使用的是6层编码器,但这里的层数6并不是固定的,可以根据实验效果来修改层数)。同理,解码器也是由多层解码模块组成(论文里也使用了6层解码器)。每层编码器网络结构是一样的,每层解码器网络结构也是一样的,不同层编码器和解码器网络结构不共享参数。
在pytorch的nn.Transformer中已经实现了Transformer主体部分(不包括编码器的Embedding、Positional Encoding和解码器的Linear+Softmax)。
Transformer — PyTorch 2.4 documentation
2.自注意力
翻译一个词语需要依赖于上下文。例如要将英文“You like this course”翻译为法语,由于法语中“like”的变位方式因主语而异,因此需要同时关注相邻的词语“You”。同样地,在翻译“this”时还需要注意“course”,因为“this”的法语翻译会根据相关名词的极性而变化。对于复杂的句子,要正确翻译某个词语,甚至需要关注离这个词很远的词。同样的概念也适用于其他 NLP 任务:虽然词语本身就有语义,但是其深受上下文的影响,同一个词语出现在不同上下文中可能会有完全不同的语义(例如“我买了一个苹果”和“我买了一个苹果手机”中的“苹果”)。
Transformer 模型的标志就是采用了注意力层 (Attention Layers) 的结构,并且Transformer编码器中的注意力层可以访问句子中的所有词语。注意力层的作用就是让模型在处理文本时,将注意力更多的放在某些关联词上。
编码器模块中的注意力层为多头注意力。当给定相同的查询、键和值的集合时,多头注意力的每一个头基于相同的注意力机制可以学习到不同的行为,然后将不同的行为作为知识组合起来,捕获序列内各种范围的依赖关系(例如,短距离依赖和长距离依赖关系)。因此与简单的 Scaled Dot-product Attention 相比,Multi-head Attention 可以捕获到更加复杂的特征信息。所谓的“多头” (Multi-head),其实就是多做几次 Scaled Dot-product Attention,然后把结果拼接。
由于查询、键和值来自同一组输入,因此被称为 自注意力(self-attention), 也被称为内部注意力(intra-attention)。
2.1 比较卷积神经网络、循环神经网络和自注意力
具体来说,将比较的是卷积神经网络、循环神经网络和自注意力这几个架构的计算复杂性、顺序操作和最大路径长度。(顺序操作会妨碍并行计算;如果任意的序列位置组合之间的路径越短,则能更轻松地学习序列中的远距离依赖关系)
总而言之,卷积神经网络和自注意力都拥有并行计算的优势,而且自注意力的最大路径长度最短。但是因为其计算复杂度是关于序列长度的二次方,所以在很长的序列中计算会非常慢。
二、输入的向量表示
输入序列的每个单词被由词向量加上位置向量表示。
Input Embedding就是将token映射成高维向量。
Positional Encoding是位置编码。在处理词元序列时,循环神经网络是逐个的重复地处理词元的, 而自注意力则因为并行计算而放弃了顺序操作。为了使用序列的顺序信息,通过在输入表示中添加位置编码(positional encoding)来注入绝对的或相对的位置信息。
1.词向量
和常见的NLP 任务一样,我们首先会使用词嵌入算法(embedding algorithm),将输入文本序列的每个词转换为一个词向量。实际应用中的向量一般是 256 或者 512 维。
通常使用nn.Embedding来实现。但nn.Embedding的参数并不是一成不变的,也是会参与梯度下降。Embedding — PyTorch 2.4 documentation
- num_embeddings:词典的大小。如果你的词典中包含5000个单词,那么这个字段就填5000。
- embedding_dim:编码后词向量的维度。
- padding_idx:填充索引。如果输入的某个单词的编号为padding_idx,那么对应的词向量为0向量。有时我们的字典里会增加一项unknown代表未知的单词,这样我们就可以使用该参数,对所有unknown的单词都编码成0。
2.位置向量
Transformer模型对每个输入的词向量都加上了一个位置向量。这些向量有助于确定每个单词的位置特征,或者句子中不同单词之间的距离特征。
有很多种不同的位置编码方式,可以通过学习得到也可以直接固定得到。接下来描述的是基于正弦函数和余弦函数的固定位置编码 (Vaswani et al., 2017)。
在位置嵌入矩阵P中,行代表词元在序列中的位置,列代表位置编码的不同维度。
2.1 绝对位置信息
在二进制表示中,较高比特位的交替频率低于较低比特位。基于正弦函数和余弦函数的固定位置编码在编码维度上降低频率。所以可以根据位置向量,确定单词的绝对位置。
2.2 相对位置信息
三、Transformer执行过程
Pytorch中Transformer的调用示例如下:
1.推理过程
上图是一个翻译任务的推理流程:Encoder 的输出被送入到 Decoder 层中以预测概率最大的下一个词,然后当前的词语序列又被送回到 Decoder 中以继续生成下一个词,重复直至出现序列结束符 EOS 或者超过最大输出长度。也就是说推理的时候,Encoder仅运行一次,Decoder需要循环运行。
Transformer调用的输入和输出如下:
- src: tokens经过Input Embedding和Positional Encoding转化为序列向量src。一般使用token 0表示句子开始(<bos>),token 1表示句子结束(<eos>),token 2为填充(<pad>)。填充的目的是为了让不同长度的句子变为同一个长度,这样才可以组成一个batch。
- tgt:tokens经过Input Embedding和Positional Encoding转化为序列向量src。tgt也是Transformer的输入。第一步输入的tgt仅有一个token固定为<bos>,之后每一步的tgt等于上一步的tgt对应的tokens拼接上一步的输出token。
- out:每一步的输出是多个概率分布,每一个概率分布等效于长度为词典长度的多分类概率。最后一个有效概率分布中概率最大的token就是当前步的输出。
2.训练过程
Transformer推理时,是一个词一个词的输出,这样做效率太低了。训练时,会将target一次性给到Transformer。
Transformer调用的输入和输出如下:
- src: 和推理的时候相同,都是待翻译句子经过Input Embedding和Positional Encoding转化的序列向量。
- tgt:如果完整的翻译结果有n个tokens,训练时是一次将前n-1个tokens输入。所以一般tgt处理时会将目标句子删掉最后一个token。
- out:在训练时,transformer会一次输出多个概率分布。得到输出概率分布后就可以计算loss了,并不需要将每一个概率分布再转成对应的token。输出的概率分布对应完整的翻译结果的后n-1个tokens。
3.自监督训练
Transformer 模型本质上都是预训练语言模型,大都采用自监督学习 (Self-supervised learning) 的方式在大量生语料上进行训练,也就是说,训练这些 Transformer 模型完全不需要人工标注数据。
例如下面两个常用的预训练任务:
这些语言模型虽然可以对训练过的语言产生统计意义上的理解,例如可以根据上下文预测被遮盖掉的词语,但是如果直接拿来完成特定任务,效果往往并不好。因此,我们通常还会采用迁移学习 (transfer learning) 方法,使用特定任务的标注语料,以有监督学习的方式对预训练模型参数进行微调 (fine-tune),以取得更好的性能。
四、Transform家族及分类
编码器和解码器可以根据任务的需求而单独使用:
- 纯 Encoder 模型(例如 BERT),又称自编码 (auto-encoding) Transformer模型:适用于只需要理解输入语义的任务,例如句子分类、命名实体识别;
- 纯 Decoder 模型(例如 GPT),又称自回归 (auto-regressive) Transformer模型:适用于生成式任务,例如文本生成;
- Encoder-Decoder模型(例如 BART、T5),又称 Seq2Seq (sequence-to-sequence) Transformer模型:适用于需要基于输入的生成式任务,例如翻译、摘要。
五、大模型
除了 DistilBERT 等少数模型,大部分 Transformer 模型都为了取得更好的性能而不断地增加模型大小(参数量)和增加预训练数据。下图展示了近年来模型大小的变化趋势:
如果每一次研究者或是公司想要使用语言模型,都需要基于海量数据从头训练,将耗费巨大且不必要的全球成本,因此共享语言模型非常重要。只要在预训练好的模型权重上构建模型,就可以大幅地降低计算成本和碳排放。
参考文献
Transformer各层网络结构详解!面试必备!(附代码实现) - mantch - 博客园
第二章:Transformer 模型 · Transformers快速入门
Transformer入门(1):模型简介及其在机器视觉上的应用 - 陶小桃Blog
https://github.com/datawhalechina/learn-nlp-with-transformers/blob/main/docs/
10.5. 多头注意力 — 动手学深度学习 2.0.0 documentation
Pytorch中 nn.Transformer的使用详解与Transformer的黑盒讲解-CSDN博客