AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


这次终于能把Transformer弄清楚了!
发布日期:2024-07-14 06:00:12 浏览次数: 1740



你将学习到的内容:本文将深入探讨Transformer架构,这是当今几乎所有尖端大型语言模型架构的核心组成部分。

首先,我们将简要回顾一些与自然语言处理(NLP)相关的基本概念,随后逐步解析Transformer的工作原理。

适用人群:本文适合对自然语言处理(NLP)感兴趣的任何人阅读。

文章难度:尽管本文并不复杂,但由于涉及众多概念,可能对新手来说有一定的难度。

先决条件:为了更好地理解本文内容,大家需要对标准神经网络有基本的工作理解,还需要对嵌入、编码器和解码器有初步认识。

Transformer之前的NLP简史:在深入探讨Transformer之前,我们简要介绍一些必要的概念和技术背景。

如果你已经熟悉这些内容,可以选择跳过此部分。其中,词向量嵌入是理解自然语言处理的基础,它通过将单个单词转换为向量来代表其含义。


词汇向量嵌入器的职责:将词汇转化为数字,以某种方式捕捉词汇的普遍含义。


虽然具体的实现方法可能因技术而异,但最终生成的成果可以视作一个“词空间”,这个空间遵循着一定的逻辑和关系。

单词本身在数学上难以直接运算,但蕴含单词信息的向量以及它们之间形成的关联,却便于数学操作。

这种将单词转化为向量的过程,我们通常称之为“嵌入”。Word2Vec,作为自然语言处理领域的一篇标志性论文,旨在生成具备特定实用特性的嵌入。

研究者们希望单词之间能够进行代数运算,而Word2Vec正是为了实现这一目标而创建的。

利用Word2Vec,当你嵌入“king”的向量,减去“man”的嵌入向量,再加上“woman”的嵌入向量,你将得到一个与“queen”含义相近的向量。


词汇嵌入的代数运算概念展示:如果将每个点视为从原点出发的向量,当你从“king”(国王)的向量中减去“man”(男人)的向量,并加上“woman”(女人)的向量时,得到的结果向量会接近于“queen”(女王)的向量。实际上,这些嵌入空间的维度要高得多,而“接近度”的度量标准也可能不太直观(如余弦相似度),但基本原理是相同的。


随着技术的不断进步,词嵌入仍然扮演着至关重要的角色,其中GloVe、Word2Vec和FastText都是备受推崇的选择。虽然子词嵌入通常展现出比全词嵌入更强大的性能,但这一话题已超出了本文范围。


另外大家想更进一步学习机器学习、深度学习、神经网络技术的可以看看以下文章(文章中提到的资料都打包好了,都可以直接添加小助手获取)


<


 人工智能资料分享 



>








人工智能60天学习计划(点击图片即可跳转)











深度学习中文教程书(点击图片即可跳转)


神经网络最全学习资料(点击图片即可跳转)







递归神经网络(RNNs)







当我们能够将单词转换为具有特定意义的数字向量时,便可以开始深入分析单词序列。

早期的一种有效策略是利用递归神经网络(RNNs),这种网络能够训练自身在顺序输入上循环运行,从而捕捉序列中的依赖关系。


RNN(循环神经网络)的基本概念:它是一种普通的全连接神经网络,但会将输出反馈到自身。


RNN的示意结构(假设有3个隐藏神经元并用于处理2个输入):图中红色箭头表示递归连接,它连接着来自后续递归层的信息。蓝色箭头表示内部连接,类似于密集层。为了说明起见,我们复制了神经网络,但请记住,网络实际上是反馈到自身的,这意味着第二个(及后续)模块的参数与第一个模块相同。


与传统神经网络不同,递归神经网络(RNNs)通过在循环连接中重用相同的参数,能够处理任意长度的序列。

这意味着,无论是长度为10的序列还是长度为100的序列,RNNs都只需要相同数量的参数。

这种网络结构因其灵活性而被广泛应用于多种建模问题,这些问题通常可以归纳为序列到序列建模、序列到向量建模、向量到序列建模,以及序列到向量再到序列的建模。


不同建模策略中RNN的一些应用概念图:序列到序列模型可能用于预测文本补全中的下一个单词;序列到向量模型可能用于评估客户对评论的满意度;向量到序列模型可能用于将图像压缩为向量,并要求模型将该图像描述为一系列文本;序列到向量到序列模型可能用于文本翻译,需要理解句子,将其压缩为某种表示,然后在另一种语言中构建该压缩表示的翻译。


尽管递归神经网络(RNNs)理论上能够处理无限长度的序列,但这一承诺在实际应用中并不完全实用。

由于RNNs的每一层都共享相同的权重,它们在处理长序列时容易出现“遗忘”输入内容的问题。

因此,RNNs在实际应用中通常只适用于处理非常短的单词序列。

为了克服这一局限性,研究者们曾尝试通过引入“门控”和“泄露”机制来改进RNNs。

其中最著名且有效的改进是长短期记忆网络(LSTM),我们将在下一节中对其进行详细描述。







长短期记忆(LSTMs)







LSTM(长短期记忆网络)的设计初衷是为了增强递归神经网络在保留重要信息方面的能力。

LSTM具备短期和长期记忆功能,能够在序列的任意位置中,选择性地保留或遗忘某些信息到其长期记忆中。


LSTM







LSTM的三个关键子组件







LSTM(长短期记忆网络)的核心概念体现在其三个关键的子组件上:“遗忘门”负责筛选并遗忘部分旧的长期记忆信息,“输入门”则负责将新的信息加入到长期记忆中,而“输出门”则负责控制从长期记忆中提取的信息,并将其作为下一次迭代的短期记忆使用。


LSTM中的参数。这个特定的LSTM期望一个维度为3的输入向量,并持有维度为2的内部状态向量。向量的维度是一个可配置的超参数。此外,请注意每个门控后面的“S”和“T”。它们分别代表sigmoid或tanh激活函数,用于将值压缩到一定的范围内,如0到1或-1到1。这种“压缩”使得网络能够“忘记”并“记忆”某些信息。图片由作者绘制,深受来源启发。


LSTM及其类似架构如GRU,相较于经典的RNN,展现出了显著的改进。

它们将记忆作为一个独立的概念,能够检查和提取关键信息,这使得它们在处理序列数据方面更具优势。

然而,尽管LSTM能够建模更长的序列,但在许多语言建模任务中,它们仍面临记忆遗忘的问题。

此外,由于LSTM和RNN一样,都依赖于前序输入进行逐步计算,因此它们的训练过程难以并行化,导致训练速度相对较慢。







通过对齐实现注意力机制







划时代的论文《通过联合学习对齐和翻译实现神经机器翻译》普及了注意力机制的概念,并为Transformer中的多头自注意力机制奠定了基础。

简单来说,注意力机制允许模型在生成输出时查看所有潜在的输入,并根据需要选择性地关注与当前输出相关的输入。换句话说,它赋予了模型决定哪些输入在特定时刻是重要或不重要的能力。

这种方法在翻译任务中产生了深远的影响。

它使模型能够更准确地捕捉输入中的关键信息,从而在翻译过程中展现出前所未有的性能。


正方形代表词汇向量嵌入,圆圈代表中间向量表示。红色和蓝色的圆圈是循环网络的隐藏状态,而白色的圆圈是通过对齐机制由注意力机制创建的隐藏状态。关键点是,注意力机制可以选择在任何给定步骤中呈现给输出的正确输入。


另外大家想更进一步学习机器学习、深度学习、神经网络技术的可以看看以下文章(文章中提到的资料都打包好了,都可以直接添加小助手获取)


<


 人工智能资料分享 



>








人工智能60天学习计划(点击图片即可跳转)











深度学习中文教程书(点击图片即可跳转)


神经网络最全学习资料(点击图片即可跳转)







Transformer







在前面的章节中,我们了解了一些基础。

接下来,我们将重点转向Transformer,这是一个集结了前人的成功智慧和新颖思想的杰作,它彻底革新了自然语言处理领域。


Transformer


我们将逐步拆解Transformer的每一个组成部分,深入探讨每个模块的工作原理。

虽然涉及的内容相当丰富,但我们会尽量避免复杂的数学推导,确保概念易于理解。







架构







Transformer本质上是一种编码器/解码器风格的模型,与我们之前探讨的序列到向量再到序列的模型类似。

编码器负责接收输入并将其转化为一个能够表达整个输入意义的紧凑表示,而解码器则基于这个嵌入,递归地构建并生成输出。


简述在序列到向量到序列任务中工作的转换器:输入(例如“我是一名经理”)被压缩成某种抽象表示,该表示编码了整个输入的意义。解码器以递归的方式工作,就像我们之前讨论的RNNs一样,以构建输出。


输入嵌入和位置编码


原始图中的输入嵌入


Transformer的输入嵌入策略与我们之前讨论的方法类似,它利用类似于Word2Vec的词空间嵌入器将输入单词全部转换为向量。

这些嵌入向量是与模型一同进行训练的,实际上可以看作是一个随模型学习而不断优化的查找表。

在初始阶段,每个单词都对应一个随机初始化的向量,但随着模型的学习过程,这些向量会根据每个单词在上下文中的表现而逐渐调整和优化。

与递归神经网络(RNNs)逐步处理序列的方式不同,Transformers能够一次性地编码整个输入序列。

然而,由于这种处理方式,Transformer编码器可能会失去有关输入单词之间顺序位置的信息。

为了弥补这一缺陷,Transformer引入了位置编码,以确保模型能够识别序列中单词的顺序。


"""Plotting positional encoding for each index.A positional encoding for a single token would be a horizontal row in the image
inspired by https://machinelearningmastery.com/a-gentle-introduction-to-positional-encoding-in-transformer-models-part-1/"""
import numpy as npimport matplotlib.pyplot as plt
#these would be defined based on the vector embedding and sequencesequence_length = 512embedding_dimension = 1000
#generating a positional encodingsdef gen_positional_encodings(sequence_length, embedding_dimension):#creating an empty placeholderpositional_encodings = np.zeros((sequence_length, embedding_dimension))
#itterating over each element in the sequencefor i in range(sequence_length):
#calculating the values of this sequences position vector#as defined in section 3.5 of the attention is all you need#paper: https://arxiv.org/pdf/1706.03762.pdffor j in np.arange(int(embedding_dimension/2)):denominator = np.power(sequence_length, 2*j/embedding_dimension)positional_encodings[i, 2*j] = np.sin(i/denominator)positional_encodings[i, 2*j+1] = np.cos(i/denominator)
return positional_encodings
#renderingfig, ax = plt.subplots(figsize=(15,5))ax.set_ylabel('Sequence Index')ax.set_xlabel('Positional Encoding')cax = ax.matshow(gen_positional_encodings(sequence_length, embedding_dimension))fig.colorbar(cax, pad=0.01)


位置编码示例:Y轴代表后续单词,X轴代表特定单词位置编码内的值。该图中的每一行代表一个单独的单词。


"""Rendering out a few individual examples
inspired by https://machinelearningmastery.com/a-gentle-introduction-to-positional-encoding-in-transformer-models-part-1/"""positional_encodings = gen_positional_encodings(100, 50)fig = plt.figure(figsize=(15, 4))for i in range(4):ax = plt.subplot(141 + i)idx = i*10plt.plot(positional_encodings[:,idx])ax.set_title(f'positional encoding {idx}')plt.show()


位置向量值相对于序列中不同索引的变化:K代表序列中的索引,图形代表向量中的值。


为了弥补Transformer在处理序列时可能丢失的单词位置信息,Transformer还引入了位置编码器。

这个编码器负责生成一个向量,该向量编码了特定单词在序列中的位置信息。

该系统巧妙地利用正弦和余弦函数来联合编码位置,使得位置信息得以连续和平滑地表达。

如果你想深入了解这种编码方式的工作原理,可以阅读相关的专业文章。

虽然你可能会担心,将这样的波形添加到单词嵌入中是否会掩盖原始嵌入的一些意义,导致模型混淆。

但实际上,神经网络(特别是Transformer,凭借其可学习的参数)非常擅长处理和理解平滑且连续的函数。

因此,对于足够大的模型来说,这种位置编码方式并不会对模型性能产生负面影响。

相反,它帮助模型更好地捕捉序列中单词的位置信息,从而提高了模型的性能。







多头自注意力机制:核心组件解析







在Transformer架构中,多头自注意力机制无疑是最为关键的子组件。


原始图中的多头自注意力机制


然而,将其简单地称为“注意力”机制可能略显误导,因为它实际上更多地扮演了“关联”和“情境化”的角色。

它使得单词之间能够相互交互,将输入的每个单词的嵌入向量列表转化为一个矩阵,这个矩阵能够全面表达整个输入序列的深层含义。


简单来说多头自注意力机制通过数学方式将不同单词的向量组合起来,形成一个矩阵,该矩阵编码了整个输入的更深层次的意义。


多头自注意力机制的运行过程可以分为四个主要步骤:

  • 创建查询(Query)、键(Key)和值(Value)

  • 分割成多个头(Heads)

  • 注意力头(Attention Head)

  • 构建最终输出多头自注意力机制


步骤 1) 创建查询、键和值

首先,我们需要理解“查询”、“键”和“值”这三个概念。尽管它们的命名可能让人联想到数据库中的概念,但实际上在自注意力机制中,这些术语只是抽象地表示了嵌入输入的不同方面。

查询、键和值本质上是输入嵌入的不同变换形式,它们将在后续步骤中用于相互之间的关联计算。


将嵌入的输入转换为查询、键和值。输入具有一个维度,即单词数量乘以嵌入大小。查询、键和值的维度都与输入相同。本质上,一个密集网络将输入投影到一个特征数量是输入三倍的张量中,同时保持序列长度不变。


上图所展示的密集网络结构包含了多头自注意力机制中的全部可学习参数。

多头自注意力机制实际上是一个可学习的函数,模型通过学习如何调整这些参数来优化输入(即查询、键和值)在最终建模任务中的表现。

在多头自注意力机制中,步骤2是将查询、键和值分割成多个“头”。

这一步是为了在实际进行情境化自注意力计算之前,增加模型的表示能力。

核心思想是,通过多个不同的“头”来捕捉输入数据中不同维度的关联信息,而不仅仅依赖于单一的关联方式。

这样做的好处是能够编码更加微妙和复杂的语义信息,从而提升模型在最终任务上的性能。


在这个例子中,我们有3个注意力头。因此,查询、键和值被分为3个部分,并传递给每个头。请注意,我们是沿着特征轴进行分割的,而不是单词轴。每个单词嵌入的不同方面被传递给不同的注意力头,但每个单词在每个注意力头中仍然存在。


多头自注意力机制 步骤 3) 注意力头

现在,我们有了被分割并传递给注意力头的查询、键和值的子组件,接下来将探讨注意力头是如何利用这些值来生成情境化结果的。

在《Attention is All You Need》这篇论文中,这一过程是通过矩阵乘法来完成的。


矩阵乘法


在矩阵乘法中,一个矩阵的行与另一个矩阵的列逐对进行点积运算,从而生成一个结果矩阵。

在注意力机制中,查询和键的矩阵通过乘法运算相结合,产生了一个我们称之为“注意力矩阵”的结果。


使用查询和键来计算注意力矩阵。请注意,键被转置以允许矩阵乘法产生正确的注意力矩阵形状。


尽管这种操作在表面上看似简单,但其影响力却不容忽视。在此步骤中,使用矩阵乘法使得每个单词的表示都能与其他单词的表示进行交互。

由于查询和键是由密集网络定义的,注意力机制学会了如何调整查询和键的表示,以优化注意力矩阵的内容。

一旦我们得到了注意力矩阵,就可以将其与值矩阵相乘。

这一步骤有三个主要目的:

  • 通过引入输入的另一种表示来增加情境化信息;

  • 创建了一个系统,使得查询和键的功能成为对值的一种变换,从而允许实现自注意力或交叉注意力,这取决于查询、键和值的来源;

  • 最重要的一点:这一操作确保了注意力机制的输出与输入具有相同的大小,这在某些实现细节上大大简化了处理过程。







重要的修正







在注意力机制中,注意力矩阵在与值矩阵相乘之前会经历一个关键的步骤——按行进行softmax运算。

这一数学细节至关重要,因为它彻底改变了注意力矩阵与值矩阵之间的交互方式,并赋予了其更深层的概念意义。

经过softmax处理后,注意力矩阵的每一行都转化为了一个概率分布,每个元素表示对应位置上的权重。

这种概率化的表示与我在另一篇文章中详细阐述的对齐注意力概念高度吻合,都强调了输入序列中不同部分之间的相对重要性。

这种处理方式不仅增强了模型的解释性,还使其能够更精准地捕捉序列中的关键信息。


从我的“注意力对齐”文章中可以看到,每一行都是一个概率分布,总和为1,这强制使最重要的事物与其他重要事物相关联。


这一细节在Transformer的广泛讨论中经常被忽视,但实际上是Transformer架构中至关重要的一个环节,因为它将模糊的关联性转化为稀疏且富含意义的选择。


注意力矩阵(即查询和键的矩阵乘法结果)乘以值矩阵,得出注意力机制的最终结果。由于注意力矩阵的形状,结果将与值矩阵具有相同的形状。请记住,这是来自单个注意力头的结果。


多头自注意力机制 步骤 4) 构建最终输出

在之前的步骤中,我们利用查询、键和值构建了一个新结果矩阵,这个矩阵的形状与值矩阵相同,但包含了更丰富的上下文信息。

值得注意的是,每个注意力头仅关注输入空间中的特定子组件(这些子组件是沿着特征轴划分的)。


回想一下,输入被拆分成了多个注意力头。在这个例子中,是3个头。


接下来,每个注意力头都会输出不同的结果矩阵。为了将这些结果整合起来,我们将它们沿着特征轴拼接(concatenate)在一起。


每个注意力头的结果会被连接在一起


这样得到的最终输出矩阵与原始输入矩阵的形状完全一致。

然而,与输入矩阵中每行直接与单个单词相关联不同,这个输出矩阵经过了多头自注意力机制的处理,因此包含了更为抽象和丰富的信息。


简而言之,注意力机制将嵌入的输入转换为富含抽象上下文的表示








Add and Norm







原始图中的Add and Norm


Add and Norm操作在Transformer编码器的每个子层中都被应用两次,且每次的效果都是相同的。

这两个操作的核心在于两个关键概念:残差连接(Residual Connections)和层归一化(Layer Normalization)。

残差连接在深度学习中是一种广泛使用的技术。

一个典型的例子是在U-Net架构中,它常用于图像分割任务。

简单来说,当模型进行复杂的计算时,有时可能会“迷失方向”。

虽然这背后有复杂的数学原理,如梯度爆炸或模型秩的崩溃,但从直观上理解,模型可能在处理问题时“过度思考”。

在这种情况下,通过残差连接重新引入输入数据,可以帮助模型保持一些简单的结构,从而防止其偏离正确的方向。

在Transformer中,Add操作实际上就是实现了这种残差连接,确保了信息能够顺利地从前一层传递到下一层,而不会因为模型的复杂计算而丢失。

Norm操作,即层归一化,则确保了每一层神经元的激活值都在一个稳定的范围内,进一步稳定了模型的训练过程。

这两者的结合使得Transformer模型能够处理更深的网络结构,同时保持高效的训练速度和良好的性能。


跳跃连接加法的可能形式如下。在这个例子中,左边的矩阵代表原始编码的输入。中间的矩阵代表来自注意力矩阵的高度上下文化结果。右边的矩阵代表跳跃连接的结果:一个仍保留原始输入某些顺序的上下文感知矩阵。


层归一化在功能上类似于跳跃连接,但它在概念上起着约束数据偏差的作用。

在深度神经网络中,数据经过多层的计算后,可能会出现极大的或极小的值,这是由于连续的非线性变换和参数更新所导致的。对于这类数据,如果直接进行后续的计算,可能会导致模型训练的不稳定。

层归一化通过计算当前层激活值的均值和标准差,然后利用这些统计量将数据标准化到一个合理的分布范围内,从而解决了上述问题。

这个过程有助于确保模型的稳定性和训练效率,因为标准化后的数据更容易被网络处理,并且能够减少梯度消失或梯度爆炸的风险。

简而言之,层归一化是Transformer等深度学习模型中不可或缺的一部分,它确保了数据在网络中的流动是可控和有效的。







前馈神经网络(Feed Forward)







原始图中的前馈网络


在注意力机制处理之后,我们得到的输出会通过一个简单的密集网络(或称为前馈网络)。

这个步骤可以被视为一种投影,模型能够学习如何将注意力机制的输出转换为对解码器更为合适的格式。

随后,前馈网络的输出会再次通过一个包含加法操作和归一化的层(通常是残差连接和层归一化的组合),得到最终的解码器输入表示。

这个最终表示将被解码器用于生成输出序列。







解码器的主要功能







在之前的部分中,我们已经深入了解了编码器的工作机制,并得到了输入数据的高度上下文化表示。

接下来,我们将探讨解码器如何利用这些表示来生成输出序列。


编码器输出与解码器之间关系的高级表示。解码器在每次递归输出循环时都会参考编码后的输入。


解码器与编码器在结构上有很多相似之处,但也存在一些关键的变化。在讨论这些变化之前,我们先来概述一下它们的相似之处。


Transformer架构


如上图所示,解码器采用了与编码器相同的词嵌入方法和位置编码技术。

然而,解码器在自注意力机制中使用了“掩码”技术,这将在后续章节中详细讨论。

此外,解码器还包含另一个多头注意力块,这个注意力块使用了编码器的输出作为键和值,而查询则基于解码器的输入。

通过这种方式,解码器能够综合考虑编码器输入和解码器输入的信息,从而决定最终的输出内容。

在通过多头注意力块之后,解码器的输出会再次经过一个前馈网络、一个加法归一化层、一个线性层以及一个softmax函数。

这个softmax函数会输出一个概率分布,表示每个可能输出单词的概率。

这样,模型就能够根据这些概率分布来选择最终的输出单词,完成整个翻译或生成任务。







Masked Multi Headed Self Attention







解码器的独特之处在于它采用了“掩码”注意力机制。这一机制与模型的训练方式紧密相关。

传统的递归神经网络(RNN)有一个核心缺陷,即它们需要按顺序进行训练。


RNNs 揭示了步骤之间的紧密依赖关系


RNN在预测下一步时高度依赖于前一步的分析结果,这导致RNN的训练速度相对较慢,因为训练集中的每个序列都必须逐一通过模型进行训练。

然而,通过对注意力机制进行巧妙的修改,Transformer模型能够克服这一限制,实现并行训练。


掩码多头自注意力机制中掩码的工作方式(以英语到法语翻译任务为例)。该任务的输入是短语“I am a manager”,期望的输出是短语“Je suis directeur”。请注意,为了简化起见,我通常忽略了功能标记(utility tokens)的概念。不过,这些标记很容易理解,比如用于开始序列、结束序列等。


在训练过程中,由于我们知道所需的输出序列,因此可以将整个输出序列(包括尚未预测的部分)同时输入到解码器中,并利用掩码来隐藏这些尚未预测的输出。

这种方法允许模型同时对序列中的所有位置进行训练,大大提高了训练效率。

我们深入探讨了Transformer模型的技术创新和工作原理,包括其编码器-解码器架构以及重要的子组件,如多头自注意力、输入嵌入、位置编码、残差连接和层归一化。

特别强调了解码器中的“掩码”注意力机制,它使得模型能够实现对整个序列的并行训练,从而显著提升了训练效率。


作者:Daniel Warfield


53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询