【Transformer】超全详解!
Transformer 与 RNN 不同,可以比较好地并行训练。Transformer 本身是不能利用单词的顺序信息的,因此需要在输入中添加位置 Embedding,否则 Transformer 就是一个词袋模型了。Transformer 的重点是 Self-Attention 结构,其中用到的Q, K, V矩阵通过输出进行线性变换得到。
0、Transformer整体结构

Transformer 的整体结构,左Encoder和右Decoder
Transformer 由 Encoder 和 Decoder 两个部分组成,Transformer 的工作流程大体如下:
第一步:获取输入句子的每一个单词的表示向量 X,X由单词的 Embedding(Embedding就是从原始数据提取出来的Feature) 和单词位置的 Embedding 相加得到。
Transformer 的输入表示
第二步:将得到的单词表示向量矩阵 (如上图所示,每一行是一个单词的表示 x) 传入 Encoder 中,经过 6 个 Encoder block 后可以得到句子所有单词的编码信息矩阵 C,如下图。n 是句子中单词个数,d 是表示向量的维度 (attention is all you need论文中 d=512)。每一个 Encoder block 输出的矩阵维度与输入完全一致。

Transformer Encoder 编码句子信息
第三步:将 Encoder 输出的编码信息矩阵 C 传递到 Decoder 中,Decoder 依次会根据当前翻译过的单词 1~ i 翻译下一个单词 i+1,如下图所示。在使用的过程中,翻译到单词 i+1 的时候需要通过 Mask (掩盖) 操作遮盖住 i+1 之后的单词。

Transofrmer Decoder 预测
上图 Decoder 接收了 Encoder 的编码矩阵 C,然后首先输入一个翻译开始符 "<Begin>",预测第一个单词 "I";然后输入翻译开始符 "<Begin>" 和单词 "I",预测单词 "have",以此类推。这是 Transformer 使用时候的大致流程,接下来是里面各个部分的细节。
一、Input
Transformer 中单词的输入表示 x由单词 Embedding 和位置 Embedding (Positional Encoding)相加得到。

Transformer 的输入表示
1.1 单词 Embedding
首先要对输入的单词进行编码,怎么编码呢?

上图直接编码的方式存在很多问题。所以人们想到了one-hot编码(下图左),但是这种编码方式无法表示单词间的相关性,且大部分位置上都是0,浪费存储空间。我们想要的的word embedding 方法是可以将相关性较强的单词映射到相似的空间位置(比如右图中绿色点均为动物,红色点均为植物),且表示向量是dense的。

这种单词的 Embedding 有很多种方式可以获取,例如可以采用 Word2Vec、Glove 等算法预训练得到,也可以在 Transformer 中训练得到。【详见表示学习】
2.2 位置 Embedding
Transformer 中除了单词的 Embedding,还需要使用位置 Embedding 表示单词出现在句子中的位置。因为 Transformer 不采用 RNN 的结构(RNN 是一种顺序模型,它通过一个个单词的顺序来处理信息,能够捕捉到单词之间的时间依赖关系),然而,Transformer 采用的是自注意力机制(self-attention),它可以在处理输入时同时考虑整个序列中的所有单词。这种机制使得模型能够捕捉到全局信息,但也导致了一个问题:单词的顺序信息在处理时没有利用。而这部分信息对于 自然语言处理来说非常重要。所以 Transformer 中使用位置 Embedding 保存单词在序列中的相对或绝对位置。
位置 Embedding 用 PE表示,PE 的维度与单词 Embedding 是一样的。PE 可以通过训练得到,也可以使用某种公式计算得到。
直观思考,要想给输入的向量添加位置信息, 最先想到的无疑就是直接使用1 , 2 , 3 , . . . , n 这样的连续数字给输入向量赋予标号来表达向量的顺序。但是这样会导致一些问题:
- 如果模型没有见过比训练时更大的整数标记(如 101、102 等),它很难推断这些数字与已知位置标记(如 1 到 100 )之间的关系,导致外推能力不足
- 当序列长度不断增大, 其位置标记也会越来越大, 不利于训练
所以进一步, 可以想将上面的位置标记进行归一化, 其中0表示第一个单词,1表示最后一个单词。这样就可以解决上面两个问题, 但是这样又会导致一些问题:
- 模型难以捕捉相对位置关系: 例如,标记值 0.5在长度为 3 的序列中表示第 2 个位置,但在长度为 7 的序列中表示第 4 个位置。
- 如果序列长度较长,[ 0 , 1 ] 范围内的连续分布可能导致相邻位置之间的差异非常小。

故而, 我们需要这样一种编码:
- 每个位置的编码值应该唯一
- 输入向量长度不同时, 其中每个分量间的相对距离保持一致
- 编码范围有界, 不会随输入向量长度增大而无限增大
在 Transformer 中采用了不同频率的正弦和余弦函数:
其中,pos 表示单词在句子中的位置,i是维度。d 表示 PE的维度 (与词 Embedding 一样),2i 表示偶数的维度,2i+1 表示奇数维度 (即 2i≤d, 2i+1≤d)。我们选择这个函数是因为我们假设它允许模型轻松学习关注相对位置,因为对于任何固定的偏移量 k,PEpos+k 可以表示为 PEpos 的线性函数。
那么为什么采用正余弦函数呢?详细解释见【Transformer】位置embedding的理解-CSDN博客
将单词的词 Embedding 和位置 Embedding 相加,就可以得到词的表示向量 x,x 就是 Transformer 的输入。那为什么位置编码是和词嵌入向量是相加而不是将二者拼接起来?

二、Encoder 结构

上图红色部分是 Transformer 的 Encoder block 结构,可以看到是由 Multi-Head Attention, Add & Norm, Feed Forward, Add & Norm 组成的。
在Transformer模型中,Encoder是由6个完全相同的Encoder组成。每个Encoder主要由两个layers组成,分别是multi-head self-attention mechanism和fully connected feed-forward network。其中,multi-head self-attention mechanism允许模型关注输入序列中的不同部分,而fully connected feed-forward network则负责进一步处理这些信息。
Multi-Head Attention 的计算过程详见笔记,
attention机制 的详细解释详见【Attention终于搞懂了】注意力机制/自注意力/多头注意力 构件详解_自注意力机制qkv-CSDN博客
现在了解一下 Add & Norm 和 Feed Forward 部分。
2.1 Add & Norm
Add & Norm 层由 Add 和 Norm 两部分组成,其计算公式如下:
由图,其中 X表示 Multi-Head Attention 或者 Feed Forward 的输入,MultiHeadAttention(X) 和 FeedForward(X) 表示输出 (输出与输入 X 维度是一样的,所以可以相加)。
Add指 X+MultiHeadAttention(X),是一种残差连接,通常用于解决多层网络训练的问题,可以让网络只关注当前差异的部分,在 ResNet 中经常用到:

残差连接
残差连接的核心思想是在网络的一层或多层之间引入直接连接,使得这些层的输出不仅包括经过非线性变换的特征,还包括未经处理的输入特征。这样做的目的是允许神经网络学习到的是输入和输出之间的残差(即差异),而不是直接学习一个完整的映射。这种方式有助于梯度在训练过程中更有效地回流,减轻深度网络中梯度消失的问题。
Norm指 Layer Normalization,通常用于 RNN 结构,Layer Normalization 会将每一层神经元的输入都转成均值方差都一样的,这样可以加快收敛。
LN是对hidden的维度去做归一化,也就是针对单个样本的不同特征做操作。因此LN可以不受样本数的限制。
具体而言,LN就是在每个样本上统计所有维度的值,计算均值和方差(注意,这里都是指的简单的MLP情况,输入特征是(bsz,hidden_dim))。所以LN是每个样本的分布是稳定的。
细节详见【Transformer】Add & Norm的理解-CSDN博客
2.2 Feed Forward
Feed Forward 层比较简单,是一个两层的全连接层,第一层的激活函数为 Relu,第二层不使用激活函数,对应的公式如下。
![]()
X是输入,Feed Forward 最终得到的输出矩阵的维度与X一致。
FeedForward的输入是什么呢?是Multi-Head Attention的输出做了残差连接和Norm之后得数据。
具体来说,Transformer中的前馈神经网络层( FeedForward ) 通常包括两个线性变换和一个非线性激活函数(如ReLU)。
第一个线性变换将输入映射到更高维度的空间,并引入非线性;
第二个线性变换则将输出映射回与输入相同的维度(或兼容的维度),通常不引入额外的非线性。
细节详见 【Transformer】Feed Forward的理解-CSDN博客
2.3 组成 Encoder
通过上面描述的 Multi-Head Attention, Fed Forward, Add & Norm 就可以造出一个 Encoder block,Encoder block 接收输入矩阵 ,并输出一个矩阵
。通过多个 Encoder block 叠加就可以组成 Encoder。
第一个 Encoder block 的输入为句子单词的表示向量矩阵,后续 Encoder block 的输入是前一个 Encoder block 的输出,最后一个 Encoder block 输出的矩阵就是编码信息矩阵 C,这一矩阵后续会用到 Decoder 中。

Encoder 编码句子信息
Transformer模型中的6个Encoder并不是孤立存在的,它们会按照顺序,依次处理输入的序列。具体来说,第一个Encoder会处理原始的输入序列,得到一个初步的表示形式。然后,这个表示形式会被送入第二个Encoder,进行更深层次的处理。以此类推,直到最后一个Encoder。
在这个过程中,每个Encoder都会利用multi-head self-attention mechanism和fully connected feed-forward network,对输入进行深入的挖掘和处理。同时,由于每个Encoder都有residual connection和normalization,因此可以确保信息的有效传递,避免梯度消失或爆炸的问题。
三、Decoder 结构

Transformer Decoder block
上图红色部分为 Transformer 的 Decoder block 结构,与 Encoder block 相似,但是存在一些区别:
- 包含两个 Multi-Head Attention 层。
- 第一个 Multi-Head Attention 层采用了 Masked 操作。
- 第二个 Multi-Head Attention 层的K, V矩阵使用 Encoder 的编码信息矩阵C进行计算,而Q使用上一个 Decoder block 的输出计算。
- 最后有一个 Softmax 层计算下一个翻译单词的概率。
3.1 解码器架构
Transformer的解码器主要由多层相同的解码器层堆叠而成,每层包含三个主要子组件:自注意力层(也称为掩码自注意力层)、编码器-解码器注意力层和前馈神经网络层。这些组件通过残差连接和层归一化进行连接,以确保信息的有效传递和模型的稳定性。
- 自注意力层:与编码器中的自注意力层类似,解码器的自注意力层也采用了多头注意力机制。但解码器在自注意力层中引入了掩码机制(Masked Self-Attention),以防止模型在生成序列时看到未来的信息。这种设计确保了模型在预测当前位置的输出时,只能依赖于已生成的输出序列和编码器的输出。
- Encoder-Decoder交互注意力层:在这一层中,解码器将自注意力层的输出作为查询(Query),编码器的输出作为键(Key)和值(Value)。通过这种方式,解码器能够关注并整合编码器中与当前预测任务最相关的信息,从而生成更准确的输出。
- 前馈神经网络层(feed forward):这是一个简单的全连接网络,用于对编码器-解码器注意力层的输出进行进一步的非线性变换。通过堆叠多个这样的前馈神经网络层,解码器能够捕捉到更复杂的特征表示,提高模型的预测能力。
3.2 自注意力层——第一个 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 并且并行化训练,即将正确的单词序列 ( I have a cat) 和对应输出 (I have a cat ) 传递到 Decoder。那么在预测第 i 个输出时,就要将第 i+1 之后的单词掩盖住,注意 Mask 操作是在 Self-Attention 的 Softmax 之前使用的,下面用 0 1 2 3 4 5 分别表示 " I have a cat "。
第一步:是 Decoder 的输入矩阵和 Mask 矩阵,输入矩阵包含 " I have a cat" (0, 1, 2, 3, 4) 五个单词的表示向量,Mask 是一个 5×5 的矩阵。在 Mask 可以发现单词 0 只能使用单词 0 的信息,而单词 1 可以使用单词 0, 1 的信息,即只能使用之前的信息。

输入矩阵与 Mask 矩阵
第二步: 接下来的操作和之前的 Self-Attention 一样,通过输入矩阵X计算得到Q,K,V矩阵。然后计算Q和 的乘积
。

Q乘以K的转置
第三步: 在得到 之后需要进行 Softmax,计算 attention score,我们在 Softmax 之前需要使用Mask矩阵遮挡住每一个单词之后的信息,遮挡操作如下:

Softmax 之前 Mask
得到 Mask 之后在 Mask
上进行 Softmax,每一行的和都为 1。但是单词 0 在单词 1, 2, 3, 4 上的 attention score 都为 0。
第四步:使用 Mask 与矩阵 V相乘,得到输出 Z,则单词 1 的输出向量
是只包含单词 1 信息的。

Mask 之后的输出
第五步: 通过上述步骤就可以得到一个 Mask Self-Attention 的输出矩阵,然后和 Encoder 类似,通过 Multi-Head Attention 拼接多个输出
然后计算得到第一个 Multi-Head Attention 的输出Z,Z与输入X维度一样。
自注意力层(Self-Attention Layer)功能:
- 捕捉解码器内部的依赖关系:自注意力层允许解码器在生成每个目标单词时,关注之前生成的单词。这意味着每个单词的表示可以基于其前面的单词动态调整,从而捕捉到序列内部的上下文信息。
必要性:
- 保持上下文一致性:在生成序列时,当前单词的生成不仅依赖于编码器的输出,还依赖于之前生成的单词。自注意力层确保了解码器能够有效地利用这些历史信息,保持生成的上下文一致性。
- 防止信息泄露:自注意力层通常会使用掩码(masking)机制,确保在生成当前单词时,只能关注之前的单词,而不能看到未来的单词。这种设计是为了保持自回归生成的特性,确保模型在生成时遵循序列的顺序。
3.2 Encoder-Decoder交互注意力层——第二个 Multi-Head Attention
Decoder block 第二个 Multi-Head Attention 变化不大, 主要的区别在于其中 Self-Attention 的 K, V矩阵不是使用 上一个 Decoder block 的输出计算的,而是使用 Encoder 的编码信息矩阵 C 计算的。

根据 Encoder 的输出 C计算得到 K, V,根据上一个 Decder block 的输出 Z 计算 Q (如果是第一个 Decoder block 则使用输入矩阵 X 进行计算),后续的计算方法与之前描述的一致。

这样做的好处是在 Decoder 的时候,每一位单词都可以利用到 Encoder 所有单词的信息 (这些信息无需 Mask)。
交互注意力层(Cross-Attention Layer)的目的
交互注意力层的主要目的是在解码过程中动态地选择和聚焦于源序列中最相关的信息。具体来说:
动态关注:通过将解码器的输出(Q)与编码器的输出(K)进行比较,模型能够动态地确定在生成当前目标单词时,应该关注源文本中的哪些单词。这种机制使得模型能够根据上下文灵活调整注意力分配。
信息传递:K和V都是来自编码器的输出,确保了源序列的信息能够被有效地传递到解码器。通过对K的查询(Q),解码器能够获取与当前生成任务最相关的源信息。
必要性:
- 信息传递:在序列到序列的任务中(如机器翻译),解码器需要依赖编码器提供的上下文信息。交互注意力层确保了解码器能够有效地利用这些信息。
- 生成上下文:交互注意力层使得解码器能够在生成每个目标单词时,基于当前的解码状态和编码器的输出,选择最相关的源信息,从而提高生成的准确性和流畅性。
3.3 Feed Forward
与在编码器层中的相同
3.4 Softmax 预测输出单词
Decoder block 最后的部分是利用 Softmax 预测下一个单词,在之前的网络层我们可以得到一个最终的输出 Z,因为 Mask 的存在,使得单词 0 的输出 Z0 只包含单词 0 的信息,如下:

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

Decoder Softmax 预测
这就是 Decoder block 的定义,与 Encoder 一样,Decoder 是由多个 Decoder block 组合而成。
四、Transformer 总结
- Transformer 与 RNN 不同,可以比较好地并行训练。
- Transformer 本身是不能利用单词的顺序信息的,因此需要在输入中添加位置 Embedding,否则 Transformer 就是一个词袋模型了。
- Transformer 的重点是 Self-Attention 结构,其中用到的 Q, K, V矩阵通过输出进行线性变换得到。
- Transformer 中 Multi-Head Attention 中有多个 Self-Attention,可以捕获单词之间多种维度上的相关系数 attention score。
- 自注意力层:主要用于处理输入序列内部的依赖关系,捕捉上下文信息,适用于编码器和解码器的自注意力计算。
- 交互注意力层:用于连接编码器和解码器,确保解码器能够动态地选择和利用编码器的输出信息。
reference:
Transformer模型详解(图解最完整版) - kongen - 博客园
位置编码: Position Embedding-CSDN博客
Transformer中的归一化(五):Layer Norm的原理和实现 & 为什么Transformer要用LayerNorm - 知乎
更多推荐


所有评论(0)