Skip to content

[神经网络]04 Transformer

目前认为,Transformer是处理序列数据上限最高的模型,并且迁移到非序列数据(比如Vision Transformer之于图像)时仍有不错的效果,因其优秀的性能、高效的计算过程和广阔的应用场景受到了广泛关注。当下大火大语言模型(如ChatGPT、BERT)都是基于Transformer的。

这一章将结合汤老师的课程、原论文以及李沐大神的网课视频,记录下Transformer的相关知识。

引子:为什么需要Transformer?

因为RNN系列模型存在缺陷(此时又是批判前辈时间,并且这些缺点自然也是Transformer的优点)

  • 难以获取长距离的依赖关系:RNN的隐层状态ht只能通过ht1传递信息,如果距离过远,信息传递会出现衰减
  • 难以并行:由于严格限制了信息传递的方式,其信息均来自上一时刻的隐层状态,因此无法并行计算。这在工程上是一个十分致命的问题。

符号约束与术语解释

符号含义
X(x1,x2,...,xn)输入序列,我们通常喜欢把输入记作X
Y(y1,y2,...,ym)Decoder的输出序列,我们通常喜欢把输出记作Y
Z(z1,z2,...,zn)Self-Attention的输出序列,这个序列是一个中间向量,用于后续的处理
R(r1,r2,...,rn)FFN的输出序列,这个序列是Self-Attention的输出序列经过FFN处理后的结果
术语含义
Attention注意力机制,指模型在生成输出时,对输入序列中不同位置的信息赋予不同的权重。
Auto-Regressive自回归,指模型的输出依赖于之前的输出,这一特点在Decoder生成输出的过程中有所体现。
Decoder解码器,在Transformer中的一种结构,用于将向量表示转换为输出序列。
Encoder编码器,在Transformer中的一种结构,用于将输入序列转换为向量表示。
FC/Fully-Connection全连接层,神经网络中一种常见的结构,每个神经元与上一层的所有神经元相连,这种结构的优点是参数多,表达能力强,缺点是计算量大。
FFN/Feed-Forward Network前馈神经网络,在Transformer原始论文中就是一个2层的MLP,也就是两个全连接层,作用是进行非线性运算,让模型学到更抽象的特征。
Multi-Head Attention多头注意力机制,是Transformer中的一种结构,用于增加模型的表达能力。
MLP/Multi-Layer Perceptron多层感知机,神经网络中一种常见的结构,由多个全连接层(FC)组成。
Self-Attention自注意力机制,是Transformer的核心,用于捕捉序列中的长距离依赖关系。
Sequence Transduction Models序列转换模型,指的是输入是序列,输出也是序列的一类模型,看得出来这是单纯从输入和输出的角度来定义的。
Stack堆叠/堆积,不要翻译成“堆栈”,那是计算机组成原理的东西。在这里指一种结构:某种“块”连续地串行排列,按照这种结构进行运算。

10.1 模型介绍

  • 在原始论文《Attention Is All You Need》中,Transformer模型被提出,并且用来完成机器翻译任务。因此下面的内容将以机器翻译任务为例,用以详细介绍Transformer模型。
  • 现在Transformer模型已经被广泛运用在各种序列数据(如时序数据、文本数据等),甚至非序列数据中了(例如Vision Transformer)
  • 顺便说一句,在这篇文章出现之前,你去搜“Transformer”基本上只能搜出来变压器广告和变形金刚剧照,但现在,它的风头已经完全盖过了这两者。但其实这个名字取得也很合适——Transformer能用在多种任务中,“变形金刚”一词很贴切,而Transformer的“Encoder-Decoder”结构,与变压器的结构(原绕组-副绕组)也有异曲同工之妙。

10.1.1 模型整体结构

Transformer结构

"The Transformer follows this overall architecture using stacked self-attention and point-wise, fully connected layers for both the encoder and decoder, shown in the left and right halves of Figure 1, respectively."

“Transformer遵循这一整体架构,编码器和解码器都使用堆叠自注意力、逐点(姑且这么翻译)、全连接层,分别如图1的左半部分和右半部分所示。”

  • 以上是Transformer原论文中的配图,其中左侧为Encoder,右侧为Decoder,我比较喜欢先整体后细节的方式,所以这一小节咱们只看整体结构和输入输出。
  1. Encoder:对于左侧的Encoder,其输入均来自上一层Encoder的输出(第一层Encoder的输入为原始输入序列),也就是图中**Input Embedding+Positional Encoding**的结果。

  2. Decoder:而对于右侧的Decoder,我们能注意到一个不同的地方:它的输入不仅来自左边Encoder,同时还包括了一个**Output Embedding+Positional Encoding。这其实就是Auto-regressive**(自回归)的体现。它表示的意思是,Decoder每生成一个yi,都会将其加入到下一时刻的输入中,也就是说,对于Decoder生成的第t个输出yt,其“Outputs (Shifted right)”实际上是(y1,y2,...,yt1)的向量表示。

    这里沐神总结的非常好:“在过去时刻的输出,也会作为当前时刻的输入”。

    • 此外,李沐老师提到,在解码器做预测任务时是没有输入的,此时的“Outputs (Shifted right)”是解码器在之前的时刻生成的输出,而“Shifted right”表示的是先前的输出作为此时的输入,是“一个一个往右移”地输入。

    这里没听懂没关系,在后面Decoder结构部分举了个例子来讲这里的“Shifted right”。

  3. 输出:因为Transformer仍然是一种**sequence transduction models**模型,因此通常来说Decoder输出的仍然是一个序列。比如在机器翻译任务中,Transformer的输入是一句德语,输出是一句英语,二者都是文本(序列数据),如下图简化结构所示。但是上图我们能看到,在Decoder的输出后面,又套了一个Linear层,然后再套一个Softmax,得到Output Probabilities。这是因为在机器翻译任务中,Decoder每次实际输出的是一个向量(logits),该向量中每个数表示一个单词的分数,随后通过Softmax将其转换为概率,并选择概率最高的单词作为本次的输出。

  4. 补充:最后,我们还能注意到在Decoder和Encoder旁边都有一个N×,这表示实际的Transformer中,编解码器实际上是“Encoders”和“Decoders”,是若干个Encoder和Decoder堆叠在一起的。在原始论文里,作者使用了6个Encoder和6个Decoder。

    但是这个"6"不用奉为圭臬,实际上这个数字是很随意的,可以根据任务的复杂度、数据集的大小等因素来调整。

Transformer简化结构

  • 所以总结一下就是:
    • Encoders:若干个Encoder层,将输入序列生成隐层空间的表示。
    • Decoders:若干个Decoder层,将隐层空间的表示转换为输出序列。
    • 特点:Encoder和Decoder经过多层编码/解码,feature map的大小不变。

10.1.2 Encoder结构

这节咱们分析一下Encoder的结构啊,原论文的图细节非常清晰,但是相对应的,有些复杂。所以咱就把原论文中的图和简化的图一块摆出来,对比着看。

如下所示的这么一个框,咱们把它叫做一个block,一个块,咱们主要是以上图为主。

Encoder结构Encoder简化结构图

  • 在看Encoder结构之前,我们可以先看看它的输入:一个Input EmbeddingPositional Encoding相加。Input Embedding好理解,用Word2Vec或者其他词嵌入算法将原始自然语言转换为向量表示,但Positional Encoding是什么?
    • 因为除了Positional Encoding之外,Transformer就没有其他捕捉序列信息的方法了。Encoder的功能就是将输入的一堆向量xi转换为另一种向量ri,你问Encoderxixj谁在前谁在后?它不知道,所以需要额外的信息来告诉它。Positional Encoding就是这个信息,它是一个和xi同维度的向量,表示xi在序列中的位置。
  • 然后我们看看Encoder啊,首先一眼能看到的是里面包括了一个**Multi-Head Attention(多头注意力模块)和一个Feed Forward**。那么至于什么是注意力机制、为什么要用多头注意力,以及为什么要来个全连接层,咱们后面会详细讲解的。
  • 简单来说,Encoder是将输入xi转换为向量表示ri
    • 接触过NLP的同学可能会奇怪:将自然语言转换成向量表示,这不是embedding吗,哪里是Encoder应该做的?说的没错,实际上输入xi已经是词向量序列了,是经过预处理过程中Word2Vec或者其他词嵌入算法得到的。
    • 但是从意义上来讲,Word2Vec以及其他算法只是将文字(Plain text)转换为向量表示,而Encoder则是利用Self-Attention,将每个词向量转换成了另一种向量,后文在Self-Attention中会讲这个向量Z的含义,当你理解了该向量的含义后,很多问题就迎刃而解了。
Z=Attention(Q,K,V)=Softmax(QKdk)V

似乎暂时还用不着,但感觉在这里放一个公式会显得很专业,就先随手放一个。

  • 随后Z将会被送到Feed Forward中进行处理,从zi转换为ri
  • 所以严格来说,是Multi-Head Attentionxi转换成了zi,而Feed Forward则将zi映射到了ri
  • 最后再说点简化结构图中的东西:
    1. 简化图中的Encoder第一步是**Self-Attention**,其实不用在意,因为Multi-Head Attention就是Self-Attention的改进形式,思想和基本原理是相同的。只不过原论文中为了尽量准确,特意指明了用的是Multi-Head Attention,在初学时二者不用泾渭分明地区分。
    2. 简化图中省去了"Add & Norm"这一步
    3. 右图中的Encoder外部出现了两个箭头,但是按照原论文来说,应当只有1个,要么是向上的,表示该Encoder的输出继续流向下个Encoder;要么是向右的,表示该Encoder已经是N个Encoders中的最后一个了,结果将流向Decoder,但是这里出现了两个箭头,可能是为了简化图的表达?不确定

10.1.3 Decoder结构

同样,也是两张图对比着看

Decoder结构Decoder简化结构

  • 在上面的两幅图中,尽管很多模块的名称看起来并不相同,但实际上这两幅图表示的过程是一样的,确实只是名称不同。咱们还是以上图(原论文)中的叫法来。

  • 首先,输入是Output Embedding+Positional Encoding的结果,而且Output Embedding还有一个Shifted right,这一串设计让人有点眼花缭乱,没事,慢慢掰扯。

    1. 先来聊个简单的:Shifted right
      • 它表示“让输入整体右移一位”,比如说我们的任务是“我爱中国” → “I love China”,那么Output Embedding就是“I love China”,经Shifted right后就变成了"<start> I love China",其中"<start>"表示一个开始标记,这样Decoder就知道开始翻译了。

        But, Why?

      • 因为咱们要做的本质上是个预测任务,Decoder翻译时是循环着逐词“蹦”出来的,那么当进行第t次循环时,它应当预测第t个词,而为了不让它直接通过Output Embedding提前知道第t个词的内容,所以整个Output Embedding都右移一位,这样Decoder就不会“提前看到答案”了。

      突然脑洞一下,这篇论文的阿拉伯语版译文会不会是Shifted left的意思?

    2. 然后Output EmbeddingPositional Encoding进行相加没什么好说的,和前面Encoder的原因一样。
    3. 那么这个Output Embedding到底是什么呢?其实就是这一堆Decoder迭代过程中的输出。比如第一轮迭代,Output Embedding就是"<start>",而这轮迭代的输出结果应当是"I",那么第二轮迭代时,Output Embedding就是"<start> I",而这轮迭代的输出结果应当是"love",以此类推。
    4. 还有一个问题:
  • OK,输入看完了我们开始看第一个模块:Masked Multi-Head Attention,咱们现在只说说Masked(掩盖/遮盖/掩码),其实都差不多,指的其实就是刚刚的Shifted right,让每个时间步的预测只能依赖于该时间步之前的输出和Encoder的输出,Attention相关的部分留到下节讲。

  • 然后我们再看第二个模块:Multi-Head Attention,它不光接收了Encoder的输出,还接收了Masked Multi-Head Attention的输出,然后....就没什么特殊的了,和Encoder的Multi-Head Attention一样。

  • Feed Forward的作用和Encoder中的一样,也是为了让模型学到更复杂的特征。

10.1.4 其他部分

Transformer结构

  • 好,咱们把这个图再贴过来,讲讲整个流程中,刚刚没提到的东西。
  1. 首先就是:Encoder和Decoder都有的这个**Feed Forward**是干嘛的
    • 从结构上来讲,它是一个前馈神经网络模块是个2层MLP,第一层用ReLU激活,第二层使用线性激活函数。
    • 从功能上来讲,它的作用是让模型学到更复杂的特征,因为Multi-Head Attention中只是只有线性变换(矩阵乘法),而Feed Forward中有非线性激活函数,能让模型学到更复杂的特征。 一个脑洞大开的表情包
  2. **\text{Add & Norm}**又是干嘛的呢?
    • 这一步是残差连接和Layer Normalization,层归一化,是为了稳定梯度,防止过拟合,属于常见的工程技巧,不是核心内容,可能是出于这个原因,在简化图中省略了。
  3. 可以看到在整个模型最后,Decoder的输出最后过了一个Linear和一个Softmax,然后得到了Output Probabilities,这可能会让人有些疑问:明明是翻译任务,应该属于预测任务而非分类任务,为什么要用Softmax呢?
    • 这是因为在机器翻译任务中,Decoder每次实际输出的是一个向量(logits),该向量中每个数表示一个单词的分数,随后通过Softmax将其转换为概率,并选择概率最高的单词作为本次的输出。
    • 比如在“我爱中国 → I love China”的任务中,在生成“I”的过程中,Decoder的输出是一个向量,比如它可能形如[0.05, 0.05, 0.80, 0.05, 0.05],其中每个数表示一个单词的分数,随后通过Softmax将其转换为概率,而“I”正是根据这个概率选择出来的。
    • 至于为什么要这么设计:当然是因为这样,每个结果都是一个概率分布,可以知道每个单词的置信度,同时也便于计算交叉熵损失。

其他的....未完待续

10.2 自注意力机制(Self-Attention)

Self-Attention是Transformer的核心,也是其最大的创新之一。它的提出解决了RNN系列模型的长距离依赖问题,同时也使得Transformer能够并行计算。

  • 每个单词有3个不同的向量
    • Q: Query(查询)
    • K: Key(键)
    • V: Value(值)

10.2.1 自注意力计算方法

  1. 每个单词都转化为Embedding(嵌入,或者说词向量)。
  2. 根据Embedding得到第i个词的向量qi,ki,vi,每个词的向量构成了WQ,WK,WV三个权值矩阵(有时候也直接记作Q,K,V)
  3. 然后计算scoreiscorei=qi.kj(j遍历其他所有的词向量),得到若干个score值,这些值构成scorei向量
  4. 然后是个工程技巧(trick),将scorei除以dk,其中dkK的维度,实质上是个归一化,避免尺度不同造成的影响,同时稳定梯度
  5. 对于上述scorei套个Softmax,转换为概率分布,然后再乘以vi,得到最终的zi
  6. 在self-attention需要强调的最后一点是其采用了残差网络中的short-cut,以及Layer Normalization,目的都是稳定梯度,防止过拟合。

10.3 其他设计

10.3.1 Multi-Head Attention

  • 实质即多个Self-Attention并行,允许不同的头关注不同的位置

10.3.2处理序列信息:Positional Encoding

  • 先前的设计中没有利用序列信息,为了解决这个问题,Transformer引入了Positional Encoding

10.3.3 其他Trick

  • 残差连接
  • Layer Normalization

Ques10-例题整理

[原理理解·自注意力机制]

题目内容

  • 请详细解释Transformer模型的自注意力(Self-Attention)机制如何帮助模型捕捉序列中的长距离依赖关系。

分析与解答

  • Self-Attention的运算过程如下:
    • Transformer为每个词向量都分配三个权重矩阵:WQ,WK,WV,将每个词向量分别与这三个权重矩阵相乘,得到qi,ki,vi;然后对于序列中的每一个词xi计算其权重:attentioni=Softmax(QKdk)。实际得到attention系数矩阵,最后按照Z=attentionV得到输出。
  • 在Transformer中,其Encoder和Decoder都使用了Self-Attention机制。
    • 在编码阶段,每个词向量经过编码后都包含了其对于整个序列的相关性信息。
    • 在预测阶段,Decoder会接收来自Encoder传入的Q、K矩阵,使得进行每一次预测时,模型拥有了对于之前序列的全局信息,从而避免了像RNN一样对于长序列编码过程中信息丢失的问题。

[模型理解·网络结构比较]

题目内容

  • 请比较并对比CNN、RNN、GRU、LSTM和Transformer这五种神经网络结构。请考虑他们的主要特性、优点、缺点和适用场景。

分析与解答

模型网络结构特性优点缺点适用场景
CNN卷积层、池化层、全连接层。通过卷积层和池化层来提取特征并减少参数量。权值共享、局部感受野、平移不变性。池化层可能会丢失信息、容易出现梯度消失或梯度爆炸。计算机视觉中,分类、识别等任务。
RNN多个神经元线性排列。适合处理序列数据。可以捕捉长期依赖关系,能有效利用时序信息。难以解决“长期依赖”问题,难以并行化计算。自然语言处理中,如机器翻译、情感分析等任务。
GRU引入了更新门和重置门。通过更新门和重置门控制信息的流动。计算相较于LSTM更快,某些问题下能达到不错的效果。在某些情况下仍然无法很好处理长期依赖问题。同上。
LSTM引入了遗忘门、输入门和输出门。通过遗忘门、输入门和输出门控制信息的流动。适用于处理长期依赖关系,能够有效地缓解梯度消失和梯度爆炸问题。计算较为复杂,开销大。同上。
Transformer包括Decoder-Encoder两部分。基于自注意力机制,能有效应对长距离依赖问题。允许并行计算,对于序列数据的处理效果更好。局部信息的获取不如RNN和CNN强。序列数据的处理,如自然语言处理。

References

上次更新于: