“什么是真实?你如何定义真实?如果你说的是你能感觉到的、你能闻到的、你能尝到的和看到的,那么真实只是你大脑解读的电信号”
黑客帝国(1991)
概述
第 1 部分:我们将学习 Transformer 架构(注意力深度)中使用的最重要的术语和部分。
第 2 部分:我们将通过示例和代码逐步深入研究 Transformers 的架构。
以下文章分为两部分。在第一部分中,我们将探讨 Transformers 的概念及其工作原理。Transformers 的概念类似于电影《黑客帝国》中的概念,一个人可以通过服用含有知识的药丸来快速学习技能。同样,我们可以将知识从以前的任务中迁移并加以改进,而不是为新任务重新发明轮子。在这个激动人心的旅程中,我们将深入研究 Transformers 的历史、应用和架构,将其与 LSTM 进行比较并探索注意力机制。我们还将讨论 Transformers 是否仅适用于文本,或者它们是否可以用于其他应用程序。
在本文的第二部分中,我们将了解 Transformers 的整个架构并对其进行详细研究。
本图描绘的 transformer 架构图取自原文
仔细看看这张图片。这是原文中 Transformer 的主要架构图。一遍又一遍,反复查看!在这一部分和下一部分中,我们将彻底分析它,逐个部分、逐个细节。我每天都会花几分钟查看它。
序列到序列
Seq-to-Seq 模型最早是在 21 世纪初引入的。随着技术的发展和神经网络的深度,尤其是随着循环神经网络 (RNN)和LSTM的使用增加,Seq-to-Seq 模型的性能和实用性得到了显着提高。
这些模型现在被认为是自然语言处理的有效方法,特别是对于机器翻译等任务。然而,它们的主要问题是梯度消失问题,尤其是在使用 RNN 或 LSTM 时。
Transformers 也使用 Seq-to-Seq 架构来完成各种任务,但经过了许多改进和修改,提高了其性能和效率。Transformers,尤其是其注意力(Attention)机制,解决了 Seq-to-Seq 模型的局限性,并在语言处理任务中提供了更好的性能。
与 Transformers 相比,这导致 Seq-to-Seq 模型的应用减少,它们主要用于历史研究。在下一节中,我们将使用时光机回顾 Transformers 的历史!
Transformer的历史
“当我们谈论人工智能,听到“Transformers”或“Attention”这些术语时,首先想到的是2017年发表的开创性论文《Attention is all you need》。它为人工智能带来了一场重大革命,让我们深入研究一下Attention的概念是什么时候首次提出的。最早全面介绍机器翻译中Attention机制的论文之一是一篇论文。通过联合学习对齐和翻译实现神经机器翻译
这篇论文和《Attention is All You Need》的主要区别在于,在翻译过程中,神经网络会关注源句子中的不同位置,并以此为依据选择目标句子中对应的单词。而2017年论文中的Attention机制则完全取代了传统的用于处理序列数据的循环层,如LSTM(长短期记忆网络)和GRU(门控循环单元)。2017年论文中的Transformer网络完全基于Attention机制构建,不需要循环层。此外,论文中还使用了自注意力机制,使网络能够关注句子中单词之间的关系,从而得到更好的翻译。
值得注意的是,2015 年,Dzmitry Bahdanau、Kyunghyun Cho 和 Yoshua Bengio 发表了另一篇关于该主题的论文。神经概率语言模型
一篇研究论文的作者利用 Attention 机制来增强机器翻译。他们引入了一种称为“监督注意力”的特定类型的注意力,它使网络能够在训练期间根据输入和相应的翻译输出将注意力集中在源句子中的重要点上。这种类型的注意力有助于网络在目标句子中更准确地选择相应的单词。
终于,在2017年,一篇题为《注意力就是你所需要的一切》的论文发表了。你只需要注意力(Attention is all you need).
可以肯定地说,人工智能革命始于一篇论文的发表,这篇论文自此成为该领域的参考点。随后,人们就该主题撰写了许多文章,并开发了许多在各种任务中实现 Transformers 的方法。
这种类型的架构甚至用于计算机视觉任务,我可能很快就会更详细地讨论它。在以下章节中,我们将彻底研究 Transformer 架构和论文“Attention is all you need”中描述的最重要的问题和机制。
注意力模型有多种类型
在本节中,我们旨在探索什么是注意力机制以及不同类型的注意力机制。我们还将对它们进行比较分析,以更好地理解它们之间的差异。
注意力(Attention)
“注意力”一词指的是将注意力集中在需要更多关注的特定点上。这一概念最初用于自然语言处理,以克服逐字翻译的局限性,而这种局限性经常导致错误。本质上,注意力为输入数据分配重要性权重,这些数据与当前任务相关,并且可以显著影响合适输出的生成。然而,注意力不仅关注输入数据,还会影响模型处理中使用的其他元素,例如模型权重、隐藏状态向量等。让我们一起探索各种类型的注意力吧!
自注意力机制
自注意力机制(Self-Attention)又称为内部注意力机制(Intra-Attention),是一种常用于深度学习架构(尤其是 Transformer 模型)的注意力机制。在这种机制中,模型不会关注其他输入序列或使用不同的方法,而是专注于输入序列的各个部分。本质上,自注意力机制允许模型将输入序列中的不同位置相互连接,并使用此信息来计算序列的表示。这种类型的注意力机制使模型能够在输出表示中考虑长距离依赖关系和上下文信息。
此概念指的是输入序列和输出的不同组件之间存在的依赖关系和关系。这些关系不仅限于 token 到 token 的交互,还可以从更远的距离间接表示。例如,在文本中,一个单词可能位于句子的开头,而其依赖词位于句子的结尾。这种长距离依赖关系存在于 Transformer 模型的自注意力过程中,允许模型在其输出表示中考虑长距离关系并利用更多上下文信息。在有关 Transformer 架构的后续章节中,我们将进一步深入探讨这一点。
软关注(Soft attention)
软注意力是一种为每个输入元素分配权重的机制,权重通常来自 softmax 函数,用于指示其重要性。这些权重决定哪些输入元素在处理和决策过程中应获得最多关注,从而产生输出。软注意力的主要优势在于,它允许模型同时关注多个输入元素,而无需指定这些元素的固定数量。这可以通过基于梯度的技术实现更高效、更快速的优化。换句话说,软注意力使用优化方法,通过梯度(偏导数)简化和改进这些过程。这使得软注意力特别适用于长度和大小可变的输入数据,例如机器翻译、问答系统、图像中的对象检测等。
例如,在机器翻译中,软注意力机制可以在翻译过程中更加关注源句子中的每个单词。它通过考虑每个单词在生成目标句子中相应单词时的重要性来实现这一点。
软注意力是一种在基于 RNN 的模型中使用的流行机制,尤其是在序列到序列模型或循环神经网络中。软注意力和自注意力之间的关键区别在于如何计算注意力权重。在自注意力中,每个元素都与所有其他元素相连,注意力权重直接从输入特征中提取。相比之下,软注意力使用机器学习模型(例如神经网络)来计算注意力权重。该模型考虑输入特征和模型的当前状态来确定注意力权重。对于哪种注意力机制更合适,没有明确的答案,因为选择取决于手头的任务。
强烈关注(Hard attention)
硬注意力是模型用来仅关注输入特征子集而忽略其余特征的机制。与为所有输入元素分配连续权重的软注意力不同,硬注意力使用离散权重进行关注。这意味着模型在每个步骤中只选择一个或几个元素进行关注,从而形成更简单、更有选择性的注意力机制。
然而,训练使用硬注意力的模型可能具有挑战性。硬注意力机制将不可微分的操作引入模型,从而使模型不可微分。如果没有可微分性,则无法使用反向传播等标准机器学习算法来优化具有硬注意力的模型。为了训练这些模型,采用了特定的技术,例如强化学习,它使用奖励和惩罚来引导模型做出正确的选择,或离散优化技术,它使用离散搜索算法来找到最佳元素集,或导数近似,它使用各种技术来近似不可微分操作的导数,从而可以使用标准的反向传播方法。
硬注意力机制有许多应用,其中之一就是图像字幕,它允许模型聚焦于图像的特定区域并选择最佳区域来生成图像字幕。
全球关注(Global attention)
全局注意力机制是序列到序列模型中使用的一种方法,特别是在机器翻译等任务中。这些机制通过为每个元素分配注意力权重,使模型能够关注输入序列的所有元素。这允许模型在计算所有输入元素的总体权重时使用输入序列中的所有可用信息,该权重用于创建上下文向量。注意力分数用于确定这些权重,并计算为每个组件的注意力概率。
使用全局注意力机制的主要优势之一是模型可以识别和理解数据中更复杂的结构。这是因为模型可以在决策和输出生成中利用长距离依赖关系和背景信息。因此,这种方法可以提高模型输出的性能和质量,特别是在模型需要关注输入句子中的所有单词以生成连贯翻译的任务中。
当地关注(Local attention)
局部注意力是一种注意力机制,常用于神经网络中的自然语言处理 (NLP) 和计算机视觉等任务。局部注意力机制旨在计算输入序列中较小区域的注意力权重。与全局注意力不同,在全局注意力中,模型会学习选择当前位置周围的特定区域或窗口,并计算整个序列的注意力权重。当相关信息位于特定的局部环境中时,例如在处理具有强局部特征的时间序列数据或文本时,局部注意力机制非常有用。
此外,局部注意力机制在计算上比全局注意力更高效,因为它们减少了所需的注意力计算次数,使其适用于具有大量输入序列或有限计算资源的应用程序。
掩蔽/多头自注意力(Masked/Multi-Head Self-Attention)
多头自注意力 (MHSA) 机制是自注意力 (SA) 机制的高级版本。与专注于单个点的 SA 不同,MHSA 可以同时关注输入序列中的几个不同方面或点。SA 和 MHSA 之间的显著区别在于,SA 计算一组注意力权重,而 MHSA 计算多组注意力权重,然后将它们组合起来产生最终输出。这种能力使 MHSA 能够处理输入元素之间更复杂的关系。此外,MHSA 可以并行化并降低 SA 的计算成本,因为每个注意力头都可以独立计算输入元素子集的注意力权重。
此外,在 Transformer 架构中,还有另一种注意力形式,称为 Masked Multi-Head Self-Attention,用于机器翻译和文本摘要等序列到序列任务。在 Masked Multi-Head Self-Attention 中,主要目标是使用特定的掩码限制模型在每个处理步骤中对序列先前部分信息的访问。这样,模型就被迫按顺序处理信息,而序列中尚未处理的部分将暂时对模型隐藏。逐渐地,根据到那时为止的可用信息计算注意力权重。
缩放点积注意力机制(Scaled Dot-Product Attention)
Transformer 模型使用一种称为 Scaled Dot-Product Attention 的技术来建立层内所有输入 token 之间的关系。这种注意力机制在 Self-Attention 和 Multi-Head Attention 中用于对句子中单词之间的关系进行建模。K、Q、V(Key、Query、Value)三个矩阵在此机制中起着至关重要的作用。
原文中给出了 Scaled Dot-Product Attention 模块的图像。来源
Key矩阵(K)计算句子中每个单词与输入词(Query)Q的相关性。它表示与输入文本相关的信息,其中句子中的每个单词都有一个Key向量。
Query矩阵(Q)计算句子中每个单词与我们要关注的单词(Context)的相关性。它表示与输入单词相关的信息,其中句子中的每个单词都有一个Query向量。
Value矩阵(V)表示句子中每个单词相关的信息,表示每个单词的语义信息,其中句子中的每个单词都有一个Value向量。矩阵K、Q、V用于根据输入单词(Query)计算句子中每个单词的权重。
缩放标记的点积(Scaling the Dot-Product of Tokens)
对于每个输入标记,都会与所有其他标记计算点积。这涉及通过计算标记的嵌入向量之间的点积来缩放点积。首先,将每对标记(源和目标)的嵌入向量相乘。然后使用得到的点积值来表示两个标记之间的重要性和依赖性。结果是一个点积值矩阵,它表示序列中不同标记之间的关系和依赖关系。这些关系和依赖关系用于在注意力算法的后续阶段计算加权注意力分数。点积反映了标记之间的关系和依赖关系,并针对每个标记对(K 和 Q)进行计算。
为了简化,我们考虑一个包含多个单词的输入句子。我们想要计算每个单词对其他单词的重要性和依赖性。例如,如果句子中有两个单词“dog”和“boy”,我们需要计算句子中每对单词的注意力分数。这是因为如果我们只关注整个句子,我们可能会错过这两个词之间的关系。例如,在句子“The dog ran with the boy”中,我们需要了解“dog”与“boy”相关。
归一化(Normalization)
内部计算的每个 token 的尺度除以一个归一化值,该值通常等于 token 向量的长度,或者可以说等于 token 表示向量长度平方和的平方根。当我们计算序列中每个 token 的内部尺度时,我们本质上是将这些值归一化为标准尺度,以便我们可以在一致且可接受的尺度上进行比较。我们为此使用了 Softmax 函数。Softmax 函数是一种将输入值转换为概率空间的函数,使得较大的值具有较高的概率,较小的值具有相应的较低概率。这有助于提高算法的稳定性和效率。
功能矩阵
在此阶段,我们根据上一阶段生成的值(即标记的点积)计算每个标记的权重。这些权重表示每个标记相对于序列中其他标记的重要性。为了计算权重,我们使用具有适当计算维度的权重矩阵。此权重矩阵的维度相当于 Transformer 输入和输出中存在的标记数量。
该图描绘了一个解码器块,我们可以清楚地看到在编码器中计算并输入到解码器中的特征矩阵。来源
总而言之,这个权重矩阵本质上是一个线性映射,它将每个输入标记转换为合适的权重。这些权重通常在 -1 和 1 之间,它们表示每个标记相对于其他标记的重要性。然后使用内部缩放的标记值为每个标记计算这些权重,这些标记值表示标记之间的关系和依赖关系。
计算最终得分
在此阶段,将先前计算出的权重乘以 token 表示,以得出每个 token 的最终值。此最终值表示该 token 相对于其他 token 的重要性,并在 Transformer 模型中用于计算注意力权重。
加权平均
在此步骤中,根据分配给每个标记的最终注意力分数来计算每个标记的重要性。然后使用这些重要性分数确定标记表示的加权平均值。此加权平均值在标记之间传递信息方面起着关键作用,确保重要标记在计算中具有更大的权重。缩放点积注意力机制是 Transformer 中使用的一种注意力机制,它可以理解序列中标记之间的位置信息和依赖关系。它有效地利用这些信息来生成输出。
Transformer中的剩余连接
残差连接在 Transformer 的架构中被广泛使用,以缓解消失梯度问题 (VGP)。这个问题在深度网络中至关重要,因为随着深度的增加,梯度可能会变得太小,接近于零,从而使其实际上不存在。残差连接有助于缓解这个问题。
该图有效地说明了带有残差连接的编码器块。来源
在 Transformers 中使用残差连接的想法受到了 ResNet 架构的启发。对于 Transformer 中的每一层自注意力和前馈神经网络,都会应用这些连接。它们帮助网络在整个网络路径中保留原始信息和原始输入。因此,梯度会快速返回到较早的层,从而减少 VGP。
这些连接也有助于知识保存。本质上,它们有助于在整个网络路径中保留主要和必要的输入特征(在初始层中提取的特征),使它们可以在更深的层中访问。因此,网络可以更有效地学习如何更好地处理这些信息,从而加快模型训练速度。此外,它减少了层中的参数数量,因为不需要存储具有额外输出部分的额外层。
考虑一个没有残差连接的 Transformer 网络。在这种情况下,信息不会直接在不同层之间传输,并且每个层都必须从头开始接收和处理信息。这增加了训练所需的阶段数,并增加了计算时间和成本。此外,梯度消失的可能性也会增加,这可能会导致网络性能不足。但是,使用残差连接可以最大限度地减少这些问题,并提高网络性能。
位置嵌入
位置编码的类型
所有类型的 Position Embedding 都用于基于 Transformer 的架构,但并非所有类型的 Position Embedding 都用于每个 Transformer 模型。下面,我们将研究它们以及它们的使用环境。
固定位置编码
这种解释使用固定向量来表示序列中的每个位置。这些向量通常在预训练期间学习并在所有序列中共享。它在原始 Transformer 论文中使用,并且仍然在许多基于 Transformer 的模型中广泛使用,包括各种版本的 BERT。
可学习的位置解释
在训练过程中,可学习的位置解释涉及为序列中的每个位置创建一个不同的向量。这种方法使模型能够适应不同序列的独特长度和结构。某些模型(例如 Transformer-XL)将此技术用于自然语言处理任务,其中序列中的每个位置都会获得不同的位置嵌入。
相对位置解释
本文解释了自然语言处理模型中使用的两种标记位置解释之间的区别。第一种解释基于标记的相对位置,而不是绝对位置。这种解释用于 Transformer-XL 和 Reformer 等模型,这些模型旨在提高机器翻译、文本生成和情感分析等文本处理任务的效率。Reformer 模型对于大型文本处理项目特别有用,因为它可以执行并行性并优化计算资源。
一些模型使用固定和可学习位置嵌入的组合,而其他模型则使用替代方法来整合位置信息。例如,原始 Transformer 模型使用正弦位置编码,它使用正弦函数对每个 token 的位置进行编码。其他模型使用旋转编码方法。位置嵌入方法的选择取决于具体任务和模型设计。
Transformers 的主要架构,左侧是编码器,右侧是解码器
注意:“本文提供的所有代码均已在 Google Colab 中测试并生成输出。代码为伪代码格式,不适用于任何特定项目;它们主要用于更好地理解主题。”
Transformers 的架构
Transformer 架构是一个强大而复杂的系统,由两个主要组件组成:编码器和解码器。每个组件内都有多个块执行特定任务。当使用 Transformer 执行任务时,该架构会重复多次,如原始文章图片中编码器和解码器各部分中的“ Nx ”所示。
然而,Transformer 架构在刚推出时就面临一些挑战,例如由于使用了 Attention 机制,计算复杂度较高。这使得它需要大量的训练数据,尤其是对于机器翻译而言。
为了解决其中一些问题,原始 Transformer 架构论文引入了Dropout等技术来减少过度拟合,后续文档介绍了解决 Transformer 主要问题的新架构。这些包括在架构中添加卷积层、使用基于特征的注意力或使用针对数据特定特征定制的 Transformer 架构。
我们还利用了AdamW等改进的训练算法来提高训练 Transformer 模型的速度和效率。在以下部分中,我们将详细研究 Transformer 架构的每一层。
编码器
编码器在 Transformer 架构中起着至关重要的作用。其主要任务是通过提取关键信息来理解和压缩输入信息。编码器包含一个或多个神经层,每个神经层通常由两个主要部分组成。多头注意力 (MHA)模块负责管理输入中所有单词或序列之间的关系。它计算每个输入的注意力分数,以关注句子或序列中的其他单词。MHA使用查询、键和值矩阵来计算单词之间的关系,并根据这些关系提取重要信息。然后,从 MHA 提取的数据由前馈神经网络层处理,该层使用非线性函数和技术(例如加权和激活)来处理输入序列(如句子中的单词、视频帧或任何其他类型的序列),接收和处理重要和关键信息。在下一节中,我们将逐层介绍编码器,看看它是如何工作的。
这张图片描绘了从原始论文中截取的编码器块。你可以看到编码器的各个部分。下面,我们的目标是逐一剖析每个部分。这张图片已被我模糊了。
Transformer 架构通常用于 Encoder 模型。然而,GPT、BERT和T5等模型已经通过使用核心模型的变体来解决它们面临的特定问题,从而修改了此架构。例如,BERT使用一种称为Masked Language Modeling (MLM)的技术进行训练。在MLM中,句子中的某些单词是隐藏的,模型必须根据周围的单词预测缺失的单词。另一方面,GPT将MLM与自回归语言模型结合使用进行训练。在自回归语言模型中,模型必须根据前面的单词预测句子中的下一个单词。这有助于GPT生成自然流畅的文本。T5 (Text-to-Text Transfer Transformer)使用多任务架构来学习各种自然语言处理任务,如翻译、摘要和问答。
嵌入层
‘
此图取自原始论文,展示了编码器的架构,其中突出显示了与嵌入层相关的部分。此图已被我模糊处理。
Transformer 架构通常使用嵌入层将序列中的单词或元素转换为嵌入向量。这些嵌入向量的维数低于独热编码向量,可以更好地表示语义和上下文信息。随后,这些嵌入向量将通过编码器层。通常,使用嵌入矩阵创建嵌入层,其中包含词汇表中每个单词或元素的向量。这些向量通常使用Word2Vec、GloVe或FastText等方法获得。例如,输入序列“ hello ”、“ world ”和“ how are you ”可以分别转换为嵌入向量,如[0.2, 0.5, -0.1]、[-0.3, 0.8, 0.6]和[0.1, -0.7, 0.4] 。我们可以轻松访问TensorFlow或PyTorch等流行库中的嵌入层,并轻松使用它们。
import torch
import torch.nn as nn
# Define the Embedding Layer
embedding_layer = nn.Embedding(10000, 300)
# Sample input data
input_data = torch.tensor([1, 5, 7, 2])
# Transform the input data into embeddings
embedded_output = embedding_layer(input_data)
# Display the dimensions of the output
print("Embedding Layer output dimensions:", embedded_output.size())
在此代码中,使用PyTorch库中的 ` nn.Embedding ` 类定义嵌入层。该层有两个参数:词汇表中的单词数(10,000)和每个单词的嵌入向量的大小(300)。
然后,将样本输入数据定义为包含多个单词索引的PyTorch张量,将其作为输入发送到嵌入层,嵌入层生成与每个单词对应的嵌入向量作为输出。最后,显示嵌入层输出的维度,并显示与输入单词对应的嵌入向量。
位置编码器
Transformer 模型不同于传统的循环神经网络模型,因为它不依赖于输入的序列顺序来生成输出。然而,这种隐式位置信息的缺失可能会导致在将 token 转换为嵌入向量时丢失重要信息。为了解决这个问题,位置编码器用于为输入 token 提供位置信息,指示它们在序列中的位置。这种位置信息的添加有助于保留信息,使模型能够区分序列中的不同 token。它还提供对序列顺序和位置的理解,从而提高模型在自然语言处理任务中的性能和效率。
位置向量通常以具有特定维度的向量或矩阵的形式生成。一种常用方法是使用正弦和余弦等数学函数为序列中的每个位置创建一个唯一值。本质上,位置编码器为输入标记配备了位置信息,使模型能够考虑标记的位置和顺序,并使用此信息生成适当的输出。
通常,位置编码器会直接放置在 Transformer 模型中的嵌入层之后。下面是一个简单的示例,演示了如何使用 PyTorch库中的位置编码器将位置信息添加到输入标记中。
import torch
import torch.nn as nn
import math
class PositionalEncoder(nn.Module):
def __init__(self, d_model, max_len=1000):
super(PositionalEncoder, self).__init__()
self.d_model = d_model
# Initialize the positional encoding matrix
pe = torch.zeros(max_len, d_model)
position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)
div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))
pe[:, 0::2] = torch.sin(position * div_term)
pe[:, 1::2] = torch.cos(position * div_term)
pe = pe.unsqueeze(0)
# Register as buffer so it's not updated during training
self.register_buffer('pe', pe)
def forward(self, x):
# Add the positional encoding to the input
x = x + self.pe[:, :x.size(1)]
return x
` PositionalEncoder`类继承自 ` nn.Module`类,它首先定义主要变量,例如嵌入向量大小`(d_model)`和最大序列长度`(max_len)`。然后,创建一个维度为 `( max_len, d_model )` 的位置矩阵,所有值最初都用零填充。接下来,对于序列中的每个位置,计算正弦位置编码变量的值并将其放置在位置矩阵中。最后,将位置矩阵注册为缓冲区,以便在模型训练过程中不会更新它。
多头注意力机制
在这张取自原始论文的图片中,你可以看到编码器的架构,其中突出显示了多头注意力层。这是 Transformer 架构的主要部分。这张图片已被我模糊了。
Transformer 架构中最重要的组件之一,也可以说是其核心,就是多头注意力机制 (MHA)。Transformer 的核心就是这种注意力机制。
这幅图取自原文,有效地说明了多头注意力 (MHA) 的运作方式。从图片左侧,我们可以了解缩放点积注意力是如何计算的,通过观察它,Q、K、V 的值更容易理解。来源
在位置编码器阶段之后,数据就可以由多头注意力 (MHA)模块处理了。该模块负责执行注意力机制,例如识别最重要的单词及其关系,这对于机器翻译等任务至关重要。为了实现这一点,需要准备嵌入向量,并使用三组 ( Q、K、V )输入多头注意力。这些集合被线性投影,然后输入到缩放点积注意力中。
在计算(Q, K)的过程中,涉及到点积运算(MatMul),矩阵值会使用Softmax 函数进行归一化,使其范围在0 到 1之间。然后通过MatMul将结果乘以V。之后,它们会经过另一个 Linear 层,并进入add & Norm 层。
但为什么这是必要的?这是为了防止在反向传播阶段出现梯度消失问题。如果不执行此步骤,梯度会变得非常小并且实际上会消失。在原始架构中,还使用了残差连接。值在使用( Q,K,V )计算之前会通过层规范化,以防止梯度下降问题。
如果不使用残差连接,由于梯度消失问题,网络后续阶段某些层的注意力可能会减弱,导致重要信息丢失或网络效率下降。如上图所示,原论文在每个阶段都使用了8 层Multi -head Attention。在下一个阶段,数据被输入到add & Norm层,我们将在后续讨论中进一步研究。
添加和归一化(Add & Norm)
Transformer 架构中的所有层都使用规范化技术(例如层规范化 或批归一化)来计算数据中每个特征或输入的均值和方差。MHA阶段可以产生具有不同值范围的输出,对它们进行规范化有助于训练过程。这种技术减少了训练过程中可能发生变化的内部变量偏差的影响,从而使网络能够适应新的、以前从未见过的情况。经过规范化之后,输入将传递到网络的后续层,在那里使用ReLU或GELU等激活函数进行进一步处理。规范化层可防止梯度过大或过小,并避免梯度爆炸和梯度消失等问题。在深度模型的训练过程中,输入特征可能会随着时间而变化,这称为协变量移位。规范化层可以减轻这些影响并加速训练过程。我们想在使用PyTorch库的 Python 代码示例中看到如何实现这一层。
import torch
import torch.nn as nn
class AddNormLayer(nn.Module):
def __init__(self, input_dim):
super(AddNormLayer, self).__init__()
self.norm = nn.LayerNorm(input_dim)
def forward(self, x):
# Add step: Adding input to the output of the layer
added = x + torch.randn_like(x)
# Norm step: Normalizing the output values
normalized = self.norm(added)
return normalized
# Using the Add & Norm layer
input_dim = 512
layer = AddNormLayer(input_dim)
# Example input
input_data = torch.randn(10, input_dim)
# Applying the layer on the input
output = layer(input_data)
print(output.shape) # Output size
在上面的代码中,我们使用PyTorch库实现了一个名为 ` AddNormLayer `的自定义层,它由两部分组成。第一部分是 ` Add `,其中将随机噪声添加到输入中。为此,将一个与输入具有相同维度的随机噪声向量添加到每个输入向量。此噪声向量是使用 ` torch.randn_like(x) ` 生成的,它从正态分布中创建具有与输入相同维度的随机值。然后,将此噪声向量添加到输入中,并在 ` Norm ` 步骤中,对从 ` Add ` 步骤获得的输出值进行归一化。为此,我们使用一个名为 ` nn.LayerNorm ` 的归一化层,它将输入维度归一化。最后,我们将这个自定义层应用于示例输入并打印输出维度以确保实现正确工作。
输出大小 ` torch.Size([10, 512]) ` 表示对于以 ` torch.randn(10, 512) ` 形式提供的示例输入,网络的输出维度表示有10 个特征,每个特征都是一个具有512 维的向量。换句话说,对于每个输入样本,都会生成一个具有512 维的输出向量,而我们的数据集中有10 个样本。
重要提示:“add & Norm”操作存在于Transformer架构的所有块中,并且始终伴随着通过激活函数直接进入的数据。数据也通过残差连接传递给它。它的输出通常是线性的或ReLU。
前馈神经网络(Feed-Forward Neural Networks)
在这张取自原始论文的图片中,你可以看到编码器的架构,其中前馈神经网络层突出显示。这张图片已被我模糊处理。
编码器由多层组成,每层都包含类似前馈神经网络的模块。在多头注意力(MHA)之后,有一个前馈神经网络(FFNN),它具有两个或更多感知器层和非线性激活函数(如ReLU、GELU或Swish)。这有助于网络学习复杂且非线性的模式,而单靠自注意力可能无法完全识别这些模式。FFNN层在应用自注意力操作后会压缩并进一步表示信息,从而降低过度拟合的可能性。该层的输出进入Add & Norm,它标准化了每层的输出特征,并使模型训练过程更快、更稳定。在经过所有编码器层之后,输出由最终的特征向量组成,通常表示为序列中每个元素的一组特征向量。这些特征向量包含来自输入序列的语义和上下文信息,并用于下一个过程,即解码器。(Q, K) 查询从解码器输入到 MHA 的最后一个块中。
解码器(Decoder)
解码器是 Transformer 架构中的一个重要组件。它负责生成最终输出,最终输出通常是文本序列或一系列元素,可用于各种目的,例如翻译、摘要或分类。解码器从编码器接收上下文向量或状态,并基于此生成单词或输出元素。解码器整合了来自两个不同来源的信息,即输入和先前的输出。它可以检查来自输入和先前输出序列的相关信息,以提供更准确的翻译或输出生成。解码器利用前馈神经网络 ( FFNN ) 来产生最终输出。这些层执行分析和组合输入特征等操作以生成最终输出,最终输出通常是用于流程下一阶段的文本序列或向量。
这张图片取自 Andrej Karpathy 的 YouTube 教程中的一张幻灯片。在这张图片中,可以清晰、出色地看到解码器及其各个组件的性能。来源
解码器由几个不同的层组成,每个层都有特定的任务。这些层包括多头注意力层和FFNN层。MHA帮助解码器关注来自输入和先前输出的相关信息,而FFNN 层则有助于非线性转换信息。
虽然解码器中执行的某些功能似乎与编码器中的功能有些相似,但它们之间存在重要差异。在解码器中的每个MHA中,都会进行注意,不同之处在于此注意是根据输入和先前输出的相关信息建模的,这些信息作为每个解码器层的输入。这使解码器能够根据输出生成的每个阶段调整其焦点。在解码器中,FFNN应用于MHA的结果,以使用非线性运算对信息进行建模并协助生成最终输出。
例如,在GPT架构中,诸如“猫坐在垫子上”这样的句子被作为模型的输入。输入句子作为标记序列输入到模型中,并由编码器层处理。在编码器层中,每个标记被转换成一个隐藏向量,表示其在句子中的含义。来自输入句子的相关信息在编码器创建的隐藏向量中建模,并作为输入提供给解码器层。在解码器层中,使用MHAL,模型可以关注来自输入的相关信息。来自输入句子的相关信息和来自先前输出的信息(如果有)用于生成输出句子中的下一个单词。此过程递归继续,直到生成完整的句子。
重要提示:在 GPT 模型中,编码器负责将输入句子转换为相关的隐藏向量,而解码器负责根据这些隐藏向量并考虑前面的文本来生成输出句子中的下一个单词。
输出!
在解释完解码器之后再讨论输出似乎有些奇怪,但这是该过程中的重要一步。解码器的第一部分涉及输出嵌入。这意味着输入向量被转换为隐藏向量(嵌入向量),这些向量同时考虑了单词的语义和位置特征。下一步是自注意力。
在本文中,“输出”是指模型在每个时间步骤的输出,而不是最终的输出词。Transformer 架构会逐渐生成输出词。在每一步中,模型都会生成一个隐藏向量,表示当前位置的单词概率分布。然后,该向量将用作模型下一步的输入,这个过程一直持续到生成最终的单词。
编码器和解码器在位置嵌入方面存在差异。在两者中,位置嵌入都表示单词在句子中的相对位置。但是,在解码器中嵌入需要不同的机制。在编码器中,输入词的顺序很重要,因为单词在句子中的位置决定了语义信息。在解码器中,除了输入词的位置之外,输出词的顺序也很重要。因此,模型必须考虑时间细节,以确保它产生正确的输出词序列。
也就是说,Decoder 使用了不同的 Positional Embedding 机制,既考虑了输出词的时间顺序,也考虑了输出词的位置。和 Encoder 类似,生成的向量也以同样的方式输入到 Attention block,但是存在被 mask 的可能。
蒙版多头自注意力(Masked Multi-Head Self-Attention)
解码器还使用了自注意力机制(Self-Attention),它与编码器中的同一层略有不同,尽管两者使用的机制几乎相同。在编码器中,自注意力机制允许模型在处理的每个步骤(例如机器翻译或其他自然语言处理任务)中检查其输入特征,模型会为每个特征计算适当的权重。然而在解码器中,自注意力机制被称为掩码 多头注意力机制(Masked Multi-Head Attention)。在每个文本生成或翻译步骤中,模型仅关注迄今为止已生成或按时间顺序排列的单词,而忽略尚未生成的单词(即未来的单词)。对自注意力机制的输入应用了掩码,以防止访问未来的信息。
此图为原始论文中的解码器,其中突出显示的部分是 Masked Multi-Head Attention,它在解码器的运行中起着至关重要的作用,尤其是对于文本生成任务。此图已被我模糊处理。
例如,假设模型正在生成一个句子,在当前步骤中,它仅生成了单词“ I ”和“ am ”。在这种情况下,被屏蔽的自注意力层仅关注这两个单词,而忽略尚未生成的单词,例如句子中的下一个单词。这可确保模型在每个生成步骤中仅关注到该时刻为止的可用信息,从而实现更准确的翻译或文本生成。此层有助于生成更准确、更有意义的翻译。
屏蔽多头注意力 (MMHA)可在训练期间实现并行计算,从而提高模型训练的效率和速度。自注意力中的屏蔽模式允许模型在每个训练步骤中仅关注前几个时间步骤中可用的信息,而忽略未来的信息。这使得模型能够有效地利用并行处理,因为每个节点都可以独立且同时执行其计算。
此功能通常用于生成文本的生成式 AI 模型(如ChatGPT 或LLM)。如果没有此功能,我们仍然可以使用生成式 AI 模型进行文本生成,但如果没有Masked Attention等机制,这些模型的文本生成性能和质量可能会下降。使用 Masked Attention 可以帮助模型在文本生成过程中更加关注句子的顺序和结构,并防止创建结构不一致的文本。
编码器-解码器注意力机制
此阶段仅用于解码器。信息从MMHA传递到后续层的方式与MHA相同。唯一的区别在于前面提到的效率。在解码器中,在MMHA之后,数据被传递到另一个MHA 层。这一层除了从MMHA接收数据外,还从编码器接收状态向量。这个阶段称为编码器-解码器注意力机制。
在每个步骤中,首先计算从解码器中的上一步收到的状态向量。然后,将此状态向量与所有编码器状态向量进行比较,以计算每个编码器状态向量对于在解码器中生成当前输出的重要性(权重)。通过这种方式,模型可以动态、智能地关注编码器输入并使用它们来生成适当的输出。
数学计算如下:首先,将代表输入中需要引起 Decoder 注意的重要关键信息的 Key Vectors,与从 Encoder 收到的包含输入中更详细信息的Value Vectors ,以及属于 Decoder 的Query Vectors (表示 Decoder 的注意点)组合成 Attention Score 等式。然后,使用这些注意力分数计算评估值,并通过加权平均获得最终的输出。
解码器中的 FFNN 层
Transformer 模型在编码器和解码器中都包含一个前馈神经网络层。然而,这两部分之间的这些层存在差异。在编码器中,此层将输入特征(通常是单词的特征向量)转换为新的特征空间,从而为模型产生最佳结果。FFNN层的所有神经元都接收每个输入特征,然后激活函数(通常是 ReLU 或 GELU)处理输出。
在解码器中,该层将Self-Attention的输出特征转换为新的特征空间,帮助模型生成最终的文本。与编码器不同,解码器在文本生成过程中不需要未来信息来使用过去的信息。因此,解码器中的FFNN 层通常实现为Masked Feed-Forward Neural Network,它限制了对未来信息的访问。此限制通过计算中的相应掩蔽来强制执行,以便模型只能访问过去的信息。
输出层(线性 + Softmax)
此图是从原始论文中截取的解码器。输出层(线性 + Softmax)是解码器架构的最后几层,实际上是 Transformer 架构的最后几层。此图已被我模糊化。
在模型的末尾,有一个线性输出层,后面跟着一个Softmax 层。线性输出层有助于将输入转换为数值,而Softmax 层将这些数值转换为归一化概率,用于预测类别(在分类模式中)或单词(在文本生成模式中)。Softmax层由两部分组成 – 最后的线性层和Softmax 层本身。让我们仔细看看每个部分,并详细研究其用途。
最后线性层(Last Linear Layer)
最后的线性层是Transformer 架构的重要组成部分,通常位于模型的末尾。该层直接接收从解码器的前几层提取的特征。其主要功能是将最终的模型特征转换到模型所训练的特定任务所需的特征空间中。该层通常由权重矩阵和偏差组成,其输入通常是在编码器或解码器阶段结束时获得的模型的最终特征向量。最终特征通常是通过应用线性运算(即权重和输入特征之间的矩阵乘法)获得的,然后是激活函数(例如ReLU或GELU)。
该层的输出取决于手头的具体任务。如果模型是为分类而设计的,则该层的输出通常会发送到Softmax 层以计算类别概率并对该类别做出最终决策。另一方面,如果模型是为文本生成而设计的,则该层的输出将由Softmax 层进行归一化,并在下一个文本生成步骤中作为单词概率发送。
举例来说,我们考虑这样一个场景:我们的模型正在将句子“我爱猫”翻译成法语。输入句子“我爱猫”经过多层,每一层都会提取特征。最后一层线性层接收这些提取出的特征,这些特征包含了从前面的层获得的含义、语法和句子结构的信息。这一层利用其权重将这些特征变换到与所需输出相对应的特征空间,即与法语句子“ J’adore les chats ”相对应的特征空间。该层为每个输入特征分配权重,以将它们变换到新的特征空间,作为Softmax 层的输入。
Softmax
一旦数据通过了最后一层线性层,它就会经过一个Softmax 层。该层将线性层的输出权重转换为模型输出中每个类或单词的归一化概率。在分类模型中,这些概率表示每个类的可能性。在文本生成模型中,这些概率表示每个单词出现在模型输出中的可能性。
Softmax层确保没有概率达到零,从而防止出现某些问题,例如零偏差和概率分布偏移。这有助于模型输出概率分布随时间保持一致。
在LLM中,如果句子中单词的概率分布发生变化,则会导致句子不连贯且毫无意义。因此,Softmax 层可确保模型按比例且一致地分配概率,防止概率分布发生意外变化。
同样,在分类任务中,如果类别的概率分布随时间发生变化,模型的准确性和可预测性可能会下降。因此,Softmax 层可确保模型按比例且一致地分配概率,并防止概率分布发生意外变化。
最终输出结果
在解码器中的 Softmax 层之后,通常使用 Transformer 架构中的以下两种方法之一生成最终输出。要么通过 Beam Search,在使用 Softmax 层计算概率后,模型采用 Beam Search 为每个步骤选择最佳预测。在这种方法中,对于每个步骤,模型都会计算多个可能的预测,然后选择其中概率最高的预测。此过程持续到达到终止条件,例如句子结束或预定步骤数。
例如,如果模型使用大小为3的集束,则会选择每一步中概率最高的预测,并且在后续步骤中,使用为下一个单词计算的概率来更新这些预测。其主要应用是机器翻译模型、图像字幕模型和基于注意力机制的文本生成模型等模型。
采样的下一步不是选择最佳预测,而是让模型使用采样过程并根据计算出的概率生成各种预测。此过程可以随机完成,这意味着预测是根据计算出的概率分布进行采样的。例如,假设一个模型想要预测句子中的下一个单词。该模型可以根据词汇表中不同单词的计算概率,使用直接采样随机选择一个单词。例如,如果词汇表包含单词“ sky”、“yellow ”和“ blue ”,概率分别计算为0.4、0.3和0.3,则模型可以使用采样随机选择单词“ sky ”。此方法用于语言模型、机器翻译、自动文本生成和图像生成等各种任务。
然而,选择哪种方法来产生合适的输出取决于我们想要执行的任务。例如,在搜索空间非常大并且使用直接采样可能太耗时的情况下,可以使用 Beam Search 来生成可能的预测。在这两种方法中,生成的输出都用作模型的输入以计算下一步,或用作程序和其他应用程序中使用的最终输出。
Transformer 的应用
Transformer 因其出色的理解句子中单词之间关系的能力而在NLP任务中广受欢迎。它们有许多应用,包括机器翻译,可以提高不同语言之间翻译的准确性。Transformer 还可以准确地总结长文本,为与文本相关的问题提供准确而全面的答案,生成各种类型的文本(如诗歌、故事、代码和电子邮件),检测和纠正拼写和语法错误,从文本中提取重要信息,并分析文本中表达的情感。此外,Transformer 还用于LLM,与用户进行自然而引人入胜的对话。
Transformers 在计算机视觉中的应用
Transformer 的应用范围已超出其传统应用,现在正用于处理图像和视频等计算机视觉任务。谷歌等大公司正在将其广泛应用于各种应用中,包括图像分类(识别物体、动物或景观)、物体检测(识别个人、汽车或建筑物)和图像分割(分割个人、汽车或建筑物)。一种名为ViT的模型(Transformer 模型)已用于提高ImageNet数据集的准确性。ViT模型是由谷歌 AI的一组研究人员在2021 年发表的一篇论文中提出的。一张图片胜过 16×16 个单词:用于大规模图像识别的 Transformers
本文展示了 Transformer 模型可以直接应用于图像。ViT模型采用了与处理图像的标准 Transformer 略有不同的架构。
它在 ImageNet 数据集上进行训练,使用具有大量参数的预训练。使用ViT模型可以在各种图像识别数据集上取得非常好的效果,优于以前的高级模型(例如基于 CNN 的模型)。
OpenAI将 Transformer 用于各种计算机视觉应用,包括图像生成、图像翻译等。
例如,名为DALL-E的 Transformer 模型可以从文本生成真实图像。微软将 Transformer 用于人脸检测、物体检测和物体跟踪。
例如,基于 Transformer 的模型Azure 认知服务为开发人员提供了计算机视觉 API。
Facebook 在人脸检测、物体检测和图像分割等任务中使用 Transformer。
例如,设计了Detectron2模型,它本质上是一个基于 Transformer 的深度神经网络的图像物体检测开源工具箱。该工具箱利用了 Transformer 模型和计算机视觉领域的其他先进方法。
使用Detectron2模型的一些好处包括准确性高、对各种输入的适应性以及在图像识别和解释中执行复杂任务的能力。
挑战和问题
Transformer 的功能非常先进,特别是在自然语言处理和计算机视觉领域。然而,没有一个模型是完美的,每个模型都有其缺点。需要考虑的一个主要问题是 Transformer 的高复杂性,它需要大量的计算资源来进行训练和使用。这可能导致较长的训练和处理时间、高能耗以及对强大硬件的需求。
此外,训练 Transformer 模型需要大量数据集,这可能导致需要存储和处理大量数据以及管理大型数据集等问题。
由于 Transformer 要求数据采用标记或数值向量的形式,这可能会降低某些领域(例如图像识别)的准确性和信息量。
结论
在我们研究的第二部分中,我们详细介绍了 Transformers 的架构。我们研究了每个组件和层,并了解了编码器、解码器和 Transformers 如何协同工作以改善不同语言之间的语言翻译。
我们还探讨了如何将 Transformers 用于各种其他任务。我们讨论了 Transformers 的一些局限性。
自2017 年推出以来, LLM的受欢迎程度持续上升,而 Transformers 是其基础。看来 Transformers 不仅保持了其受欢迎程度,而且每天都在变得越来越受欢迎。
然而,近年来,出现了Infini-Transformers等其他架构。Infini -Transformers是具有无限深度的 Transformer 模型系列,我发现的关于这个主题的最重要的论文是由 Google 的研究团队撰写的。不遗漏任何上下文:具有无限注意力机制的高效无限上下文 Transformers
这些模型利用标准 Transformer 架构,并对其进行了修改以增加其深度。
例如,它们在架构中使用ReLU 激活函数代替softmax 激活函数,在每个 Transformer 块之间加入批量归一化层,并采用新的位置注意函数。这些模型使用在大型文本数据集上使用大量参数进行预训练进行训练。之后,对模型进行微调以适应各种NLP任务,例如机器翻译、文本摘要和问答。
我将来会更多地介绍这些模型。然而,变化的速度已经大大加快,可能很快就会出现一种比 Transformers 更有效的模型。感谢您陪伴我阅读这篇文章。我在写这篇文章的时候学到了很多东西,希望对你也有帮助。
RA/SD 衍生者AI训练营。发布者:chris,转载请注明出处:https://www.shxcj.com/archives/3533