原文:
towardsdatascience.com/multi-head-attention-formally-explained-and-defined-89dc70ce84bd
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/417cbccda279e8c55f4619bfafffb302.png
多头的机器人,正在关注 – 图由作者(AI 生成,Microsoft Copilot)
多头注意力在 transformers 中扮演着至关重要的角色,而 transformers 已经彻底改变了自然语言处理(NLP)。理解这一机制是获得当前最先进语言模型清晰图景的必要步骤。
尽管这个概念几年前就被提出,并且自那时以来已被广泛使用和讨论,但模糊的符号和缺乏正式定义阻碍了新来者迅速揭开多头注意力机制的神秘面纱。
在本文中,目标是提供一个全面且明确的正式化多头注意力,以便使这一机制易于理解。
由于为了更好地理解新概念,亲自使用它们是至关重要的,因此本文附带了一些练习/问题(附带解决方案),以便精确地了解多头注意力发生了什么。
免责声明:在开始定义和解释多头注意力之前,请注意,LaTeX 支持的缺失迫使我将方程转换为图像以显示不同的数学对象。
输入
首先,让我们明确多头注意力机制的输入。我们定义多头注意力层的输入为:
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/cc329c66033f5336335084657d69c214.png
输入 – 图由作者提供
其中X是一个有n行和d列的矩阵,这两个维度对应于:
n:输入序列的长度。(标记的数量)
d:标记向量的维度。
序列长度
通常,我们为所有序列设置一个默认的固定长度n。它通常取值如 256 或 512(在“Attention Is All You Need”,Vaswani 等人,2017 年使用过的值)。然后,所有输入序列都被填充或截断,以便它们最终恰好有n个标记。
这可以看作是一个序列中的单词数量。
因此,X的每一行对应于输入序列中的一个标记。
标记维度
当我们对一些文本进行标记化时,它被转换成一个由标记组成的序列,每个标记由一个特征向量表示。
标记向量可以是什么的最简单例子是由 one-hot 编码给出的:如果你有一组 1,000 个可能的标记,每个标记可以通过一个 1,000 维的二进制向量来建模,其中 999 个组件设置为0,一个1用于与给定标记关联的组件。在这里,d将是 1,000。
这就是为什么输入序列的每个n个标记,由X的一个行表示,都带有d列。
练习 1 – 建模输入序列
我们希望在以下假设下对句子“注意力即所需”进行建模:
输入序列的固定长度为n = 8。
可以建模的标记集合是T ={“all”, “attention”, “cat”, “is”, “need”, “transformer”, “you”}。
标记向量是基于可能的标记集合T的独热编码表示。
我们不考虑特殊标记,如“序列结束”标记。(如果你不理解这个假设,那完全没问题。)
Q1:在这里,标记向量的维度d是多少?
Q2:根据我们刚刚做出的假设,给出“注意力即所需”的输入矩阵X。
(以下为“回顾”部分后的解决方案。)
回顾
在多头注意力中,我们将包含整个已标记输入序列的类似矩阵的X传递到多头注意力层。
解决方案 – 练习 1
Q1:在这里,可能的标记集合T包含七个标记,我们假设我们使用独热编码来建模标记。因此,d = 7(集合T中的标记数量)。
Q2:首先,我们知道n = 8和d = 7,因此我们知道我们应该得到一个有八行七列的矩阵X。
每一行都应该对应输入句子中的每个标记。然而,正如你可能注意到的,“注意力即所需”只包含五个标记。你如何在矩阵中填充八行?
一种选择是在输入序列中填充空标记,这将导致X的底部出现三个空行。
*NB:另一种方法是将空标记包含在可能的标记集合中,即T ={“all”, “attention”, “cat”, “is”, “need”, “transformer”, “you”, ∅},其中 ∅ 是空标记。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/56fab77261b49cfc2fe3b77be3ce4f82.png
带填充行的输入矩阵 – 图片由作者提供
现在,我们通过正确编写独热向量来完成X的填写。你最终应该得到以下矩阵:
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/db67173d6d4a8d0b7a9920ce28455b58.png
输入矩阵示例 – 图片由作者提供
查询、键、值
在“多头注意力”中,有“多头”,这意味着使用这种机制的层将使用多个头。
如果“头”这个术语对你来说不清楚,你可以将其视为“映射”或“层”。
设h为多头注意力层中将有的注意力头数。
现在,让我们定义什么是查询、键和值。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/cddb678fe220399bccc12b36bfbabad1.png
查询、键和值定义 – 图片由作者提供
虽然它们的名称不同,但查询、键和值本质上具有相同的定义:它们是输入矩阵与权重矩阵的乘积。
在这里,当k和v是正整数时,权重矩阵位于以下矩阵空间中:
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/afc174ce849fe51d690e8c814849aa30.png
查询、键和值权重矩阵 – 作者图片
权重矩阵在不同的h个头之间是不同的,因此下标是i,其中i的范围从1到h。
权重矩阵在查询、键和值之间是不同的,因此有上标 "Q"、 "K"和 "V"来区分它们。
在论文 “Attention Is All You Need” (Vaswani et al., 2017) 中,k和v通常设置为k = v = d / h.
练习 2 – 查询、键和值
以下矩阵的维度是什么?
一个查询Q?
一个键K?
一个值V的维度是多少?
(以下为 “回顾” 之后的解决方案。)
回顾
到目前为止,没有什么异常。我们只定义了几个矩阵。最具挑战性的部分是跟踪矩阵维度。
解决方案 – 练习 2
在仔细阅读矩阵乘法之后,你应该得到查询、键和值矩阵的以下维度:
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/ebfda253820f808d103d3353193c82e9.png
查询、键和值维度 – 作者图片
注意力
注意力可以定义为以下映射:
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/d01fd860a32d8cabaf15383196ee9ed8.png
注意力函数 – 作者图片
其中softmax函数是在行上取的:
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/611950ef56110bb773817252103e5ee6.png
Softmax 函数 – 作者图片
作为提醒,softmax函数是一种将向量中的值归一化的方法。它将它们转换成一个系数之和为 1 的向量,使得softmax的输出可以表示一个概率分布。
练习 3 – 注意力和矩阵维度
以下矩阵的维度是什么?
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/a528c51c94f40fa16cb44dea683ebb56.png
注意力和矩阵维度(练习)- 作者图片
练习 4 – 注意力解读
将以下短语与其对应的数学表达式匹配。给定的短语之前没有介绍,但可以通过解释数学表达式来猜测它们。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/e7b3134a14e248e0d94b0a11148d6b1a.png
将短语与其对应表达式匹配 – 作者图片
练习 5 – 解读矩阵
Q1:对于给定的查询Q,
一行Q代表什么?
一列Q代表什么?
(对于键K和值V也可以做出相同的解释。)
Q2:对于给定的查询Q和给定的键K,行i和列j,下面的系数代表什么?
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/22d3ac8872dab5dc6b60f9a90f51058a.png
QK^T 系数 – 图像由作者提供
Q3:对于给定的查询Q和给定的键K,我们如何解释以下矩阵的行?
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/c451a0cb7f627ea4a1b652970053fa3a.png
注意力权重 – 图像由作者提供
(以下“回顾”之后提供解决方案。)
回顾
总的来说,我们现在可以了解任何给定注意力头内部发生的事情,如下所示。
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/424f18b2c06280b34f46ac76af5dab49.png
注意力头对输入的操作 – 图像由作者提供
解决方案 – 练习 3
我们依次获得了以下矩阵的维度:
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/c68bbcf6997c5e2bd78c5cfb7bcd3578.png
注意力和矩阵维度(解决方案)- 图像由作者提供
解决方案 – 练习 4
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/dd6060aee1e2ea5ef8d44b204de128e7.png
匹配短语和表达式 – 图像由作者提供
(缩放的)注意力分数是输入标记在查询空间和键空间中的投影之间的点积。它们提供了一个原始分数,“每个输入标记对每个输入标记的关注程度”。
注意力权重从上述注意力分数中创建一个概率分布。
缩放点积注意力基于注意力权重和值空间中的输入投影,给出了输入序列的新潜在表示。
解决方案 – 练习 5
Q1:由于查询Q是输入X在查询空间中的投影,并且基于Q的维度,你可以推断出:
一个Q的行代表一个输入标记向量,在查询空间中表示。
一个列的Q代表查询空间中的一个潜在维度。
Q2:在Q和K的转置之间的乘积的第i行和第j列的系数代表输入序列的第i个标记与第j个标记的相关程度。
这个系数越高,第i个标记与第j个标记的相关性(~相似性)就越高。
Q3:首先,注意力权重矩阵每一行的和等于 1。
该矩阵的第i行可以解释为当我们查看标记i时,输入序列标记对序列意义的贡献的概率分布。
多头注意力
现在,在多头注意力机制中,不同的头发生了什么?
连接
所有不同头部的输出在行方向上连接,并与输出权重矩阵相乘:
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/5ccd04252df56cfae825e00d02f9527d.png
多头 – 作者图片
再次强调,这并不太技术性,最具挑战性的部分仍然是记住不同矩阵的维度。
练习 6 – 多头维度
以下矩阵的维度是什么?
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/56dfb7effd34674e146840d71f234e02.png
多头维度(练习)- 作者图片
练习 7 – 输出解释
当它被引入时,多头注意力应用于机器翻译,用于翻译英语和德语之间的句子。
注释输入X和输出Y = MultiHead(X)的维度。
练习 8 – 为什么有多个?
为什么要有多个注意力头?特别是,你看到不同头如何相互作用吗?
(以下为“回顾”后的解答。)
回顾
多头注意力最终只是简单地将不同预定义注意力头的输出连接到一个大矩阵中。然后,它被转换为一个nxd输出矩阵,与输入的维度相匹配。
解决方案 – 练习 6
这些矩阵的维度,它们介入多头注意力,是:
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/ebc0521da7b81e5ed5b61ef9ca5f193e.png
多头维度(解决方案) – 练习 7
解决方案 – 练习 7
如你所注意到的,输入X和输出Y = MultiHead(X)的维度是匹配的,因为它们都是nxd。
因此,多头注意力的输出可以解释为其输入的重构,或者至少是另一个具有相同固定长度的序列。
由于多头注意力最初是为机器翻译引入的,因此可以将输出解释如下:给定一个由矩阵X模型的英语输入序列,多头注意力层输出一个矩阵Y,该矩阵模拟了输入序列翻译成德语(或任何其他语言)。
解决方案 – 练习 8
首先,使用多个不同头部的想法是让多个头部关注不同标记之间的关系。
事实上,不同的头在多头注意力的最后阶段相互作用:
https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/a7d1e65713eaf1ae1c3c99d5005e3074.png
详细输出系数 – 作者图片
对于每个给定的标记,所有头部的输出都会相加。这就是不同头部相互作用的地方。
结论
总的来说,多头注意力包括利用两件事将输入序列X转换为输出序列Y:
注意力机制
多个注意力头的连接
要正确理解这个机制,最重要的是清楚地识别在整个计算过程中使用的所有矩阵的维度。