如何最简单、通俗地理解Transformer

如何最简单、通俗地理解Transformer

附赠自动驾驶最全的学习资料和量产经验:链接

目标:用通俗的方式拆解Transformer结构,配合具体示例帮助理解。

思维导图:

image

image

好了,下面进入正题!

一、Transformer结构整体介绍

Transformer这个词汇已经不是新鲜词了,网上关于它的深入探讨和解读层出不穷。如果没有NLP算法基础的话,看着可能有点发懵,不过没关系,你并不需要完全掌握所有细节。只需明确两个核心概念即可:

  1. Transformer 中的注意力机制是如何工作的

  2. Decoder 部分的生成式输出具体意味着什么

对于一条输入的数据,在这个复杂的架构中是如何流动和处理的,我来给大家拆解一下

Transformer最经典论文【Attention Is All You Need】,没有之一。地址:https://arxiv.org/abs/1706.03762

首先:Transformer由编 码器(Encoder) 和解码器(Decoder)组成,其中编码器用于学习输入序列的表示,解码器用于生成输出序列。

image

image

1.1 如何做文本表示

在Transformer模型中,首先会对输入文本进行处理以得到合适的表示。

为什么要进行这样的转换呢?
考虑这样一个场景:当你输入"AI+编程 扬帆起航"这句话,计算机能直接理解吗?或者说,当你与ChatGPT互动时,它是否真的“听到”了你说的每一个词或字?实际上并非如此。
ChatGPT并不直接处理自然语言。它需要将我们的输入转换为它能理解的数据形式。简而言之,它会把每个词或每个字符编码成一个特定的向量形式。

这个编码过程具体步骤如下:

  1. 词嵌入(Word Embedding): 文本中的每个单词都被转换为一个高维向量。这个转换通常是通过预训练的词嵌入模型(如Word2Vec、GloVe等)完成的。

  2. 位置嵌入(Positional Embedding): 标准的Transformer模型没有内置的序列顺序感知能力,因此需要添加位置信息。这是通过位置嵌入完成的,它与词嵌入具有相同的维度,并且与词嵌入相加。

例如,考虑句子"AI+编程 扬帆起航"。
如果没有位置嵌入,该句子可能会被错误地解析为"编AI+程,航帆扬起"等,这会破坏句子原有的顺序和语义。位置嵌入的目的就是确保编码后的词向量能准确地反映句子中词语的顺序,从而保留整个句子的原意。

  1. 相加(Addition): 词嵌入和位置嵌入相加,得到一个包含了文本信息和位置信息的新的嵌入表示。最终得到输入的Transformer表示x,这样,模型就能知道每个单词不仅是什么,还能知道它在序列中的位置。

image

image

举个例子:

image

image

通过这样的一个处理过程,模型就可以认识"扬帆起航"这样的一个输入。

那对于Transformer的输入处理部分,从架构图上编码器和解码器部分都有输入,这个怎么理解?

image

image

这是因为:在Transformer模型中,编码器(Encoder)和解码器(Decoder)各自有独立的输入。通常,在有监督学习的场景下,编码器负责处理输入样本,而解码器处理与之对应的标签。这些标签在进入解码器之前同样需

要经过适当的预处理。这样的设置允许模型在特定任务上进行有针对性的训练。

通过一个简单的机器翻译任务来说明这个概念。假设有以下的英语到法语的翻译对:

  • 英语(输入样本): “Hello, world”

  • 法语(标签): “Bonjour, monde”

在这个示例中,编码器(Encoder)会接收"Hello, world"这个句子作为输入。这个句子首先会被转换成一组词向量或者字符向量,然后进入编码器进行处理。
与此同时,解码器(Decoder)会接收与"Bonjour, monde"对应的标签作为输入。同样地,这些标签首先会被转换成一种机器可理解的表示(比如词向量或字符向量),然后进入解码器。
编码器处理完输入样本后,它的输出会与解码器的输入进行某种形式的结合,以生成最终的翻译输出。通过这个机制,模型可以在有监督的学习环境中进行训练,以完成特定的任务,如机器翻译。

1.2 如何理解Encoder(编码器部分)

Transformer中的编码器部分,作用是学习输入序列的表示,位置如下图所示:

image

image

在Transformer模型的编码器(红色虚线框)部分,数据处理流程如下:

首先,输入数据(比如一段文字)会被送入注意力(Attention)机制进行处理,这里会给数据里的每一个元素(比如每一个字或词)打个分数,以决定哪些更重要,在"注意力机制"(Attention)这个步骤之后,会有一些新的数据生成。

接着,一个“Add”操作会被执行,在注意力机制"中产生的新数据会和最开始输入的原始数据合在一起,这个合并其实就是简单的加法。"Add"表示残差连接,这一操作的主要目的是确保数据经过注意力处理后的效果至少不逊于直接输入的原始数据。

随后,数据会经过一个简单的数学处理,叫做“层归一化”(Norm),主要是为了让数据更稳定,便于后续处理。之后,数据将进入一个双层的前馈神经网络。这里的目标是将经过注意力处理的数据映射回其原始的维度,以便于后续处理。这是因为编码器会被多次堆叠,所以需要确保数据的维度在进入下一个编码器前是一致的。简单来说:就是把经过前面所有处理的数据变回原来的形状和大小。

注意看图中编码器左侧的Nx标识,意味着会有多个编码器堆叠。

最后,为了准备数据进入下一个编码器(如果有的话),数据会再次经过“Add”和“Norm”操作,输出一个经过精细计算和重构的词向量表示。

这样的设计确保了模型在多个编码器层之间能够有效地传递和处理信息,同时也为更复杂的计算和解码阶段做好了准备。简单来说,Transformer的编码器就是通过这些步骤来理解和处理输入的数据,然后输出一种新的,更容易理解的数据形式。如图:

image

image

1.3 如何理解Decoder(解码器部分)

Transformer中的解码器部分,作用是用于生成输出序列,位置如下图所示:

image

image

在Transformer模型的解码器(紫色虚线框)部分,数据处理流程如下:

在Decoder部分,数据首先进入一个带遮罩(masked)的注意力(Attention)机制,这个遮罩的作用是确保解码器只能关注到它之前已经生成的词,而不能看到未来的词。

然后,这一层输出的信息会与来自Encoder部分的输出进行融合。具体来说,这两部分的信息会再次经历一个注意力机制的处理,从而综合考虑编码与解码的内容。

这个过程之后,解码器的操作与编码器部分大致相同。数据会经过层归一化、前馈神经网络,再次进行层归一化,最终输出一个词向量表示。输出的词向量首先会通过一个线性层(Linear)。这一步的目的是将向量映射到预先定义的词典大小,从而准备进行词预测。

最后,使用softmax函数计算每个词的生成概率。最终,选取概率最高的词作为该时刻的输出。

现在假设有一个很小的词典,只有3个词:“apple”,“banana”,“cherry”。线性层会将这个3维向量转换成另一个3维向量(对应“词典”大小)。
假设转换后的向量是 [2.5, 1.0, -0.5]
通过softmax函数,这个向量会转换为概率分布,比如 [0.8, 0.18, 0.02]
这就意味着模型认为下一个词是“apple”的概率是80%,是“banana”的概率是18%,是“cherry”的概率是2%。
这样,就能从解码器的高维输出中预测出一个实际的词语了。

这样,Decoder不仅考虑了之前解码生成的词,还综合了Encoder的上下文信息,从而更准确地预测下一个词。

二、注意力机制,到底在注意什么?

对于人类来说,当开始做某一件事时,通常会集中注意力在某些关键信息上,而忽视其它不太相关的信息。

当你正在开车并接近一个交叉口时,你可能会特别关注红绿灯、行人以及其他车辆的动向,而忽略了沿路的风景或广告牌等不太相关的信息。这样,你能确保自己作出正确的行动决策,比如停车或继续行驶。

那对于计算机来说,它是如何解析上下文信息,理解不同语义之间的关系呢?

image

image

这个图通常用来展示如何通过注意力机制确定代词"it"指代的是哪个名词(在这个例子中是"The Animal")原始句子:“The Animal didn’t cross the street because it was too tired"译为:因为动物太累了所以没有过马路。“it"指代的是"The Animal”,然而,如果改变句子中的一个词,将"tired"替换为"narrow”,得到的新句子是"The Animal didn’t cross the street because it was too narrow",译为:由于街道太窄,动物没有过马路。在这个新的句子中,“it"指"the street”。

因此,模型需要能够理解当输入的句子改变时,句子中的词义也可能会随之改变。这种灵活性和准确性在Transformer模型中得到了体现,而之前的模型都无法达到这一目标。

2.1 Self-Attention机制的工作原理

Attention机制的工作原理可以这样形象化地描述:

模型把每个词编码成一个向量,然后把这些向量送入模型中。在这里,每个词都会像发送一条“询问”一样,去问其他词:“咱们之间的关系紧密吗?我们亲近吗?”如果关系紧密,模型就会采取一种行动,反之则会采取另一种行动。不仅每个词都会发出这样的“询问”,而且也会回应其他词的“询问”。通过这样的一问一答互动,模型能够识别出每两个词之间的紧密关系。一旦这种关系被确定,模型就会把与该词关系更紧密的词的信息“吸收”进来,与其进行更多的信息融合。这样,比如在翻译任务中,模型就能准确地识别“it”应该翻译为“animal”,因为它的向量已经融合了与“animal”这个词紧密相关的信息。

所以注意力机制的核心就是要做重构词向量这样一件事。这种机制转化成计算机的计算过程,是这样的:

2.2 Q,K、V的计算过程

对于上面形象化的描述中,可以抽取出注意力机制的三要素:

  • Q:即query,可以理解为某个单词像其它单词发出询问

  • K:即Key,可以理解为某个单词回答其它单词的提问

  • V:即Value,可以理解为某个单词的实际值,表示根据两个词之间的亲密关系,决定提取出多少信息出来融入到自身

image

image

在Transformer模型中,Q、K和V是通过输入向量表示Transformer(x)与相应的权重矩阵Wq,Wk,Wv进行矩阵运算得到的。

如果你熟悉深度学习,那么应该知道,数据在模型内部主要是与不同的权重参数进行矩阵乘法。如果之前没基础的,就把它当作模型的一个固有模块,一个制定的计算规则。

这些权重矩阵最初是通过数学方法进行初始化的,然后在模型多轮训练的过程中逐渐更新和优化。目标是使得传入的数据与这些权重矩阵相乘后,能够得到最优化的Q、K和V矩阵。

以Q为例,其第一个元素是通过输入向量_x_的第一行与权重矩阵Wq的第一列进行点乘和加和运算得到的。

image

image

因此,在Q矩阵中的第一行实际上是这样的意义:它包含了第一个词(与输入X的第一行对应)在查询其他词时所需的关键信息。同样地,K和V矩阵的计算逻辑与此相似。在K矩阵的第一行里,存储的是第一个词在回应其他词的查询时所需的信息。而在V矩阵的第一行,所包含的是第一个词自身携带的信息。在通过Q和K确定了与其他词的关系后,这些存储在V中的信息被用来重构该词的词向量。

当得到了Q,K,V之后,Attention做了如下操作:

image

image

这个公式就涉及到了一问一答的这个过程,它表现出来的计算过程是这样的:

image

image

计算过程同样是矩阵相乘再相加,所以得到的QK^T矩阵就表达了词与词之间关系的紧密程度

为什么这样就能衡量词之间的紧密程度?
在计算矩阵乘法的时候,向量对应元素的乘积,这种计算方式在数学上叫向量的内积。
向量的内积在向量的几何含义上表达的是:内积越大,两个向量就更趋向于平行的关系,也就表示了两个向量更加相似,当内积为0,两个向量就会呈现垂直的关系,表示两个向量毫不相关。
那对于Attention机制中这种Q和K一问一答的形式,问的就是两个词之间的紧密程度,所以也就可以通过内积的方式,来衡量两个词之间的相似性

在这个过程中,可能也都注意到了,它对自己也进行了提问,并自己也给出了回答,为什么要这样做呢?

以这个示例:“The Animal didn’t cross the street because it was too tired"译为:因为动物太累了所以没有过马路。“it"正常来说作为代词,指代的是"它”,但在这个句子中,我们希望它指代是"The Animal”,所以它不把自己在这个句子中的重要性也表现出来,不对自己的信息进行重构的话,它可能就没有办法改变自己原有的意思,也就无法从原本的意思"它"改为指代"The Animal"。

也就是因为这种操作,所以在Transformer中的注意力机制被叫做Self-Attention(自注意力机制)。

当衡量句子之间的紧密关系的结果出来之后,那么如何去重构V?转化成计算过程是这样的:

image

image

在计算得到QK^T矩阵矩阵后,假设第一行的数据分别为:100,80,20,12,那么接下来的问题就变成了如何量化地决定哪些词应贡献多少信息。

为解决这一问题,就会应用Softmax函数来对每一行进行归一化处理,这样做会确保该行中所有元素的和为1。假如经过Softmax处理后,第一行变成了某种分数形式,例如:0.4,0.2,0.2,0.1,那么这意味着将用第一个词的40%的信息、第二个词的20%的信息…来构建目标词的新表示。这样,Softmax操作实质上是在量化地衡量各个词的信息贡献度。

公式中除以\sqrt{d_k}是为了避免在计算向量內积时因为向量矩阵过大,计算出来的数值比较大,而非单纯的因为词之间的紧密程度这一问题。

当得到了每个词之间的信息贡献度概率之后,重构V的过程转化成计算过程是这样的:

image

image

进一步拆解这个过程是这样的:

image

image

也就是说:从第一个词中拿出40%的信息,从第二个词中拿出20%的信息…以此类推,最终得到Z,通过这种计算的形式得到的Z矩阵,每个位置就包含了所有与之有关系的信息。

这就是Transformer中Self-Attention机制中的计算过程。

三、 Decoder 如何做生成式输出

Transformer的Decoder部分与Encoder部分有许多相似之处,但也存在一些关键的差异。Decoder增加了一个额外的注意力层。此外,除了它自身的输入信息,Decoder还会整合Encoder的输出信息。(如果是监督训练任务)

image

image

Transformer模型中的解码器(Decoder),其主要任务是预测下一个输出词,所以称它为生成式模型。

为了更好地理解这个过程,可以用一个机器翻译任务作为例子:

假设有一条中英双语训练样本:"我是一名学生" (X) --> "I am a student" (Y)
当解码器开始工作时,它需要一个初始的输入来启动预测过程。但是,为了预测第一个词"I",解码器没有之前的上下文。因此,需要为其引入了一个起始符 <s> 作为初始的输入。所以训练样本的目标序列就被调整为:<s>, I, am, a, student
解码的过程如下:

  1. 输入起始符<s>到解码器。

  2. 通过Attention机制,解码器对编码器的输出(也就是"我是一名学生"的表示)进行注意,并进行融合。

  3. 基于起始符<s>和编码器的融合输出,解码器预测第一个词,即"I"。

  4. 接下来,"I"和<s>都会被用作已知信息,再次输入到解码器。

  5. 解码器继续通过Attention机制对编码器的输出进行注意,然后预测下一个词"am"。

  6. 这个过程不断重复,直到预测出整个句子"I am a student"。

看下这个动图尝试理解:

http://jalammar.github.io/images/t/transformer_decoding_2.gif

3.1 Decoder中的Attention与Encoder中的Attention有什么不同

首先,从名称上,就可以发现它们有所区别。在Decoder中,首先遇到的是“Masked Attention”。为什么需要这种设计?在Transformer模型的解码阶段,每个词都是逐个生成的。

例如,当预测“am”时,模型不应该提前“知道”或“看到”接下来的“a student”。

可以将这个过程想象为一个时间线:在预测一个特定的词时,你不能“预知”它之后的词汇,因为在实际情境中,那部分尚未发生。为了确保模型在这一时点上不会受到未来词汇的干扰,解码器采用了掩码操作。通过这种方式,模型在处理某个词时,后续的所有词都会被遮挡,确保模型只基于已知的上下文进行预测。

image

image

拆解成Decoder内部的计算过程,是这样的:

首先:准备输入数据矩阵(由标签加上起始符组成)和遮挡矩阵(Mask矩阵)。如图

image

image

遮挡矩阵的设计是为了确保在计算时,被遮挡的部分(上半部分)得到的是一个较小的值,使其对结果的影响最小。

具体地说:
考虑遮挡矩阵的第一行,它表示预测第一个词时的情况。此时,模型只知道起始符,而对于当前预测的词及
其后的词,模型是不知道的。这意味着模型在预测第一个词时,仅能依赖起始符
类似地,当模型在预测第二个词时,即遮挡矩阵的第二行,它仅知道起始符和第一个词。而第二个词及其后
的所有词对模型来说都是未知的。

这样的设计确保了模型在预测某个词时,仅仅依赖于其之前的词,而不会受到后面词的干扰。

然后还是经过和Encoder过程一样的Q,K,V计算过程:

image

image

image

image

得到的QK^T矩阵后(表明词与词之间关系的紧密程度的矩阵),与之前准备的Mask矩阵做按位相乘,如图:

image

image

对于QK^T矩 与mask矩阵相乘的过程,这个“相乘”是按位相乘,也就是每个对应的元素进行相乘。

为了直观地理解,可以设想mask矩阵的遮挡部分都是0,而未遮挡的部分都是1。那么,在这种按位相乘之后,被遮挡的部分在结果中的对应位置就都是0。例如,对于第一个位置,它只有起始符是“亮”的(也就是为1),而其它部分都是“暗”的(也就是为0)。

举个示例,假设得到的QK^T矩阵的前两行Score 是这样的:

image

image

这样设计的目的是确保:在预测当前词时,模型只能获取到它之前的词的信息,而对当前词自身及其后面的所有词都是一无所知的。在计算得到QK^T矩阵后,在Mask QK^T 上进行Softmax操作。此时,每一行的元素和都会等于1。然而,对于单词0,其在单词1、2、3和4上的Attention Score都是0。

image

image

最后:将经过Softmax的Masked QK^T 与Value矩阵V相乘以获取注意力加权的输出,这个输出Z就是Decoder的Masked Self-Attention部分的结果,如下:

image

image

## 3.2 理解什么是Cross Attention

当输入经过Mask Attention后,要进入第二个Attention,但这个Attention不再是单纯的自注意力机制,而是Cross Attention,如下:

image

image

为什么需要Cross Attention?**因为编码器持有了输入序列(比如:“我是一个学生”)的信息,而解码器的目标是在给定该输入时产生正确的输出序列。为了实现这一点,解码器需要对编码器输出的所有信息都有所了解,从而知道下一个输出词应该是什么。

Cross Attention的操作方式和普通的注意力机制非常相似,但是Q来自于解码器的输出,而K和V来自于编码器的输出。这确保了解码器可以"询问"编码器有关输入序列的信息。这种"一问一答"的描述是形象的,它说明了解码器是如何利用编码器的信息来确定最合适的输出的。

例如,在进行“我是一个学生”到“I am a student”的翻译时,解码器可能会询问编码器:“根据你对‘我’的理解,接下来我应该输出什么?”通过这种方式,解码器可以更准确地预测目标序列的下一个词。

你可以这样简单理解:
第一步是类似于“自己对话”的方式,这被称作Masked Self-Attention。这确保解码器在“猜”某个词时只参考前面的词。接着是第二步,叫做Cross Attention或“交叉对话”。这里,解码器会“询问”编码器关于原始句子(例如:“我是一个学生”)的信息。这就像解码器问编码器:“你认为我接下来应该说什么?”然后编码器给出建议,例如:“接下来应该是‘I’”。这样,解码器就能更好地完成翻译任务。
所以,简单说,第一步是解码器和自己“对话”,确定应该问什么问题。第二步是向编码器“提问”,得到答案,并继续翻译。这就是Decoder的两步注意力机制的工作原理。

在Decoder的这种Cross Attention之后,模型将继续进行与Encoder部分相似的处理流程,包括多次的注意力计算和前馈神经网络操作。当Decoder的这些步骤全部完成后,输出会进入一个线性层进行映射。这个映射层的作用是把Decoder的输出转化为与词典大小相同的向量。接着,这个向量会经过Softmax层,转化为概率分布。我们最后根据这个概率分布选择概率最大的词作为输出。

image

image

这样,Transformer的整个工作流程就完成了。

  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值