掌握Transformer之学习各组件

文摘   科技   2024-09-13 07:36   江苏  
点击蓝字
 
关注我们










01


引言



这是我关于Transformer系列的第二篇文章。在前一篇文章中,我们了解了Transformer结构的功能、相关架构及其相比于RNN架构的优势在本文中,我们可以深入了解Transformer结构的工作原理。我们将通过实际的矩阵表示来了解数据如何在该结构内流动,并了解每个阶段所需要执行的相关计算。


闲话少说,我们直接开始吧!






02


Transformer整体结构


正如我们在第一部分中所看到的,Transformer架构的主要组成如下所示:

Transformer整体网络结构

观察上述结构,我们知道编码器和解码器的输入,主要包括嵌入层以及位置编码层;同时编码器stack包含多个编码器,其中每个编码器包括一个多头自注意力层以及一个前馈神经网络层;解码器stack包含多个解码器,其中每个解码器包括一个多头自注意力层,一个多头交叉注意力层以及一个前馈神经网络层;右上角的输出head主要包括全连接线性层以及分类softmax层。
为了展示每个组件的功能,让我们以训练Transformer来解决翻译问题的过程中深入探讨一下 Transformer 的工作原理。我们将使用一个训练数据样本进行讲解,该样例包括一个输入序列(英语'You are welcome')和一个目标序列(西班牙语'De nada')。




03


 嵌入


与任何 NLP 模型一样,Transformer 需要了解每个单词的两个方面--单词的含义及其在序列中的位置。

  • 嵌入层对单词的词义进行编码。
  • 位置编码层表示单词在句子中的位置。

Transformer将这两种编码表示进行相加操作,从而将二者结合在一起。

我们首先来学习嵌入层,Transformer有两个嵌入层,如上图所示:输入序列被送入第一个嵌入层,即输入嵌入层。将目标序列右移一个位置,并在第一个位置插入一个开始标记后,将目标序列送入第二个嵌入层。
请注意,在推理过程中,我们没有目标序列,我们将输出序列循环送到第二个嵌入层,这就是它被称为 "输出嵌入"的原因。

如上图所示,使用我们的词汇表可以将文本序列映射为数字单词 ID。然后,嵌入层将每个输入词映射为嵌入向量Embeddings,嵌入向量是该单词更丰富的语义表示。






04


  位置编码层


由于 RNN 实现了一个循环,每个单词都是按顺序输入的,因此它隐含地知道每个单词的位置。然而,Transformer架构并不使用 RNN,序列中的所有单词都是并行输入的。这是它相对于 RNN 架构的主要优势,但这也意味着位置信息会丢失,必须重新单独进行添加。

与两个嵌入层一样,Transformer架构中也有两个位置编码层。位置编码的计算与输入序列无关。这些都是固定常数值,只取决于序列的最大长度。这些常数的计算公式如下:

上述公式中:

  • pos 是单词在输入序列中的位置

  • d_model 是编码矢量的长度(与嵌入矢量长度相同)

  • i 是位置编码向量中的索引值

换句话说,位置编码层交织了一条正弦曲线和一条余弦曲线,所有偶数索引都有正弦值,所有奇数索引都有余弦值。举例来说,如果我们对一个包含 40 个单词的序列进行编码,我们可以在下面看到一些组合的编码值。

蓝色曲线表示所有40个单词位置的第 0 个索引的编码情况,橙色曲线表示所有 40 个单词位置的第1个索引的编码情况。其余的索引值也有类似的曲线。




05


  矩阵计算


我们知道,深度学习模型一次处理一批训练样本。嵌入层和位置编码层对表示一批序列样本的矩阵进行处理。嵌入层采用(samples,seq_len)形状的单词矩阵。它将每个单词ID编码成单词向量,单词向量的长度为embedding_size,从而得到一个(samples,seq_len,embedding_size)形状的输出矩阵。位置编码层使用的编码大小等于嵌入大小。因此,它产生的矩阵形状与嵌入矩阵相似。

嵌入层和位置编码层产生的(samples,seq_len,embedding_size)矩阵形状在整个Transformer结构中都会保持不变,因为数据会流经编码器Stack和解码器Stack,直到最后的输出层对其进行reshape。

这样我们就掌握了Transformer中的三维矩阵维度。不过,为了简化可视化效果,从现在起我们将去掉第一个维度(samples),而使用单个样本的二维表示法:

输入嵌入将其输出送入编码器。同样,输出嵌入也会输入到解码器。






06


  编码器

编码器stack和解码器stack分别由多个(通常是六个)编码器和解码器组成,按顺序连接。

编码器stack中的第一个编码器接收经过嵌入层和位置编码层的输入嵌入,而其他编码器则接收前一个编码器的输出作为输入。编码器将其输入传入多头自注意力层,自注意力层的输出进入前馈神经网络层,然后将其输出向上发送到下一个编码器。如下所示:

自注意力层和前馈神经网络层均有一个skip-connection,然后进行LayerNorm归一化层。最后一个编码器的输出被送入解码器stack中的每个解码器,如下所述。





07


  解码器

解码器的结构与编码器的结构非常相似,但也有一些不同之处。与编码器一样,解码器stack中的第一个解码器接收嵌入层和位置编码层处理后的输出嵌入作为输入。stack中的其他解码器上一个解码器的输出作为输入。
解码器将其输入传递给多头自注意力层。该层的工作方式与编码器略有不同。它只允许关注序列中较早的位置。这是通过mask位置来实现的,我们稍后将讨论这一点。

与编码器不同,解码器有第二个多头交叉注意力层,即编码器-解码器交叉注意力层。编码器-解码器交叉注意力层的工作原理与自注意力层类似,只是它结合了两个输入源--其下的自注意力层和编码器stack的输出。该注意力层的输出被送入前馈神经网络层,然后将其向上输出发送到下一个解码器。
每个子层(自注意力层、编码器-解码器交叉注意力层和前馈层)周围都有一个残差连接,然后是LayerNorm归一化层。






08


  Attention

在Transformer系列第一篇文章中,我们谈到了为什么在处理序列时注意力机制如此重要。在 Transformer 中,Attention 有三个用途:

  • 编码器中的自注意力层 - 关注输入序列自身

  • 解码器中的自注意力层 - 关注目标序列自身
  • 解码器中的交叉注意力层 - 目标序列关注输入序列
Attention层的输入有三个Query,Key和Value。在编码器的自注意力层中,编码器的输入会传递给Q、K、V这三个参数,如下所示:

与之类似,在解码器的自注意力层中,解码器的输入被传递给所有三个参数,即Q、K和V。
与之不同的是,在解码器的交叉注意力层中,编码器stack中最后一个编码器的输出被传递给参数V 和 K。其下的自注意力模块的输出则传递给参数Q。如下所示:





09


Multi-head  Attention

Transformer将每个注意力处理器称为一个注意力头,并并行重复多次。这就是所谓的多头注意力。它通过将多个类似的注意力计算组合在一起,使注意力具有更强的特征表达能力。

Query、Key和Value分别通过独立的线性层,每个线性层都有自己的权重,产生三个结果,分别称为 Q、K 和 V。然后,如下图所示,使用注意力公式将这些结果合并在一起,计算得出注意力分数。

这里需要注意的是,Q、K 和 V 包含了序列中每个单词的编码表示。然后,Attention的计算会将序列中的每个单词与其他单词结合起来,这样注意力得分就可以用来衡量单词应该重点关注序列中的哪些单词。




10


  Attention Mask

在计算注意力得分时,注意力模块会执行掩码mask操作。掩码mask有两个目的:

  • 在编码器的自注意力层以及解码器中的交叉注意力层中,掩码mask的作用是将输入句子中存在填充的注意力输出置为零,以确保填充不会影响自注意力。(注:由于输入序列可以是不同长度的,因此会像大多数 NLP处理过程一样,用填充标记对其进行扩展,以便将固定长度的向量输入Transformer)。

  • 在解码器的自注意力层中,掩码mask的作用是防止解码器在预测下一个单词时 "偷看 "目标句子中的其余部分。

解码器处理源序列中的单词,并用它们来预测目标序列中的单词。在训练过程中,解码器通过Teacher Forcing来完成这一工作,将完整的目标序列作为解码器的输入。因此,在预测某个位置的单词时,解码器可以使用该单词之前的目标单词以及该单词之后的目标单词。这使得解码器可以通过使用未来中的目标词来 "作弊"。例如,在预测 "单词 3 "时,解码器只应参考目标词的前 3 个输入词,而不应参考第 4 个单词 "Ketan"。

因此,解码器会屏蔽掉序列中当前需要预测单词后面的输入单词。

在计算注意力分数时(请参阅前面显示计算过程的图片),会在 Softmax 之前对分子进行掩码mask。屏蔽掉的元素(白色方格)被设置为负无穷大,这样 Softmax 就会将这些值变为零。




11


  输出层

解码器stack中的最后一个解码器将其输出传递给输出组件,由输出组件将其转换为最终输出句子。

全连接线性层将解码器输出向量投射到单词得分中,目标词汇中的每个单词在句子中的每个位置都有一个得分值。例如,如果我们的最终输出句子有 7 个单词,而目标西班牙语词汇有 10000 个单词,那么我们就会为这 7 个单词中的每个单词生成 10000个分值。这些分值表示词汇中的每个单词在句子该位置出现的可能性。

然后,Softmax 层会将这些分数转化为概率(和加起来为 1.0)。在每个位置上,我们会找到概率最高的单词的索引,然后将该索引映射到词汇表中的相应单词。这些词就构成了Transformer的输出序列。如下所示:





12


  计算损失

在训练过程中,我们使用损失函数(如交叉熵损失)将生成的输出概率分布与目标序列进行比较。概率分布给出了每个词在该位置出现的概率。

假设我们的目标词汇只包含四个单词。我们的目标是生成与预期目标序列 "De nada END "相匹配的概率分布。

这意味着,在第一个位置的概率分布中,"De "的概率应为 1,而词汇表中所有其他词的概率均为 0。同样,在第二个和第三个位置,"nada "和 "END "的概率应分别为 1。

像往常一样,损失被用来计算梯度,通过反向传播训练Transformer,更新其权重。




13


  结论

希望这篇文章能让大家对训练期间Transformer内部的运行机制有所了解。正如我们在上一篇文章中所讨论的,Transformer在推理过程中循环运行,但大部分处理过程保持不变。

多头注意力模块赋予了Transformer结构强大的功能。在下一篇文章中,我们将继续深入了解注意力的计算细节。


您学废了嘛?





点击上方小卡片关注我




添加个人微信,进专属粉丝群!



AI算法之道
一个专注于深度学习、计算机视觉和自动驾驶感知算法的公众号,涵盖视觉CV、神经网络、模式识别等方面,包括相应的硬件和软件配置,以及开源项目等。
 最新文章