Transformer 架构17 Mar 2025 | 6 分钟阅读 在 Google 发布文章“Attention is all you need”之前,RNN 架构被用于解决几乎所有 NLP 问题(例如机器翻译)。尽管注意力机制已在 RNN 架构中使用,但仍存在一些缺点:RNN 网络处理长词效果不佳,并且训练时间非常缓慢,因为模型必须逐步遍历句子。Transformer 的出现就是为了解决这些问题。BERT 和 GPT-2 就是使用 Transformer 架构构建的。Transformer 架构可以被理解为一种将注意力机制应用于整个编码器和解码器的架构。 ![]() 在传统的 RNN 设计中,编码器和解码器都接受序列作为输入,并在时间步长上遍历整个短语。这意味着我们必须等到编码器到达最后一个时间步长,然后才能开始将其馈送给解码器输出。这个选项减慢了训练速度。虽然使用截断反向传播来缩短训练时间,但它并未充分利用并行处理(同时运行所有内容)的潜力,因此性能仍然不佳。 ![]() RNN 设计的第二个缺点出现在输入是长短语时。 长短语 ==> 长时间步 ==> 梯度变化更大(太小/太大)==> 梯度消失/爆炸 ==> 信息丢失/衰减 ![]() LSTM长短期记忆(LSTM)是解决 RNN 架构中梯度消失问题的一种方法。基本上,LSTM 有一个“单元,用于启用所有信息通过单元并避免训练期间的衰减/丢失信息,以及一个遗忘门,用于跳过连接以避免梯度消失/爆炸。” ![]() LSTM 解决了梯度消失的缺点,但其本身的架构比 RNN 更复杂,因此训练速度非常慢,尤其是在处理长句子时。 Transformer 架构![]() Transformer 包含两部分:输入(编码器)和输出(解码器)。Transformer 的输入与 RNN 的输入不同。Transformer 中没有“时间步长”,因此短语输入不会是循环的。每个输入位置都是平等的,单词不再有序,它会馈送到并行处理中。你可能会想,没有循环我们怎么能做到呢?答案是位置编码。 位置编码采用这种方法是因为建议的设计不使用单词顺序(第一个单词、第二个单词等)。输入序列中的所有单词都以无特定顺序或位置的方式馈送到网络(与典型 RNN 不同),因此模型不知道单词是如何组织的。因此,每个单词嵌入都包含一个依赖于位置的信号,以帮助模型整合单词顺序。这种添加不仅避免了删除嵌入信息,还包含了重要的位置信息。在 RNN 的情况下,我们按顺序将单词馈送给 RNN,以便第 n 个单词在第 n 步提供,从而使模型能够包含单词顺序。 短语中的每个单词同时通过 Transformer 的编码器/解码器堆栈。模型对每个单词的位置、顺序或重复没有任何概念。但实际上,单词的位置和顺序是任何语言的重要组成部分。它们决定了句子的语法,进而决定了句子的含义。由于这个特性,我们可以自然地理解一件事:如果 Transformer 不像 RNN 那样将所有单词视为“有序/循环”,那么 Transformer 必须使用另一种机制来确保句子中的每个单词都能按照自己的正确位置进行跟随。 为模型提供顺序感的一个可能选择是包含每个单词在句子中位置的信息。我们将这种“信息”称为位置编码。 位置编码是通过将维度为 d_model 的嵌入向量添加到每个单词来形成的,从而得到一个与嵌入向量大小相同的向量。这个位置编码向量告诉模型这个单词在短语中的位置。让我们先定义这些向量。 ![]() ![]() 例如,在句子“The little bird took its flight”中,单词“bird”的位置编码向量是(此处取 d_model=300): ![]() 让我们解释一下为什么这个位置向量中会有 sin(2)、cos(2)、sin(1.88)、cos(1.88),等等。 首先,上面所示的编码向量用于位置=2 的“bird”单词。⇒ pos = 2。其次,d_model = 300,这意味着向量的维度将从 [0,299] 范围,每个维度都将具有一对(sin,cosine)函数。
考虑一个较长文本的位置编码的热力图。每一行代表一个单词,并显示其位置编码向量的前 40 个值。 ![]() 如果短语中两个单词 A 和 B 之间的距离与单词 C 和 D 之间的距离相同,那么它们的位置编码向量应该反映这一点。 计算位置编码后,我们将输入嵌入和位置编码相加,得到最终的带有上下文信息的嵌入输入:Embedding_with_context = input embedding + positional encoding。 自注意力机制基本上,多头注意力向量是多个自注意力向量的连接。为了理解多头注意力,我们将首先查看自注意力向量。 自注意力是一种序列到序列的转换,它将一个令牌序列转换为另一个令牌序列。一个单词的良好表示必须与其在短语中的上下文相匹配。单词 i 的嵌入向量 W(i) 必须准确地与 i 左边的单词 W(1),..., W(i-1) 以及右边的单词 W(i+1),..., W(n) 相关联。 自注意力是充分利用句子中注意力机制力量的方式。详细分为 3 个步骤
自注意力不是为每个单词学习一个单一的嵌入来执行这三个任务,而是为每个任务学习一个不同的单词嵌入。从一个通用嵌入转变为每个单词的三个专用嵌入。将任务 1 的嵌入称为查询(query),任务 2 的称为键(key),任务 3 的称为值(value)。 ![]() 例如,假设我们有句子“The little bird took its flight”。我们想确定单词“bird”的注意力表示。首先,我们评估这个单词与短语中其他单词的关系。 ![]() 为了实现这一点,我们将它的查询向量 Q(bird) 与所有其他单词的键 K(the),..., K(flight) 进行点积,生成一个包含句子中所有单词的权重向量:α(the),…,α(flight)。然后,我们将这些权重应用于句子中所有单词的值向量 V(the),..., V(nest) 的加权和。 公式我们将查询和键馈送到一个执行矩阵乘法然后 softmax 的数学函数中。 resultant context vector for Q is the product of the probability vector generated by the softmax and the Value. 自注意力被定义为从相同的输入序列 X 生成查询、键和值。 多头注意力自注意力的一个问题是,一个单词(x)的注意力几乎会关注它本身。例如,对“bird”的注意力将对单词“bird”得分最高。这显然是合乎逻辑的。 但我们想看到的是“bird”这个词与其他词是如何交互的。因此,多头注意力是一种解决方案,它仅仅整合了由多个注意力(头)或代理检查的知识,而不是像通常情况那样独立进行。单词向量被分成固定数量(h,头的数量)的块,并对相关块应用自注意力,为每个单词产生一个 h-context 向量。最终的上下文向量是通过连接所有 h 个上下文向量并乘以 Wo 矩阵(加权矩阵)来创建的。 ![]() 下一话题基于局部离群因子的新颖性检测 |
我们请求您订阅我们的新闻通讯以获取最新更新。