Transformer模型凭借其卓越的能力,可以并行处理大量数据,为理解和生成人类语言带来了重大进步,彻底改变了自然语言处理(NLP)领域。这篇文章深入剖析了为Transformer模型准备数据的复杂机制,特别是聚焦于以下三个基本要素:
我们的任务是训练一个模型,只需给出前半句:
“生活就像骑自行车。”
它就能生成后半句。我们将逐步走过这个过程,以理解Transformer如何处理输入。
第一步:输入数据处理
使用任何机器学习模型的第一步都是处理输入数据。在我们的例子中,输入文本是:
“生活就像骑自行车。”
计算机无法直接理解人类语言。它们需要将文本以数字形式表示——使用向量、矩阵或数字序列。这种转换使得像Transformer这样的模型能够处理数据并从中学习。
构建词汇表:
首要任务是创建一个词汇表——一个包含训练数据集中每个单词的字典。例如,如果我们的训练数据包含各种励志名言,我们的词汇表可能包括“生活”、“平衡”、“自行车”、“前行”等词汇。每个单词都映射到一个唯一的索引。因此,训练数据中所有不重复的单词将组成词汇表。
分配数字索引:
接下来,我们为词汇表中的每个单词分配一个唯一的数字索引。这样,我们就可以用数字来表示单词了。
提取输入单词:
对于输入文本“Life is like riding a bicycle”,我们提取相应的索引如下,
转换成序列:
这一系列的索引就是输入到Transformer模型中的数据。它作为输入文本的数值表示,使模型能够对其进行处理。
第二步:词嵌入
一旦我们有了输入序列的索引,下一步就是将这些索引转换成词嵌入。词嵌入将每个单词表示为固定大小的向量,使得模型更容易捕捉单词之间的语义关系。
什么是词嵌入?
词嵌入是编码单词语义信息的高维向量,相似的单词或经常同时出现的单词具有相似的嵌入。这些向量可以想象成一个多维空间(通常是数百个维度,如原始Transformer论文中的512维),在这个空间中,由于上下文相似,“bicycle”(自行车)和“ride”(骑行)之间的距离比“bicycle”(自行车)和“cloud”(云)之间的距离更近。嵌入的每个维度都捕捉了某些语言特征,比如一个单词是动词还是实体。然而,由于这些特征是在训练过程中学习的,因此确定每个维度的确切含义可能具有挑战性。
嵌入层:
我们序列中的每个词索引都会通过一个嵌入层。这个层将每个索引映射到一个实数向量。原始的Transformer论文中使用的嵌入大小为512。
学习有意义的表征:
最初,这些嵌入是随机分配的。在训练过程中,Transformer会根据给定的任务调整这些向量,以更好地表示单词的含义。例如,“life”(生命)和“existence”(存在)的嵌入可能会随着时间的推移而变得更加接近,因为它们具有相似的含义。
嵌入的可视化:
想象一下在多维空间中绘制单词。像“life”(生命)、“alive”(活着的)和“survival”(生存)这样的单词会聚集在一起,而像“bicycle”(自行车)和“cloud”(云)这样的单词则会相距较远。
这有助于Transformer不仅理解单个单词,还能理解它们在给定上下文中的相互关系。嵌入层有助于将原始数值输入转换为Transformer可以用来理解文本的丰富表征。
第三步:位置嵌入
现在我们已经有了词嵌入,接下来需要解决一个关键问题——Transformer天生并不理解单词的顺序。与像LSTM这样的循环模型逐个处理序列中的单词不同,Transformer会同时查看所有单词。虽然这使得它们更快,但也意味着它们缺乏单词出现顺序的信息。
考虑以下两个句子:
“Life is like riding a bicycle, it requires balance.”(生活就像骑自行车,它需要平衡。)
“Life requires balance, like riding a bicycle.”(生活需要平衡,就像骑自行车一样。)
这两个句子包含相同的单词,但结构略有不同,导致意义上有细微差别。为了让Transformer捕捉到这些差异,我们需要添加关于单词顺序的信息——这就是位置嵌入发挥作用的地方。
为了给Transformer提供单词顺序的感知,我们将位置嵌入添加到词嵌入中。输入序列中的每个位置都会获得一个唯一的向量,该向量编码了其位置。
方法1:基于整数的位置编码
一个直接的想法是给每个位置分配一个对应的整数。例如,第一个词的嵌入会携带一个全零向量,下一个词则是一个全一向量,依此类推。然而,这种方法很快就会暴露出局限性。随着序列长度的增加,分配给后续单词的较大数字可能会压过底层的词嵌入,导致表示发生偏斜。这种不对齐可能会影响模型保持语义一致性的能力,尤其是在较长文本中。例如,e30和p30这样的数字会过度扭曲嵌入。
方法2:相对于序列长度的分数位置表示
另一种直观的方法是将每个单词的位置表示为总序列长度的一个分数,确保值在0到1之间保持归一化。例如,在一个包含四个单词的句子中,位置嵌入可能对应于像0.25、0.5这样的值。
这一策略虽然看似有效,但却引入了一个重大挑战:相同位置(例如,第二个单词p1)的位置嵌入会因序列长度的不同而变化,从而引入不一致性,这可能会使模型感到困惑并降低性能。为了获得最佳结果,位置值理应独立于序列长度。
方法3:正弦位置嵌入
下一种方法利用正弦函数来生成位置嵌入,从而在x轴上创建一条平滑的波浪形曲线来编码单词位置。通过将单词位置映射到正弦波的高度,每个位置都会在一个有限范围内获得一个唯一值,无论序列长度如何。这种方法通过标准化位置嵌入值,缓解了之前方法中出现的扭曲风险。
然而,一个缺点出现在曲线上对称位置的单词上(例如,在可视化环境中用蓝色和紫色等颜色表示);尽管这些单词的位置不同,但它们产生的位置值却相同,这可能导致潜在的歧义。
方法4:受二进制启发的编码
最后,一种创新的视角借鉴了二进制表示原理。在二进制编码中,比特率的变化是可预测的;最低有效位在每个数字间交替变化,下一个较低的位在每两个数字间交替,依此类推。
将这种概念从二进制位转换为浮点数,可以实现一种紧凑且高效的编码机制,该机制能够在不占用过多计算资源的情况下保持单词位置的唯一性。这种受二进制启发的方法为Transformer中位置嵌入的设计提供了一条有前景的道路。
Transformer方法:使用正弦函数的位置编码
在Transformer的背景下,通过正弦函数嵌入单词位置提供了一种精细的方法来连续捕获位置信息。该解决方案通过使用交替的正弦和余弦函数,解决了传统位置编码的挑战。这些函数表示出类似于二进制位模式的连续、平滑波形,但在基于浮点数的系统中更加灵活和高效。
正弦频率调制
为了避免位置嵌入的冗余,不同位置使用不同频率的正弦函数,引入了一种微妙但强大的手段来区分序列中即使位置相近的单词。
其原理如下:如果两个点在低频正弦波上靠得很近,那么它们将难以区分;然而,高频会放大波形高度的差异。因此,每个位置及其频率共同构成了序列中单词的整体顺序信息。
这种方法依赖于根据每个嵌入维度调整正弦频率,使得在较低频率下能够区分较近的单词,而在较高频率下,相隔较远的单词则表现出明显的差异。这种频率调制确保模型能够准确识别输入中单词之间的即时和远距离关系。
因此,为了实现有效的位置编码,一个关键方面是频率调制,它必须根据嵌入向量中的每个位置而变化。在这里,变量i在产生这些变化中起着关键作用。通过在不同的i值下重新计算正弦曲线,我们在嵌入维度上生成了一系列具有不同频率的曲线,为每个位置pos创建了细微差别的位置嵌入。在这里,d=512,是位置嵌入的维度。
让我们通过一个例子来阐明这一点。假设我们需要确定位于“蓝色”和“紫色”位置的单词的位置嵌入。当在低频率下(例如,在第三个嵌入维度中)检查这些嵌入时,这两个位置的值最初可能看起来是相同的。然而,随着我们增加频率——或者向第一个嵌入维度推进——这些值开始显著不同。这种差异在高频率下尤其明显,即使是很小的位置差异也会变得非常显著。
因此,这种频率调制确保了序列中每个单词的位置嵌入保持唯一性,为模型提供了单词位置之间的强有力区分,这对于在复杂序列中保持上下文完整性至关重要。
双正弦方法:同时使用正弦和余弦
为了进一步增强区分度,作者同时使用了正弦和余弦函数。序列中的奇数位置使用正弦函数,而偶数位置则依赖余弦函数。这种双重方法为Transformer提供了更强大的编码机制;正弦和余弦的结合支持通过sin(x)和cos(x)的线性调整来实现sin(x + k)和cos(x + k)之间的转换。重要的是,这是单独使用正弦或余弦函数无法实现的。原始的Transformer论文使用了以下公式进行位置编码:
其中:
• pos是单词在序列中的位置
• i是维度索引(范围从0到d_model/2-1)
• d_model是模型嵌入的维度
正弦函数的频率由以下项决定:
10000^(i/d_model)
这个项表示正弦函数的波长。随着i的增加,这个项会减小,这意味着频率会增加。
其工作原理如下:
直观理解
频率和维度索引i之间的这种关系有几个目的:
通过使频率相对于i呈指数变化,位置编码同时捕获了细粒度(高频)和粗粒度(低频)的位置信息,使模型能够在不同尺度上有效利用位置信息。这种方法使模型能够理解,尽管“bicycle(自行车)”出现在“life(生活)”之后,但在我们示例引文的上下文中,它们是密切相关的。
第四步:整合单词嵌入和位置嵌入
现在我们已经有了单词嵌入和位置嵌入,我们将它们结合起来以创建位置感知的单词嵌入。这些嵌入随后被传递到Transformer的其余层中,模型在那里学习单词及其在句子中的位置之间的复杂关系。
通过添加位置嵌入而不是连接它们,Transformer可以更自然地将单词含义与位置信息结合起来。这种方法还确保模型能够处理不同长度的句子,而不会因为位置编码的变化而感到困惑。
在Transformer模型中,将位置嵌入(PE)与单词嵌入(WE)进行连接(而非相加)的战略意义是什么?
将PE与WE连接允许模型独立处理位置信息和语义信息,这可能增强模型区分位置上下文和单词含义的能力。这可以在自然语言处理(NLP)应用中解锁新的功能,特别是那些需要细致上下文理解的应用。然而,连接会增加模型的复杂性,需要投影层来保持原始维度,并可能影响内存使用和计算成本。对于高性能用例来说,准确性和资源需求之间的这种权衡是一个至关重要的考虑因素。
Tensor2Tensor(T2T)在其位置编码中为何强制设置max_timescale为10,000,这对Transformer性能有何影响?
T2T的max_timescale=10,000强制位置编码具有周期性,意味着位置编码在每10,000个标记后重置。这种设置降低了长序列的复杂性,但也可能减少PE在较短序列中的贡献。对于较短的序列,特别是在语言建模等任务中,PE的维度影响可能变得微不足道,从而将重点转移到WE上。了解这种平衡有助于从业者基于序列长度和所需的上下文敏感性来调整Transformer架构。
在Transformer中,将位置嵌入和单词嵌入相加如何影响位置信息和语义信息的分离?
将PE和WE相加会产生一定程度的交互,可能会模糊位置信息和语义信息之间的区别,但这种重叠可能是有利的。对于某些NLP任务,相加可以增强位置依赖性,使单词表示能够根据句子位置进行调整。这种协同作用可能提高位置敏感任务(如命名实体识别或机器翻译)的模型准确性,在这些任务中上下文细微差别至关重要。
基于观察到的用例,在什么情况下相加嵌入可能优于连接?
在严重依赖上下文混合的模型中,如处理双向序列依赖(例如双向LSTM)或多分辨率嵌入(例如基于字符和基于单词的嵌入)的模型,相加嵌入已显示出性能提升。相加可以加强对于单词关系和位置细微差别至关重要的任务中有益的上下文交互,如情感分析或对话AI。这一发现表明,在任务结果依赖于语义空间内强位置影响的情况下,相加可能是首选。
在Transformer架构中,跳跃连接在增强PE和WE之间的协同作用方面扮演了什么角色?
跳跃连接允许PE和WE信息在Transformer层之间持续集成,增强了它们对中间表示的影响。这种持续集成有助于在整个网络中保持句法结构和位置细微差别,增强了模型处理复杂句法(如翻译和语言生成任务)的能力。对于部署基于Transformer解决方案的企业而言,这意味着在分层上下文挑战中模型性能的一致性得到改善。
T2T的位置编码策略如何影响Transformer与旧有嵌入(如word2vec)的兼容性?
T2T中的位置编码在Transformer中引入了独特的空间关系,使其在功能上不同于缺乏位置感知的旧有嵌入(如word2vec)。对于希望将预训练嵌入与Transformer集成的企业来说,了解这种差异可以指导适应策略,如微调或混合嵌入方法,以实现对齐,同时不牺牲位置敏感任务上的性能。
结论
Transformer初看可能很复杂,但分解其组件后,我们会发现它是一个既优雅又有效的系统。无论是生成文本、总结文章还是翻译语言,Transformer都依赖这些基本构建块来理解和生成人类语言。