注意力模块存在于编码器栈和码器栈的每个编码器中。我们首先来详细了解一下编码器的注意力机制。
以英译西举例,源序列示例是 "The ball is blue.",目标序列是 "La bola es azul"。
源序列首先经过嵌入和位置编码层,每个词被生成嵌入向量。嵌入向量随后被传递到编码器,编码器首先会经过注意力模块。
在注意力机制中,嵌入的序列会经过三个线性层,生成三个独立的矩阵:查询矩阵、键矩阵和值矩阵,用于计算注意力得分。
需要注意的是,这些矩阵的每一行都对应于源序列中的一个单词。
输入的每一行都是序列中的一个单词
要理解注意力机制的运作方式,需要从源序列中的各个词语入手,追踪它们在 Transformer 模型中的处理路径,,即注意力模块内部的运作机制。
这将有助于理解源序列和目标序列中的每个词是如何与其他词相互作用的。
因此,在下面的解释中,请集中注意力关注每个词所执行的操作,以及每个向量如何映射到原始输入词。如果矩阵形状、算术运算的具体细节、多个注意力头等与每个词的去向没有直接关系,直接忽略这些细节。
为了简化解释和可视化,我们忽略嵌入维度,只跟踪每个单词的行。
每个词都经过一系列「可学习的」变换
上面说的每一行,都是由它对应的源词,经过一系列变换生成的:嵌入、位置编码、线性层。
所有这些转换都是可训练的操作。这意味着这些操作中使用的权重并非预先设定,而是由模型学习,从而产生所需的输出预测。
关键问题是,Transformer 如何确定哪组权重能带来最佳结果?我们稍后会再讨论。
注意力分数:Query 词和 Key 词之间的点积
注意力机制执行多个步骤,我们只关注线性层和注意力分数。
从公式可以看出,注意力机制的第一步是对查询矩阵(Q)和键矩阵(K)的转置进行矩阵乘法(即点积)。观察每个词的变化。
我们生成一个中间矩阵(我们称之为「因子矩阵」),其中每个单元格都是两个单词之间的矩阵乘法
例如,第四行的每一列对应于第四个查询词与每个关键词的点积。
注意力得分:查询词和值词之间的点积
下一步是将中间「因子矩阵」与值 (V) 矩阵相乘,得出注意力模块输出的注意力分数。可以看到,第四行对应于第四个查询词矩阵与所有其他键值对的乘积。
这样就产生了注意力模块输出的注意力得分向量(Z)。
理解输出得分的方法是:对于每个词,它是「值矩阵」中所有词的编码值乘以「因子矩阵」的权重。「因子矩阵」是该特定词的查询值与所有词的键值的点积。
查询词、键和值的作用
Query 词:可以理解为 "我正在为它计算注意力" 的那个词。
Key 和 Value 词:是 "我正在关注"的那个词,换句话说,就是"这个词跟我的 Query 词有多相关"。
举个例子。对于 "The ball is blue" 这个句子,"blue" 那一行里,包含了 "blue" 与其他每个词的注意力分数。在这个例子里, "blue" 就是 Query 词,而其他词就是 Key / Value。
注意力计算里还有别的操作,比如除法和 Softmax。暂时忽略它们。这些操作只是改变矩阵里的数值,但不会影响每个词所在的行在矩阵中的位置,也不会引入任何词与词之间的交互。
点积,揭示词与词之间的相似度
我们已经看到,注意力分数通过计算点积并将结果相加,捕捉到特定词语与句子中其他所有词语之间的某种交互作用。但是,矩阵乘法是如何帮助 Transformer 确定两个词语之间的相关性的呢?
为了理解这一点,请记住,查询行、键行和值行实际上是具有嵌入维度的向量。让我们深入了解一下这些向量之间的矩阵乘法是如何计算的。
当我们对两个向量进行点积运算时,我们将成对的数字相乘,然后将它们相加。
如果两对数字(例如上面的 a 和 d)均为正数或均为负数,则它们的乘积为正数。乘积会增加最终的总和。
如果一个数是正数,另一个数是负数,那么它们的乘积将为负数。乘积会减少最终的总和。
如果乘积为正数,则两个数越大,它们对最终总和的贡献就越大。
这意味着,如果两个向量中对应数字的符号一致,则最终的总和会更大。
不同词之间的相关性
点积的这个特性,同样适用于注意力分数。如果两个词的向量更对齐(也就是符号一致的部分更多),那么注意力分数就更高。
那么,我们希望 Transformer 表现出什么样的行为呢?
对于句子里彼此相关的两个词,希望注意力分数高。
对于不相关的两个词,希望注意力分数低。
举个例子。对于 "The black cat drank the milk" 这个句子:
"milk"(牛奶)和 "drank"(喝)非常相关。
"milk" 和 "cat"(猫)可能稍微有点相关(但没那么强)。
"milk" 和 "black"(黑色的)则基本不相关。
我们希望模型学到的输出是这样的:
"milk" 和 "drank" 产生高注意力分数。
"milk" 和 "cat" 产生一个稍低的分数。
"milk" 和 "black" 产生一个可以忽略不计的低分。
为了达到这个效果,"milk" 和 "drank" 的词向量必须对齐;"milk" 和 "cat" 的词向量会有些分歧;而 "milk" 和 "black" 的词向量则会相当不同。
现在,回到前来遗留的问题:Transformer 是怎么知道哪一组权重能给它带来最佳结果的?
这些词向量,是基于词嵌入和线性层的权重生成的。因此,Transformer 可以去学