自注意力
0. 什么是自注意力机制
自注意力类似于注意力机制,它们从根本上共享相同的概念和许多常见的数学运算。自注意力模块根据k个输入,返回k个输出。此模块中允许输入相互交换信息,并找出他们应该更加关注哪个输入。
自注意力机制分为以下步骤:
- 准备输入
- 初始化权重
- 派生键、查询和值
- 计算输入1的注意力得分
- 计算softmax
- 分数与值相乘
- 对加权值求和得到输出1
- 为输入2和输入3重复步骤4-7
注意:数学运算是向量化的,即所有输入一起进行数学运算。
1. 准备输入

在本教程中,假设有3个输入,每个输入的维度为4。
Input 1: [1, 0, 1, 0] Input 2: [0, 2, 0, 2] Input 3: [1, 1, 1, 1]
2. 初始化权重
每个输入必须有三种表示(见下图)。这些表示称为键(橙色)、查询(红色)和值(紫色)。在这个例子中,我们假设这些表示的维数是3。因为每个输入的维度都是4,这意味着每个权重集合的形状都必须是4×3。

为了获得这些表示,每个输入(绿色)都要与键的一组权重相乘,与查询的一组权重相乘,与值的一组权重相乘。在我们的例子中,我们初始化三组权重如下。
Weights for key: [[0, 0, 1], [1, 1, 0], [0, 1, 0], [1, 1, 0]]
Weights for query: [[1, 0, 1], [1, 0, 0], [0, 0, 1], [0, 1, 1]]
Weights for value: [[0, 2, 0], [0, 3, 0], [1, 0, 3], [1, 1, 0]]
注意:在神经网络设置中,这些权值通常是小数,使用适当的随机分布随机初始化,如高斯分布、Xavier分布和kaimin分布。这个初始化在训练之前完成一次。
3. 派生键,查询,值
现在我们有了三组权重,让我们实际获取每个输入的键、查询和值表示。
输入1的键表示: [0, 0, 1] [1, 0, 1, 0] x [1, 1, 0] = [0, 1, 1] [0, 1, 0] [1, 1, 0]
使用相同的一组权重来获得输入2的键表示: [0, 0, 1] [0, 2, 0, 2] x [1, 1, 0] = [4, 4, 0] [0, 1, 0] [1, 1, 0]
使用相同的一组权重来获得输入3的键表示: [0, 0, 1] [1, 1, 1, 1] x [1, 1, 0] = [2, 3, 1] [0, 1, 0] [1, 1, 0]
更快的方法是利用矩阵乘法: [0, 0, 1] [1, 0, 1, 0] [1, 1, 0] [0, 1, 1] [0, 2, 0, 2] x [0, 1, 0] = [4, 4, 0] [1, 1, 1, 1] [1, 1, 0] [2, 3, 1]

使用相同的方法得到每个输入的值表示 [0, 2, 0] [1, 0, 1, 0] [0, 3, 0] [1, 2, 3] [0, 2, 0, 2] x [1, 0, 3] = [2, 8, 0] [1, 1, 1, 1] [1, 1, 0] [2, 6, 3]

最后得到查询表示: [1, 0, 1] [1, 0, 1, 0] [1, 0, 0] [1, 0, 2] [0, 2, 0, 2] x [0, 0, 1] = [2, 2, 2] [1, 1, 1, 1] [0, 1, 1] [2, 1, 3]

注意:在实践中,可以在矩阵乘法的乘积上加一个偏置向量。 # 4. 计算输入1的注意力分数
为了获得注意力分数,我们从输入1的查询(红色)和所有键(橙色)(包括它自己)之间的点积开始。因为有3个键表示(因为我们有3个输入),我们得到3个注意力分数(蓝色)。 [0, 4, 2] [1, 0, 2] x [1, 4, 3] = [2, 4, 4] [1, 0, 1]
注意:我们只使用来自输入1的查询。稍后,我们将对其他查询重复此步骤。
注意:上述操作称为点积注意,是打分函数之一。其他分数函数包括缩放点积和additive/concat。
5. 计算softmax

softmax([2, 4, 4]) = [0.0, 0.5, 0.5]
6. 分数与值相乘

每个输入的softmax注意力分数(蓝色)与相应的值(紫色)相乘。这将导致3个对齐向量(黄色)。在本教程中,我们将把它们称为加权值。
1: 0.0 * [1, 2, 3] = [0.0, 0.0, 0.0] 2: 0.5 * [2, 8, 0] = [1.0, 4.0, 0.0] 3: 0.5 * [2, 6, 3] = [1.0, 3.0, 1.5]
7. 加权值相加得到输出1

将所有的加权值(黄色)按元素相加:
[0.0, 0.0, 0.0] \(+\) [1.0, 4.0, 0.0] \(+\) [1.0, 3.0, 1.5] \(-------\) \(=\)[2.0, 7.0, 1.5]
结果向量2.0,7.0,1.5是输出1,它基于输入1与所有其他键交互的查询表示,包括它自己。 # 8. 对输入2和输入3重复步骤4-7
现在我们已经完成了输出1,我们对输出2和输出3重复步骤4到7。
注意:由于点积分数函数的存在,查询和键的维度必须始终相同。然而,值的维度可能不同于查询和键。结果输出将与值的维度相同。
原教程链接:https://towardsdatascience.com/illustrated-self-attention-2d627e33b20a(应该需要翻墙)