3. Transformer —— 理解QKV

        在写这一章之前,我原本想继续写decoder,交叉注意力,掩码注意力等等。但是,如果按照之前的对q,k,v的解释,我觉得并不能很好理解decoder、交叉注意力倒是在做什么,最后这个decoder是怎么把下一个单词给预测出来的?q,k,v到底都是些什么东西?为什么要qk点积?等等一系列问题,都很难理解。

        于是,我觉得应该从向量的角度,重新理解q, k,v及attention中各种运算的意义。这篇文章很大程度上受益于3Blue1brown的两个对transformer形象解读的视频。我非常建议大家去看下他的视频。

1. 词向量

        正如我们之前所说,embedding是将人类理解的单词变成计算机理解的数字。

        在transformer中,单词先经过一次单词编码,再经过一层位置编码。位置编码的意义就是标注这个单词是句子中的第几个单词。总之,经过这两次编码后,得到一个向量,代表词空间中这个单词。比如,通过两层embedding,将 "china" 编译成 [ 3, 6 ,10]。那么在这个三维的词空间中,这个向量就代表china。现实情况中,embedding出来的词向量的维度往往很高。

             同样的,embedding将句子里的单词都编译到一个空间中。如下图所示,在进行学习前,所有的这些向量,只是杂乱无章的,在空间中分布着,仅仅代表着单词本身。

        模型学习的意义,就是调整这些向量,使得其按照一定的逻辑关系在空间中分布。简单的来说就说是物以类聚,相近意思的单词应该靠在一起。看下图,在经过学习后,“中国”和“熊猫”相近,“澳大利亚”“袋鼠”相近。而且中国和澳大利亚就离得很远。

        注意这两个绿色的小剪头,他们也代表着一种关系,可以是 “这个国家代表性的动物是什么”。由此可以看到,学习后的向量,可以蕴含十分丰富的关系和逻辑,包含了语义和句法的信息,以及重要的是,也包涵了下一个单词是什么的信息

        学习前,中国这个向量,只代表中国。学习后,模型就可以知道,跟中国相近的还有 熊猫熊猫 是 中国的一种代表性动物。如果是在生成一段关于中国的介绍,那么跟中国相近的熊猫,这个单词就更容易被获取到,这个单词的概率就更大,就更容易被生成出来,比如生成“中国熊猫”。像 澳大利亚,袋鼠 这些,由于离得很远,那么肯定更难被读取,下一词是他们的概率也就更低。

        上述的学习过程,其实就是encoder中自注意力的学习过程。比如在中文翻译成英文的过程中,encoder先学习的是中文文本。学习后,使中文的词向量按照一定的关系在空间中分布。

2. Q,K是什么?              

        同样地,我们看下面这张图片。在计算x1的注意力时,q1可以理解“句子里什么单词跟thinking(x1)有关?”。对于k1,k2可以理解是对于这个问题的回答。比如,k1回答是“我是这个词的形容词”时,q1*k1的相似度结果就会是正值而且较大。如果k2是“我跟这个词没关系”,q1*k1的相似度结果就会是负值。

        在向量的层面上,该怎么理解呢?x1,x2,...,等是高维度的词向量(比如12,288)。我们要比较问题和回答之间的关系,就需要将q,k放到同一个空间维度(qk空间,通常是较低的维度,比如128)下比较。

        把高维度的词向量x,通过Wq,输出到低维度的,qk空间中的,查询query向量q。

        同理,把高维度的词向量x,通过Wk,输出到低维度的,qk空间中的,回答key向量k。

        那么,为了计算问题query和回答key之间的相似度,很明显是可以通过向量的点积来计算得到。比如上面两张图的例子,creature和fluffy在原文本中是"fluffy creature",指的是 毛茸茸的生物。显然他们两的关系很大,fluffy 是 creature的形容词。那么在QK空间中,creature向量q和fluffy 的回答向量k之间的相似度就很高。从图中也可以看到,他们几乎一致。

        这里简单说下向量点积,向量a和向量b越相近,那么他们的点积是正值而且会越大。向量a和向量c越相远,那么他们的点积是负值而且会越大。

       

        得到相似度分数后,会进行一次归一化的处理,也是为了方便后续的计算。就是下图中的softmax以及括号里的除以\sqrt{d_{k}}

3. V 就是 X 吗?

        我个人觉得对于v的理解,是整个attention中最重要的部分。在刚学习的时候,我一直认为v就是代表x。我看的很多文章,都是认为v是x。包括我第一篇文章里的例子,把v直接看作x似乎是个很合理的事情。

        但是这样理解的话,会有很多不合理的地方。首先,如果v是x,那么为什么不就用x,还花费那么大的参数量Wv和计算量去构造出这个v?其次,在实际结构中有个残差连接,对于这个输出的z,又把原来的x加了回来。如果z已经代表了新的x,那再加上x的后,这又成啥了?而且在decoder中的交叉注意力中,这么理解更加奇怪。比如在中文翻译成英文时,为什么要把代表中文的词向量加到英文的词向量中,等等问题。

        让我们一起来探讨下v是个什么东西。还记得这张图片中绿色的小箭头吗?中国的代表性动物是熊猫,澳大利亚的代表性动物是袋鼠。绿色的向量代表着一种逻辑关系,重要的是,他是可以加到其他不同的向量上。加到“中国”,就可以指向“熊猫”。加到”澳大利亚“,就可以指向“袋鼠”。

       V就是这种绿色的小箭头,代表的是词向量之间的关系,并且是可以应用在不同的词向量上得到新的,富有意义的词向量。

        结合上一节说到的,由q,k得到的相似度(注意力分数),可以理解为权重。将这个分数与关系向量v相乘,代表不同的关系有不同的权重。比如对于句子“中国的大熊猫很可爱,等我放暑假的时候,一定要去看看。” 其中,”大熊猫“跟“中国”,“可爱”,关系都比较大,跟“暑假”可以说关系不大。

        比如,对于“大熊猫”来说,“中国”相似度0.8,“可爱”0.2,“暑假”0.1。那么得到z就是   

             z = 0.8*v1+0.2*v2+0.1*v3

        下图中的绿色向量就是v加权输出后的结果。此时,这里的黄色向量,就代表着,中国的可爱的大熊猫(还跟假期会被去观看,有一点点关系)。

        那么这个黄色向量是哪里来的呢?注意,在残差连接中,原始输入x又重新被加回到输出。原始输入x就是红色向量,在加上attention的结果绿色向量后,就得到了学习后的黄色向量。黄色向量所代表的词蕴含了更多的信息。

4.总结

        在这一篇中,我们重新认识了词向量,qkv以及他们的意义和作用。在此基础上,后续才能更好的理解decoder的工作原理。接下来,主要会讲解decoder结构和原理,transformer的总体结构,训练和预测流程。如果能找到合适的项目的话,会进行代码层面的学习演示。

        非常感谢您的阅读,有任何问题,欢迎指正和交流~~

        

       

  • 42
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Transformer中的QKV计算是通过将输入的特征向量分别映射为查询(Q)、键(K)和值(V)向量,然后通过计算注意力权重来获取最终的输出。下面是计算Transformer中的QKV的步骤: 1. 映射输入特征向量为查询(Q)、键(K)和值(V)向量[^1][^2]。 - 首先,通过线性变换将输入特征向量映射为查询向量Q、键向量K和值向量V。这个线性变换可以使用矩阵乘法和偏置项来实现。 - 例如,在自然语言处理任务中,输入特征向量可以是词嵌入向量,通过线性变换将其映射为查询向量Q、键向量K和值向量V。 2. 计算注意力权重[^1]。 - 使用查询向量Q和键向量K计算注意力权重。注意力权重表示了查询向量与键向量之间的相关性。 - 通过计算查询向量Q和键向量K的点积,然后除以一个缩放因子(如向量维度的平方根),再经过softmax函数得到注意力权重。 3. 使用注意力权重加权求和得到输出。 - 将注意力权重与值向量V相乘,然后对结果进行加权求和,得到最终的输出向量。 - 这个输出向量可以作为下一层的输入,或者作为模型的最终输出。 下面是一个示例代码,演示了如何计算Transformer中的QKV: ```python import torch import torch.nn as nn # 定义一个Transformer模型 class Transformer(nn.Module): def __init__(self, input_dim, output_dim): super(Transformer, self).__init__() self.linear_q = nn.Linear(input_dim, output_dim) self.linear_k = nn.Linear(input_dim, output_dim) self.linear_v = nn.Linear(input_dim, output_dim) def forward(self, x): q = self.linear_q(x) k = self.linear_k(x) v = self.linear_v(x) # 计算注意力权重 attention_weights = torch.softmax(torch.matmul(q, k.transpose(-2, -1)) / torch.sqrt(torch.tensor(q.size(-1))), dim=-1) # 使用注意力权重加权求和得到输出 output = torch.matmul(attention_weights, v) return output # 创建一个Transformer模型实例 input_dim = 512 output_dim = 256 transformer = Transformer(input_dim, output_dim) # 输入特征向量 x = torch.randn(10, input_dim) # 计算Transformer中的QKV output = transformer(x) print(output) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值