transformer 教程(一) qkv矩阵介绍以及为什么除以根号d推导
1. 关于自注意力机制
自注意力机制(Self-Attention)是 Transformer 模型的核心思想,它允许模型在处理输入序列时,能够“关注”到序列中的不同部分,并根据这些部分的重要性来调整当前位置的表示。
想象一下你在阅读一个句子,“爱丽丝是一位杰出的软件工程师,她主导开发了公司核心的推荐系统”,当你读到 “她” 的时候,你的大脑会自动将 “她” 和 “爱丽丝” 联系起来。自注意力机制做的就是类似的事情,在较长的句子中,它能够让模型在处理 “她” 这个词时,更多地关注 “爱丽丝” 这个词。
1.1 Q, K, V:三个关键的矩阵
为了实现自注意力,模型会为输入序列中的每个词创建三个向量:
- Query (查询) 向量 (q): 代表当前正在处理的词。可以把它想象成一个“问题”,它要去寻找和自己相关的其他词。
- Key (键) 向量 (k): 代表序列中可以被“查询”的词。可以把它看作是每个词的“标签”,用来和“问题”进行匹配。
- Value (值) 向量 (v): 代表词的实际内容。当 Query 和 Key 匹配成功后,Value 向量就会被用来计算最终的输出。
这三个向量都是通过将词的嵌入向量(Embedding)与三个不同的权重矩阵(WQ, WK, WV)相乘得到的。这三个权重矩阵是模型在训练过程中学习到的。
1.2 注意力分数的计算
现在我们来看一个具体的例子,假设我们的输入序列是 “Thinking Machines”。
-
获取 Q, K, V 向量:
我们为 “Thinking” 和 “Machines” 这两个词分别计算 Q, K, V 向量。对于 “Thinking”:
q1 = embedding("Thinking") * WQ k1 = embedding("Thinking") * WK v1 = embedding("Thinking") * WV对于 “Machines”:
q2 = embedding("Machines") * WQ k2 = embedding("Machines") * WK v2 = embedding("Machines") * WV -
计算注意力分数 (Attention Score):
接下来,我们计算每个词对于其他所有词的注意力分数。这个分数是通过将 Query 向量和 Key 向量进行点积得到的。当我们计算 “Thinking” 这个词的注意力时:
score1_1 = q1 · k1 # Thinking 对 Thinking 的分数 score1_2 = q1 · k2 # Thinking 对 Machines 的分数 -
缩放 (Scale):
为了防止梯度爆炸,我们会将注意力分数除以一个缩放因子,这个因子通常是 Key 向量维度的平方根 (√dk)。我们将在下一节详细讨论为什么需要这样做。# Thinking 对 Thinking 的分数 score1_1 = score1_1 / sqrt(dk) # Thinking 对 Machines 的分数 score1_2 = score1_2 / sqrt(dk) -
Softmax:
然后,我们对缩放后的分数进行 Softmax 操作,这样所有分数的和就为 1。这些 Softmax 之后的分数代表了在处理当前词时,应该给予其他词多少的“关注度”。# Thinking 对 Thinking 和 Machines 的 Softmax 分数 softmax_scores = softmax([score1_1, score1_2]) -
加权求和:
最后,我们将 Softmax 分数与对应的 Value 向量相乘,然后将它们相加,得到最终的自注意力输出。# Thinking 对 Thinking 和 Machines 的加权求和 z1 = softmax_scores[0] * v1 + softmax_scores[1] * v2
这个输出 z1z1z1 就是 “Thinking” 这个词经过自注意力层之后的新的表示,它包含了来自 “Thinking” 和 “Machines” 这两个词的信息。
如果我们将整个过程用一个公式来表示,那就是自注意力机制的核心公式:
Attention(Q,K,V)=softmax(QKTdk)V Attention(Q, K, V) = softmax(\frac{QK^T}{\sqrt{d_k}})V Attention(Q,K,V)=softmax(dkQKT)V
其中 Q,K,VQ, K, VQ,K,V 分别是查询、键、值矩阵,dkd_kdk 是键向量的维度。
2. 为什么要除以根号d (The Scaling Factor)
在计算注意力分数时,我们将 Query 向量和 Key 向量进行点积。当向量的维度 dkd_kdk 比较大时,点积的结果可能会变得非常大。
为了更好地理解这个问题,我们首先引入一些基本的统计学概念。
2.1 独立随机变量和方差
假设我们有两个的随机变量 XXX 和 YYY,它们的方差分别是 Var(X)Var(X)Var(X) 和 Var(Y)Var(Y)Var(Y)。那么它们的和的方差是:
Var(X+Y)=Var(X)+Var(Y)+2∗Cov(X,Y)Var(X+Y)=Var(X)+Var(Y)+2*Cov(X,Y)
Var(X+Y)=Var(X)+Var(Y)+2∗Cov(X,Y)
如果两个随机变量 XXX 和 YYY 是独立的,那么它们的协方差 Cov(X,Y)Cov(X, Y)Cov(X,Y) 为 0。所以:
Var(X+Y)=Var(X)+Var(Y)
Var(X + Y) = Var(X) + Var(Y)
Var(X+Y)=Var(X)+Var(Y)
这是一个非常重要的性质,它告诉我们,独立随机变量的和的方差等于各自方差的和。
2.2 为什么要除以根号d
现在,让我们假设 qqq 和 kkk 是两个独立的随机向量,它们的每个元素 qiq_iqi 和 kik_iki 都服从均值为 0,方差为 1 的标准正态分布。
q=(q1,q2,...,qdk)
q = (q_1, q_2, ..., q_{d_k})
q=(q1,q2,...,qdk)
k=(k1,k2,...,kdk)
k = (k_1, k_2, ..., k_{d_k})
k=(k1,k2,...,kdk)
其中 E[qi]=0E[q_i] = 0E[qi]=0, Var(qi)=1Var(q_i) = 1Var(qi)=1,E[ki]=0E[k_i] = 0E[ki]=0, Var(ki)=1Var(k_i) = 1Var(ki)=1。
它们的点积 q⋅kq \cdot kq⋅k 可以写成:
q⋅k=∑i=1dkqiki q \cdot k = \sum_{i=1}^{d_k} q_i k_i q⋅k=i=1∑dkqiki
由于 qiq_iqi 和 kik_iki 是独立的,我们可以计算 qi∗kiq_i * k_iqi∗ki 的均值和方差:
均值计算:
E(q⋅k)=E(∑i=1dkqiki)=∑i=1dkE(qi∗ki)=∑i=1dkE(qi)∗E(ki)=0E(q \cdot k) = E(\sum_{i=1}^{d_k} q_i k_i) = \sum_{i=1}^{d_k} E(q_i * k_i) = \sum_{i=1}^{d_k} E(q_i) * E(k_i) = 0E(q⋅k)=E(i=1∑dkqiki)=i=1∑dkE(qi∗ki)=i=1∑dkE(qi)∗E(ki)=0
方差计算:
Var(q⋅k)=Var(∑i=1dkqiki)=∑i=1dkVar(qiki)=∑i=1dkVar(qi)∗Var(ki)=dk Var(q \cdot k) = Var(\sum_{i=1}^{d_k} q_i k_i) = \sum_{i=1}^{d_k} Var(q_i k_i) = \sum_{i=1}^{d_k} Var(q_i) * Var(k_i) = d_k Var(q⋅k)=Var(i=1∑dkqiki)=i=1∑dkVar(qiki)=i=1∑dkVar(qi)∗Var(ki)=dk
可以看到,点积 q⋅kq \cdot kq⋅k 的方差等于 dkd_kdk。这意味着,当 dkd_kdk 越大,点积的方差就越大,方差大意味着点积的结果会更加分散,这在后续的 Softmax 操作中会导致数值不稳定。为了避免这个问题,我们在计算注意力分数时,会将点积结果除以 dk\sqrt{d_k}dk。使点积计算完之后的结果保持在均值为 0,方差为 1 的分布上。从而避免了数值不稳定的问题。
