Transformer 模型详解
1. Transformer 概览
2017 年,Google 在论文 Attention is All You Need 中提出了 Transformer 模型。Transformer 使用了 Self-Attention(自注意力) 机制,取代了在 NLP 任务中常用的 RNN。这一创新使得模型能够高效进行并行计算,并且显著提高长序列依赖问题的处理能力。
下图展示了 Transformer 的完整结构:
![图片[1]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/67702677d0e0a243d4ec02cb.png)
1.1 Transformer 结构概览
Transformer 主要基于 Encoder-Decoder 框架构建,整体可以分为以下两个主要组件:
- Encoder(编码器): 用于对输入数据进行特征提取。
- Decoder(解码器): 根据输入和编码器的输出生成目标序列。
如下图示例,Transformer 在机器翻译任务中的输入是一段法语,输出则是对应的英语句子。
![图片[2]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/6770268ad0e0a243d4ec02cf.png)
编码器和解码器的层级结构如下:
![图片[3]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/6770269dd0e0a243d4ec02d3.png)
其中,编码组件由多层编码器(Encoder)组成(在论文中作者使用了 6 层编码器,在实际使用过程中你可以尝试其他层数)。解码组件也是由相同层数的解码器(Decoder)组成(在论文也使用了 6 层)。如下图所示:
![图片[4]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677026aad0e0a243d4ec02d5.png)
每个编码器由两个子层组成:Self-Attention 层(自注意力层)和 Position-wise Feed Forward Network(前馈网络,缩写为 FFN)如图 1.5 所示。每个编码器的结构都是相同的,但是它们使用不同的权重参数。
![图片[5]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677026b4d0e0a243d4ec02d7.png)
编码器的输入会先流入 Self-Attention 层。它可以让编码器在对特定词进行编码时使用输入句子中的其他词的信息(可以理解为:当我们翻译一个词时,不仅只关注当前的词,而且还会关注其他词的信息)。后面我们将会详细介绍 Self-Attention 的内部结构。然后,Self-Attention 层的输出会流入前馈网络。
解码器也有编码器中这两层,但是它们之间还有一个注意力层(即 Encoder-Decoder Attention),其用来帮助解码器关注输入句子的相关部分(类似于 seq2seq 模型中的注意力)。
![图片[6]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677026d4d0e0a243d4ec02e0.png)
1.2 引入张量
我们已经知道了模型由Encoder-Decoder架构构成,让我们开始研究各种张量以及他们的流动吧!要知道深度学习玩的就是shape。
和通常的NLP任务一样,我们使用词嵌入(Words to Embeddings)将每个词转为一个词向量。在Transformer中,词嵌入向量的dim为512。
![图片[7]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677026ddd0e0a243d4ec02e3.png)
嵌入操作仅仅是发生在最底层的Encoder中,所有的编码器都会接收到一个维度为512的向量(底层编码器接受的是词嵌入的向量,其他编码器接受的对应上一个编码器的输出)。
对输入序列完成词嵌入后,每个词都会流经编码器的Self-Attention Layer与Feed Forward Layer。
![图片[8]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677026e5d0e0a243d4ec02e4.png)
接下来,我们换一个更短的句子作为示例,来说明在编码器中每个子层中发生了什么。
比如这一句Thinking Machines,首先进入Self-Attention Layer中,使得每一个token会考虑其他的token,接着进入Feed Forward Layer,得到新的输出,并送入下一个编码器。
1.3 自注意力机制(Self-Attention)
1.3.1 Self-Attention 概述
让我们通过一个简单句子 “The animal didn’t cross the street because it was too tired”,来理解 Self-Attention 的基本概念:
- 在这里,"it" 到底指代 “animal” 还是 “street” 呢?对于人来说,这是个简单的问题,但是对于机器而言这并不容易。
- Self-Attention 的目标是学会捕捉句子中的这种对应关系,比如这里,Self-Attention会将
it和animal关联起来。
当模型处理每个词(输入序列中的每个位置)时,Self-Attention 机制使得模型不仅能够关注当前位置的词,而且能够关注句子中其他位置的词,从而可以更好地编码这个词。
通过 Transformer 的 Self-Attention,模型可以捕捉句子中某个词对其他词的重要性。例如:
![图片[10]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677026fdd0e0a243d4ec02e6.png)
1.3.2 Self-Attention 的计算过程
Self-Attention 的核心是计算输入序列中所有词汇之间的相关性,其基本结构如下图所示:
![图片[11]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/67702706d0e0a243d4ec02e8.png)
对于 Self-Attention 来讲,Q(Query) K(Key)和 V(Value)三个矩阵均来自同一输入,并按照以下步骤计算:
- 首先计算 ( Q ) 和 ( K ) 之间的点积。为了防止其结果过大,会除以 ( $\sqrt{d_k}$ ),其中 ( $d_k $) 为 Key 向量的维度。
- 然后利用 Softmax 操作将结果归一化为概率分布,再乘以矩阵 V 就得到了加权求和的表示。
整个计算过程可以表示为:
$$
Attention(Q, K, V) = \text{softmax}\left(\frac{QK^{T}}{\sqrt{d_k}}\right)V
$$
为了更好地理解 Self-Attention,下面我们通过具体的例子进行详细说明。
1.3.3 Self-Attention 详解
下面通过一个例子,让我们看一下如何使用向量计算 Self-Attention。计算 Self-Attention 的步骤如下:
第 1 步:
对编码器的每个输入向量(在本例中,即每个词的词向量)创建三个向量:Query 向量、Key 向量 和 Value 向量。
它们是通过词向量分别和 3 个矩阵相乘得到的,这 3 个矩阵通过训练获得。
请注意,这些向量的维数小于词向量的维数。例如,新向量的维数为 64,而词嵌入(Embedding)和编码器输入/输出向量的维数为 512。新向量不一定非要更小,这样做是为了使多头注意力计算保持一致的结构特性。
图解示意:
- Input:输入序列由词语 "Thinking" 和 "Machines" 构成,其对应的词嵌入为 $x_1$ 和 $x_2$。
- Queries (Q):通过权重矩阵 $W^Q$ 计算得到对应的 Query 值 $q_1$ 和 $q_2$。
- Keys (K):通过权重矩阵 $W^K$ 计算得到对应的 Key 值 $k_1$ 和 $k_2$。
- Values (V):通过权重矩阵 $W^V$ 计算得到对应的 Value 值 $v_1$ 和 $v_2$。
![图片[12]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/67702711d0e0a243d4ec02f1.png)
在上图中:
- $x_1$ 乘以权重矩阵 $W^Q$ 得到 $q_1$,即与该单词关联的 Query 向量。
- 最终每个单词的输入都会生成一个 Query 向量、一个 Key 向量和一个 Value 向量。
什么是 Query、Key 和 Value 向量?
它们是抽象表示,对于注意力的计算和思考非常有用。请继续阅读后文,理解这些向量在注意力分配中的作用。
第 2 步:
计算注意力分数。假设我们正在计算这个例子中第一个词 “Thinking” 的自注意力。我们需要根据 “Thinking” 这个词,对句子中的每个词都计算一个分数。这些分数决定了我们在编码 “Thinking” 这个词时,需要对句子中其他位置的每个词放置多少的注意力。
这些分数,是通过计算 “Thinking” 的 Query 向量和需要评分的词的 Key 向量的点积得到的。
如果我们计算句子中第一个位置词的注意力分数,则第一个分数是 $q_1$ 和 $k_1$ 的点积,第二个分数是 $q_1$ 和 $k_2$ 的点积。
![图片[13]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/67702730d0e0a243d4ec02fa.png)
这些 Softmax 分数决定了在编码当前位置的词时,对所有位置的词分别有多少的注意力。很明显,当前位置的词汇有最高的分数,但有时注意一下与当前位置的词相关的词是很有用的。
第 3 步:
将每个分数除以 $\sqrt{d_k}$($d_k$ 是 Key 向量的维度)。
目的是在反向传播时,求梯度更加稳定。实际上,你也可以除以其他数。
第 4 步:
将这些分数进行 Softmax 操作。Softmax 将分数进行归一化处理,使得它们均为正数且和为 1。
![图片[14]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/6770279cd0e0a243d4ec02ff.png)
这些 Softmax 分数决定了在编码当前位置的词时,对所有位置的词分别有多少的注意力。
很明显,当前位置的词汇有最高的分数,但有时注意与当前位置的词相关的词是很有用的。
第 5 步:
将每个 Softmax 分数分别与每个 Value 向量相乘。这种做法背后的直觉理解是:
- 对于分数高的位置,相乘后的值就越大,我们把更多的注意力放在它们身上;
- 对于分数低的位置,相乘后的值就越小,这些位置的词可能跟相关性不大,我们就可以忽略这些位置的词。
第 6 步:
将加权后的 Value 向量(即上一步求得的向量)求和。这样就得到了自注意力层在这个位置的输出。
计算过程:
- Input:
- Embedding: $x_1$, $x_2$
- Queries: $q_1$, $q_2$
- Keys: $k_1$, $k_2$
- Values: $v_1$, $v_2$
- Score:
- $q_1 \cdot k_1 = 112$
- $q_1 \cdot k_2 = 96$
- Divide: 除以 $8 (\sqrt{d_k})$:
- 对应计算 $14$ 和 $12$
- Softmax:
- $0.88$ 和 $0.12$
- Softmax X Value:
- 用 Softmax 分数分别加权 $v_1$ 和 $v_2$
最终求和后:
- Output: 输出向量 $z_1$, $z_2$
![图片[15]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677027b2d0e0a243d4ec0306.png)
这样就完成了自注意力的计算。生成的向量会输入到前馈神经网络中。但是在实际实现中,此计算是以矩阵形式进行,以便实现更快的处理速度。下面我们来看看看如何使用矩阵计算。
1.3.4 使用矩阵计算 Self-Attention
第 1 步:
计算 Query、Key 和 Value 矩阵。首先,将所有词向量放到一个矩阵 $X$ 中,然后分别和 3 个我们训练过的权重矩阵($W^Q$、$W^K$ 和 $W^V$)相乘,得到 $Q$、$K$ 和 $V$ 矩阵。
![图片[16]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677027bcd0e0a243d4ec0307.png)
矩阵 $X$ 中的每一行,表示输入句子中的每一个词的词向量(长度为 512,在图中为 4 个方框)。矩阵 $Q$、$K$ 和 $V$ 中的每一行,分别表示 Query 向量、Key 向量和 Value 向量(它们的长度都为 64,在图中为 3 个方框)。
第 2 步:
计算自注意力。由于这里使用了矩阵进行计算,可以将前面的第 2 步到第 6 步压缩为一步。
![图片[17]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677027c3d0e0a243d4ec030c.png)
1.4 多头注意力机制 (Multi-head Attention)
在 Transformer 论文中,通过添加一种多头注意力机制,进一步完善了自注意力层。具体做法:
首先,通过 $h$ 个不同的线性变换对 Query、Key 和 Value 进行映射;
然后,将不同的 Attention 拼接起来;
最后,再进行一次线性变换。基本结构如下图所示:
![图片[18]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677027ccd0e0a243d4ec030d.png)
每一组注意力用于将输入映射到不同的子表示空间,这使得模型可以在不同子表示空间中关注不同的位置。整个计算过程可表示为:
$$
\text{MultiHead}(Q, K, V) = \text{Concat}(\text{head}_1, \cdots, \text{head}_h) W^O
$$
$$
\text{head}_i = \text{Attention}(Q W_i^Q, K W_i^K, V W_i^V)
$$
其中:
- $W_i^Q \in \mathbb{R}^{d_{\text{model}} \times d_k}$
- $W_i^K \in \mathbb{R}^{d_{\text{model}} \times d_k}$
- $W_i^V \in \mathbb{R}^{d_{\text{model}} \times d_v}$
- $W^O \in \mathbb{R}^{h d_v \times d_{\text{model}}}$
在论文中,指定 $h = 8$(即使用 8 个注意力头)且 $d_k = d_v = \frac{d_{\text{model}}}{h} = 64$
在多头注意力下,我们将注意力单独维持不同的 Query、Key 和 Value 权重矩阵,从而得到不同的 Query、Key 和 Value 矩阵。如前所述,我们将 $X$ 乘以 $W^Q$、$W^K$ 和 $W^V$ 矩阵,得到 Query、Key 和 Value 矩阵。
![图片[19]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677027d4d0e0a243d4ec030e.png)
按照上面的方法,使用不同的权重矩阵进行 8 次自注意力计算,就可以得到 8 个不同的 $Z$ 矩阵。
![图片[20]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677027dcd0e0a243d4ec030f.png)
因为前馈神经网络层接收的是一个矩阵(每个词的词向量),而不是上面的8个矩阵。因此,我们需要一种方法将这8个矩阵整合为1个矩阵。具体方法为:
-
把 8 个矩阵 ${Z_0, Z_1, \cdots, Z_7}$ 拼接起来。
-
把拼接后的矩阵和一个权重矩阵 $W^O$ 相乘。
-
得到最终的矩阵 $Z$,这个矩阵包含了所有注意力头的信息。这个矩阵会输入到 FFN 层。
![图片[21]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677027e3d0e0a243d4ec0312.png)
下面是多头注意力的整个过程:
![图片[22]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677027edd0e0a243d4ec0313.png)
现在让我们重新回顾一下前面的例子,看看在对示例句中的“it”进行编码时,不同的注意力头关注的位置分别在哪:
![图片[23]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677027f7d0e0a243d4ec0315.png)
当我们对“it”进行编码时,一个注意力头关注“The animal”,另一个注意力头关注“tired”。从某种意义上来说,模型对“it”的表示,融入了“animal”和“tired”的部分表达。
Multi-head Attention 的本质是,在参数总量保持不变的情况下,将同样的 Query,Key,Value 映射到原来的高维空间的不同子空间中进行 Attention 的计算,在最后一步再合并不同子空间中的 Attention 信息。这样降低了计算每个 head 的 Attention 时每个向量的维度,在某种意义上防止了过拟合;由于 Attention 在不同子空间中有不同的分布,Multi-head Attention 实际上是寻找了序列之间不同角度的关联关系,并在最后拼接这一步骤中,将不同子空间中捕获到的关联关系再综合起来。
1.5 位置前馈网络 (Position-wise Feed-Forward Networks)
位置前馈网络就是一个全连接前馈网络,每个位置的词都会经过这个完全相同的前馈神经网络。其由两个线性变换组成,即两个全连接层组成,第一个全连接层的激活函数为 ReLU 激活函数。
可以表示为:
$$
FFN(x) = \max(0, xW_1 + b_1)W_2 + b_2
$$
在每个编码器和解码器中,虽然这个全连接前馈网络结构相同,但不共享参数。整个前馈网络的输入和输出维度都是 $d_{\text{model}}=512$ ,第一个全连接层的输出和第二个全连接层的输入维度为 $d_{\text{ff}}=2048$ 。
1.6 残差连接和层归一化
编码器结构中有一个需要注意的细节:每个编码器的每个子层(Self-Attention层和FFN层)都有一个残差连接,再执行一个层标准化的操作的,整个计算过程可以表示为:
$$
subLayerOutput = LayerNorm(x + SubLayer(x))
$$
![图片[24]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/6770c8c5d0e0a243d4ec0d1d.png)
将向量和自注意力层的层标准化操作可视化:
![图片[25]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/6770c9bdd0e0a243d4ec0d5a.png)
上面的操作也适用于解码器的子层。假设一个Transformer是由两层编码器和两层解码器组成,如下图所示:
![图片[26]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/6770cabad0e0a243d4ec0dc0.png)
为了方便进行残差连接,编码器和解码器中的所有子层和嵌入层的输出维度需要保持一致,在论文中,$dim=512$。
1.7 位置编码
词的顺序对语言的理解与表达有着重要影响,因为它可以直接改变句子的语义。例如,“The cat chased the dog”和“The dog chased the cat”仅交换了主语与宾语的顺序,就完全改变了行为的主体与对象;同样,“Are you going to the park?”与“You are going to the park.”仅通过词序调整就从陈述句变为了疑问句。此外,修饰语的位置也会影响句义,例如“The small boy kicked the ball”描述的是一个小男孩,而“The boy kicked the small ball”则强调球是小的。动作顺序的变化也会影响事件逻辑关系,例如“She got up and then drank coffee”和“She drank coffee and then got up”体现的先后顺序截然不同。
为了解决这个问题,Transformer 模型为每个输入的词嵌入向量添加一个向量。这些向量遵循模型学习的特定模式,有助于模型确定每个词的位置,或序列中不同词之间的距离。
![图片[27]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/6770cb98d0e0a243d4ec0df3.png)
如果我们假设词嵌入向量的维度是4,那么实际的位置编码如下:
![图片[28]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/6770cbc8d0e0a243d4ec0e08.png)
这些位置编码到底遵循什么模式呢?其具体的数学公式如下:
$$
PE_{(pos, 2i)} = \sin(pos / 10000^{2i/d_{\text{model}}})
$$
$$
PE_{(pos, 2i+1)} = \cos(pos / 10000^{2i/d_{\text{model}}})
$$
其中,pos 表示词在序列中的位置,i 表示编码维度。
上述设计的函数使得模型可以学习到词之间的相对位置信息,例如对于任意位置 $PE_{(pos+k)}$,可以通过线性函数表达为:
$$
\cos(\alpha + \beta) = \cos(\alpha) \cos(\beta) - \sin(\alpha) \sin(\beta)
$$
$$
\sin(\alpha + \beta) = \sin(\alpha) \cos(\beta) + \cos(\alpha) \sin(\beta)
$$
在实际实现中,这些值可以直接通过可视化方式理解。每一行映射到一个单词的位置编码向量,其中第一行表示输入序列中第一个单词的位置编码,每一行包括 64 个编码值,每个值的范围通常落在 [-1, 1] 之间。
![图片[29]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/6770cc62d0e0a243d4ec0e1c.png)
需要注意的是,官方提供的示例代码(TensorFlow 1.x 版本 中的 get_timing_signal_1d() 函数和 TensorFlow 2.x 版本 中的 call() 函数)与 Transformer 论文中的方法稍微存在一定差异:Transformer 论文中,sine 函数和 cosine 函数产生的值交织在一起;而官方提供的代码中,左半部分的值全是由 sine 函数产生的,右半部分的值全是由 cosine 函数产生的,然后将它们拼接起来。官方代码生成的位置编码值的可视化图如下:
![图片[30]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/6770cc9cd0e0a243d4ec0e2a.png)
当然,这不是唯一生成位置编码的方式。但这种方式的优点是:可以扩展到未知的序列长度,这样就满足了seq2seq任务的序列长度不确定性。
1.8 解码器
现在,我们以及了解了编码器的大部分概念,我们也了解了解码器的组件的原理。现在让我们来看看编码器和解码器是如何协同工作的。
通过上面的介绍,我们已经了解第一个编码器的输入是一个序列,最后一个编码器的输出是一组注意力向量 Key 和 Value。这些向量将在每个解码器的 Encoder-Decoder Attention 层被使用,这有助于解码器把注意力集中在输入序列的合适位置。
![图片[31]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/6770cd9cd0e0a243d4ec0e45.gif)
在完成了编码阶段后,我们开始解码阶段。解码阶段的每个时间步都输出一个元素。
接下来会重复这个过程,直到输出一个结束符,表示 Transformer 解码器已完成其输出。每一步的输出都会在下一个时间步输入到下面的第一个解码器,解码器像编码器一样将解码结果显示出来。就像我们处理编码器输入一样,我们也为解码器的输入加上位置编码,来指示每个词的位置。
Encoder-Decoder Attention 层的工作原理和多头自注意力机制类似。不同之处是:Encoder-Decoder Attention 层使用前一层的输出构造 Query 矩阵,而 Key 和 Value 矩阵来自于编码器栈的输出。
1.9 Mask(掩码)
Mask 表示掩码,它对某些值进行掩盖,使其在参数更新时不产生效果。Transformer 模型里面涉及两种 mask,分别是 Padding Mask 和 Sequence Mask。其中,Padding Mask 在所有的 scaled dot-product attention 里面都需要用到,而 Sequence Mask 只有在 Decoder 的 Self-Attention 里面用到。
1.9.1 Padding Mask
什么是 Padding mask 呢?因为每个批次输入序列的长度是不一样的,所以我们要对输入序列进行对齐。具体来说,就是在较短的序列后面填充 0(但是如果输入的序列太长,则是截断,把多余的直接舍弃)。因为这些填充的位置,其实是没有什么意义的,所以我们的 Attention 机制不应该把注意力放在这些位置上,所以我们需要进行一些处理。
具体的做法:把这些位置的值加上一个非常大的负数(负无穷),这样的话,经过 Softmax 后,这些位置的概率就会接近 0。
1.9.2 Sequence Mask
Sequence Mask 是为了使得 Decoder 不能看见未来的信息。也就是对于一个序列,在 $t$ 时刻,我们的解码输出应该只能依赖于 $t$ 时刻之前的输出,而不能依赖 $t$ 之后的输出。因为我们需要想一个办法,把 $t$ 之后的信息给隐藏起来。
具体的做法:产生一个上三角矩阵,上三角的值全为 0。把这个矩阵作用在每个序列上,就可以达到我们的目的。
总结:对于 Decoder 的 Self-Attention,里面使用到的 scaled dot-product attention,同时需要 Padding Mask 和 Sequence Mask,具体实现就是两个 Mask 相加。其他情况下,只需要 Padding Mask。
1.10 最后的线性层和Softmax层
解码器栈的输出是一个 float 向量。我们怎么把这个向量转换为一个词呢?通过一个线性层再加上一个 Softmax 层实现。
线性层是一个简单的全连接神经网络,其将解码器栈的输出向量映射到一个更长的向量,这个向量被称为 logits 向量。
现在假设我们的模型有 10000 个英文单词(模型的输出词汇表)。因此 logits 向量有 10000 个数字,每个数表示一个单词的分数。
然后,Softmax 层会把这些分数转换为概率(把所有的分数转换为正数,并且加起来等于 1)。最后选择最高概率所对应的单词,作为这个时间步的输出。
![图片[32]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/6770d09ad0e0a243d4ec0ede.png)
1.11嵌入层和最后的线性层
在 Transformer 论文,提到一个细节:编码组件和解码组件中的嵌入层,以及最后的线性层共享权重矩阵。不过,在嵌入层中,会将这个共享权重矩阵乘以$\sqrt{d_{model}}$。
1.12 正则化操作
Transformer 模型为了增强其泛化能力,避免过拟合,在训练过程中使用了以下两种正则化方法来提升性能:
1. Dropout
Dropout 是一种常用的正则化技术,用于减少模型过拟合。在 Transformer 中,Dropout 被广泛用于编码器和解码器的每个子层的输出中。具体操作步骤如下:
- 位置:Dropout 作用在残差连接和层归一化(Layer Normalization)之前。
- 实现:
- Dropout 随机将部分神经元的输出置为零,从而随机丢弃某些特征,预防模型对具体特征的过度依赖。
- 在 Transformer 中,对输入向量、位置编码向量的加和结果,执行 Dropout。
- 论文中提供的参数:Dropout 概率 $P_{\text{drop}} = 0.1$。
具体意义:
- Dropout 避免模型陷入对某些输入单一特征的过拟合,提高模型在未见数据上的表现能力。
2. Label Smoothing (标签平滑)
标签平滑 是一种配合交叉熵损失函数(Cross-Entropy Loss)使用的正则化技术,用于缓解模型过拟合的问题。它通过在训练过程中对目标类别的标签概率分布进行调整,从而提高模型的稳定性。
具体调整方式如下:
-
标准做法:
- 如果某类别(目标)标签是符合 "one-hot" 形式的 $y = [1, 0, 0, ..., 0]$,则系统会直接训练模型预测为 $y$。
-
平滑后:
- 标签的概率被调整为 $(1-\epsilon)$ 为目标概率,$\epsilon$ 均分给其他类别。即,标签 (y) 从严格的 "one-hot" 分布变成一个更加平滑的概率分布,例如:
-
假设 $n=3$,有目标标签概率调整为:
$$
y = [1-\epsilon, \frac{\epsilon}{n-1}, \frac{\epsilon}{n-1}]
$$
-
论文使用的参数:平滑因子 $\epsilon_{ls} = 0.1$。
具体意义:
- 标签平滑能有效缓解模型过于自信的问题,避免预测时输出概率分布过于尖锐,提高模型的泛化能力。
- 1本网站名称:MuQYY
- 2本站永久网址:www.muqyy.top
- 3本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长 微信:bwj-1215 进行删除处理。
- 4本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
- 5本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
- 6本站资源大多存储在云盘,如发现链接失效,请联系我们我们会在第一时间更新。


![图片[9]-Transformer详解-MuQYY的博客](https://pic1.imgdb.cn/item/677026f1d0e0a243d4ec02e5.png)







暂无评论内容