在前面文章讲解了QKV矩阵的原理,属于比较主观的解释,下面用简单的代码再过一遍加深下印象。
白话transformer(三)
我们呢就使用一个句子来做一个测试,
text1 = "我喜欢的水果是橙子和苹果"
text2 = "相比苹果我更加喜欢国产的华为"
比如我们有两个句子,里面都有苹果这个词。我们用text1来走下流程
我们使用spacy进行词嵌入生成,代码很简单
nlp = spacy.load('zh_core_web_sm')
doc = nlp(text1)
我们为了简单一点只取前10个维度,实际上spacy默认的词嵌入维度是很高的,我们只是用前十个来过一下流程。
emd_dim = 10
dics = {}
for token in doc:
dics[token.text] = token.vector[:emd_dim]
X = pd.DataFrame(dics)
这样我们就得到了第一个句子中所有词的embedding表示
具体的内容可以查看之前的文章Bert基础(一)–自注意力机制
为了创建查询矩阵、键矩阵和值矩阵,我们需要先创建另外三个权重矩阵,分别为 W Q 、 W K 、 W V W^Q 、W^K、W^V WQ、WK、WV。用矩阵X分别乘以矩阵 W Q 、 W K 、 W V W^Q 、W^K、W^V WQ、WK、WV,就可以依次创建出查询矩阵Q、键矩阵K和值矩阵V。
d_k = 6 # QKV向量的维度
A
t
t
e
n
t
i
o
n
(
Q
,
K
,
V
)
=
s
o
f
t
m
a
x
(
Q
K
T
d
k
)
V
Attention(Q,K,V) = softmax(\frac{QK^{T}}{\sqrt{d_k}})V
Attention(Q,K,V)=softmax(dkQKT)V
d_k是指公式中的d_k
Wq = np.random.randn(emd_dim, d_k)
Wq矩阵的格式,就是10*6
Wk, Wv,同样
Q = X * Wq
np.dot(X.T, Wq)
这样就得到了查询矩阵Q,Q其实可以理解为每个词需要查询的内容。
同样可以计算K和V矩阵
计算公式为:
X
W
Q
∗
(
W
K
X
)
T
XW^Q *(W^KX )^T
XWQ∗(WKX)T
其实就是我们计算好的Q和K
Q
K
T
Q K^T
QKT
直接点乘就可以得到每个词和每个词的相似性:
Q@K.T/ np.sqrt(d_k)
我们自己遍历计算一下即可
# 计算Softmax
for i in range(len(df_QK)):
exp_v = np.exp(df_QK.iloc[i])
softmax = exp_v / np.sum(exp_v)
df_QK.iloc[i] = softmax
现在就得到了最后的相似性矩阵
A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T d k ) V Attention(Q,K,V) = softmax(\frac{QK^{T}}{\sqrt{d_k}})V Attention(Q,K,V)=softmax(dkQKT)V
根据公示直接将前面计算的结构点乘V