前言:
Transformer 结构非常重要,需要认真学习一遍
1. 李沐老师课程 :
2. Transformer 论文:
3. Transformer 代码:
4. Transformer 自测题目:
5. Transformer 博客:
Transformer/BERT/实战 | 冬于的博客 (ifwind.github.io)
一.Transformer 的介绍:
Transformer 在原论文中第一次提出就是将其应用到机器翻译领域,它的出现使得机器翻译的性能和效率迈向了一个新的阶段。
它摒弃了循环结构,并完全通过注意力机制完成对源语言序列和目标语言序列全局依赖的建模。在抽取每个单词的上下文特征时,Transformer 通过自注意力机制(self-attention)衡量上下文中每一个单词对当前单词的重要程度。在这个过程当中没有任何的循环单元参与计算。这种高度可并行化的编码过程使得模型的运行变得十分高效。

二.Transformer 的结构简单介绍:

Transformer 的主要组件包括编码器(Encoder)、解码器(Decoder)和注意力层。其核心是利用多头自注意力机制(Multi-Head Self-Attention),使每个位置的表示不仅依赖于当前位置,还能够直接获取其他位置的表示。 从宏观角度来看,Transformer 的编码器是由多个相同的层叠加而成的,每个层都有两个子层(子层表示为 sublayer)。第⼀个子层是多头自注意力(multi-head self-attention)汇聚;第二个子层是基于位置的前馈网络(positionwise feed-forward network)。主要涉及到如下几个模块:
1. 嵌入表示层:

本层主要是针对输入的文本序列,将文本中的单词分别转换为其对应的向量表示的方法,即对每一个单词创建一个向量表示。 值得注意的地方是,由于 Transformer 结构中没有循环结构,因此,序列中没有提示模型单词间相互位置和前后关系的信息。在送入编码器端建模其上下文语义之前,需要在嵌入表示层进行词嵌入时加入位置编码信息Positional Encoding。 具体来说,序列中每一个单词所在的位置都对应一个向量。这一向量会与单词表示对应相加并送入到后续模块中做进一步处理。在训练的过程当中,模型会自动地学习到如何利用这部分位置信息。为了得到不同位置对应的编码,Transformer 模型使用不同频率的正余弦函数如下所示:
首先,正余弦函数的范围是在 ,导出的位置编码与原词嵌入相加不会使得结果偏离过远而破坏原有单词的语义信息。
其中,pos 表示单词所在的位置, 和 表示位置编码向量中的对应维度, 则对应位置编码的总维度。依据三角函数的基本性质,可以得知第 个位置的编码是第 个位置的编码的线性组合,这就意味着位置编码中蕴含着单词之间的距离信息。
1.1. 位置编码的线性组合
在位置编码的上下文中,线性组合意味着一个位置的编码可以通过另一个位置编码的线性变换来获得。这通常通过正弦和余弦函数实现,具体如下:
- 正弦编码: 这里,𝑃𝐸(𝑝𝑜𝑠,2𝑖)是位置 𝑝𝑜𝑠在第 2𝑖维的编码。
- 余弦编码: 这里,𝑃𝐸(𝑝𝑜𝑠,2𝑖+1) 是位置𝑝𝑜𝑠在第 2𝑖+1 维的编码。 线性组合的示例 假设我们有一个模型的维度 ,我们想要计算位置 的编码。我们可以使用以下步骤:计算缩放因子 ,对于 , , 等。
2.计算正弦和余弦编码:
对于 : .
对于
如果我们想要计算位置 的编码,比如 (即位置 4),我们可以通过将位置3的编码乘以相应的缩放因子来获得:
- 相似编码表示近位置:如果 𝑝𝑜𝑠和𝑝𝑜𝑠+𝑘 的编码非常相似,这可能意味着 𝑘 较小,即这两个位置在句子中的距离较近。
- 不同编码表示远位置:如果 𝑝𝑜𝑠和𝑝𝑜𝑠+𝑘 的编码差异较大,这可能意味着 𝑘 较大,即这两个位置在句子中的距离较远。
zhuanlan.zhihu.com/p/121126531
zhuanlan.zhihu.com/p/105001610
2. 注意力层:
2.1. 基本概念:
在 Transformer 中使用的注意力层为自注意层(Self-Attention),其在机器翻译模型中在源语言的编码和目标语言的生成中频繁地被使用以建模源语言、目标语言任意两个单词之间的依赖关系。具体的,给定由单词语义嵌入及其位置编码叠加得到的输入表示 ,为了实现对上下文语义依赖的建模,进一步引入在自注意力机制中涉及到的三个元素:查询 ,键 ,值 。在编码输入序列中每一个单词的表示的过程中,这三个元素用于计算上下文单词所对应的权重得分。直观地说,这些权重反映了在编码当前单词的表示时,对于上下文不同部分所需要的关注程度。
为了得到编码单词 时所需要关注的上下文信息,通过位置 查询向量与其他位置的键向量做点积得到匹配分数:
为了防止过大的匹配分数在后续 Softmax 计算过程中导致的梯度爆炸以及收敛效率差的问题,这些得分会除放缩因子 以稳定优化。放缩后的得分经过 Softmax 归一化为概率之后,与其他位置的值向量相乘来聚合希望关注的上下文信息,并最小化不相关信息的干扰。上述计算过程可以被形式化地表述如下:
其中 , , 分别表示输入序列中的不同单词的 向量拼接组成的矩阵, 表示序列长度, 表示自注意力操作的输出。

2.2. 操作过程:
对于输入的文本的表示矩阵 X,实际上,自注意力机制中涉及到的三个元素:查询 ,键 ,值 ,是由同样的输入矩阵X线性变换而来的。我们可以简单理解成:,其可以用图像表示为:

X 矩阵中的每一行都对应输入句子中的一个单词,W 矩阵为权重矩阵。在了解以上内容后计算自注意力。
2.2.1. 创建三个向量:
根据编码器的每个输入向量(在本例中为每个单词的嵌入 )创建三个向量 。即为每个单词创建一个查询向量、一个关键向量和一个值向量。请注意,这些新向量的维度比嵌入向量小。它们的维度为 64,而嵌入和编码器输入输出向量的维度为 512。
具体操作为:将 x1 与 WQ 权重矩阵相乘,得出 q1,即与该词相关的 "查询 "向量。最终,我们为输入句子中的每个单词创建了一个 "查询"、一个 "关键 "和一个 "值 "投影。

2.2.2. 计算得分:
假设我们要计算本例中第一个单词 "Thinking "的自注意力。我们需要将输入句子中的每个单词与这个单词进行对比。分数决定了我们在对某个位置的单词进行编码时,对输入句子中其他部分的关注程度。
分数的计算方法是将查询向量与我们要评分的单词的关键向量进行点乘。比如,如果我们处理的是 1 号位置单词的自注意力,那么第一个分数就是 和 的点积。第二个分数是 和 的点积。

2.2.3. 处理得分:
将得分按照公式除以放缩因子 以稳定优化,一般 是键的维度。,进行缩放后使用 softmax 运算进行归一化处理:
这个 softmax 分数决定了每个词在这个位置的表达量。显然,这个位置上的单词将拥有最高的 softmax 分数,但有时也可以用于关注与当前单词相关的另一个单词。
2.2.4. 处理选择值向量:
将每个值向量乘以 softmax 分数(准备求和)。这里主要是保持我们想要关注的单词的值不变,而忽略无关的单词(例如得分为 0.001 这样的小数的单词)。
将加权值向量相加。这将产生自注意层在该位置(第一个单词)的输出。

aicarrier.feishu.cn/wiki/SyROwp…
注意力机制到底在做什么,Q/K/V怎么来的?一文读懂Attention注意力机制-腾讯云开发者社区-腾讯云 (tencent.com)
3. 前馈层:

前馈层接受自注意力子层的输出作为输入,并通过一个带有 Relu 激活函数的两层全连接网络对输入进行更加复杂的非线性变换。实验证明,这一非线性变换会对模型最终的性能产生十分重要的影响。
其中 表示前馈子层的参数。另外,以往的训练发现,增大前馈子层隐状态的维度有利于提升最终翻译结果的质量,因此,前馈子层隐状态的维度一般比自注意力子层要大。
4. 残差连接与归一化:
由 Transformer 结构组成的网络结构通常都是非常庞大。编码器和解码器均由很多层基本的Transformer 块组成,每一层当中都包含复杂的非线性映射,这就导致模型的训练比较困难。因此,研究者们在 Transformer 块中进一步引入了残差连接与层归一化技术以进一步提升训练的稳定性。具体来说,残差连接主要是指使用一条直连通道直接将对应子层的输入连接到输出上去(这里可以类比残差神经网络的残差快来帮助理解),从而避免由于网络过深在优化过程中潜在的梯度消失问题:
其中 表示第层的输入, 表示一个映射函数。此外,为了进一步使得每一层的输入输出范围稳定在一个合理的范围内,层归一化技术被进一步引入每个 Transformer 块的当中:
其中 和 分别表示均值和方差,用于将数据平移缩放到均值为 0,方差为 1 的标准分布, 和 是可学习的参数。层归一化技术可以有效地缓解优化过程中潜在的不稳定、收敛速度慢等问题。 图解Transformer系列三:Batch Normalization & Layer Normalization (批量&层标准化) - 掘金 (juejin.cn)
5. 编码器和解码器结构:
根据给出的网络架构,编码器端可以较为容易实现。但相比于编码器端,解码器端要更复杂一些。具体来说,解码器的每个 Transformer 块的第一个自注意力子层额外增加了注意力掩码),对应图中的掩码多头注意力(Masked Multi-Head Attention)部分。这主要是因为在翻译的过程中,编码器端主要用于编码源语言序列的信息,而这个序列是完全已知的,因而编码器仅需要考虑如何融合上下文语义信息即可。而解码端则负责生成目标语言序列,这一生成过程是自回归的,即对于每一个单词的生成过程,仅有当前单词之前的目标语言序列是可以被观测的,因此这一额外增加的掩码是用来掩盖后续的文本信息,以防模型在训练阶段直接看到后续的文本序列进而无法得到有效地训练。
此外,解码器端还额外增加了一个 多头注意力(Multi-Head Attention)模块,使用交叉注意力(Cross-attention)方法,同时接收来自编码器端的输出以及当前 Transformer 块的前一个掩码注意力层的输出。查询是通过解码器前一层的输出进行投影的,而键和值是使用编码器的输出进行投影的。它的作用是在翻译的过程当中,为了生成合理的目标语言序列需要观测待翻译的源语言序列是什么。基于上述的编码器和解码器结构,待翻译的源语言文本,先经过编码器端的每个Transformer 块对其上下文语义的层层抽象,然后输出每一个源语言单词上下文相关的表示。解码器端以自回归的方式生成目标语言文本,即在每个时间步 t ,根据编码器端输出的源语言文本表示,以及前 t-1 个时刻生成的目标语言文本,生成当前时刻的目标语言单词。