0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何理解attention中的Q,K,V?

新机器视觉 来源:知乎问答 2023-12-04 09:40 次阅读

回答一:作者-不是大叔

我们直接用torch实现一个SelfAttention来说一说: 1.首先定义三个线性变换矩阵,query, key, value:

class BertSelfAttention(nn.Module):

    self.query = nn.Linear(config.hidden_size, self.all_head_size) # 输入768, 输出768
    self.key = nn.Linear(config.hidden_size, self.all_head_size) # 输入768, 输出768
self.value=nn.Linear(config.hidden_size,self.all_head_size)#输入768,输出768

 注意,这里的query, key, value只是一种操作(线性变换)的名称,实际的Q/K/V是它们三个的输出

2. 假设三种操作的输入都是同一个矩阵(暂且先别管为什么输入是同一个矩阵),这里暂且定为长度为L的句子,每个token的特征维度是768,那么输入就是(L,768),每一行就是一个字,像这样:

63352ccc-9025-11ee-939d-92fbcf53809c.png

乘以上面三种操作就得到了Q/K/V,(L, 768)*(768,768) = (L,768),维度其实没变,即此刻的Q/K/V分别为:

63421c16-9025-11ee-939d-92fbcf53809c.png

代码为:

class BertSelfAttention(nn.Module):
    def __init__(self, config):
        self.query = nn.Linear(config.hidden_size, self.all_head_size) # 输入768, 输出768
        self.key = nn.Linear(config.hidden_size, self.all_head_size) # 输入768, 输出768
        self.value = nn.Linear(config.hidden_size, self.all_head_size) # 输入768, 输出768
    
    def forward(self,hidden_states): # hidden_states 维度是(L, 768)
        Q = self.query(hidden_states)
        K = self.key(hidden_states)
        V = self.value(hidden_states)

3. 然后来实现这个操作:

634c6400-9025-11ee-939d-92fbcf53809c.png

① 首先是Q和K矩阵乘,(L, 768)*(L, 768)的转置=(L,L),看图:

635aa88a-9025-11ee-939d-92fbcf53809c.png

首先用Q的第一行,即“我”字的768特征和K中“我”字的768为特征点乘求和,得到输出(0,0)位置的数值,这个数值就代表了“我想吃酸菜鱼”中“我”字对“我”字的注意力权重,然后显而易见输出的第一行就是“我”字对“我想吃酸菜鱼”里面每个字的注意力权重;整个结果自然就是“我想吃酸菜鱼”里面每个字对其它字(包括自己)的注意力权重(就是一个数值)了~ ② 然后是除以根号dim,这个dim就是768,至于为什么要除以这个数值?主要是为了缩小点积范围,确保softmax梯度稳定性,具体推导可以看这里:莲生三十二:Self-attention中dot-product操作为什么要被缩放(https://zhuanlan.zhihu.com/p/149903065),然后就是为什么要softmax,一种解释是为了保证注意力权重的非负性,同时增加非线性,还有一些工作对去掉softmax进行了实验,如PaperWeekly:线性Attention的探索:Attention必须有个Softmax吗?(https://zhuanlan.zhihu.com/p/157490738)

③ 然后就是刚才的注意力权重V矩阵乘了,如图:

63629874-9025-11ee-939d-92fbcf53809c.jpg

注意力权重 x VALUE矩阵 = 最终结果 首先是“我”这个字对“我想吃酸菜鱼”这句话里面每个字的注意力权重,和V中“我想吃酸菜鱼”里面每个字的第一维特征进行相乘再求和,这个过程其实就相当于用每个字的权重对每个字的特征进行加权求和,然后再用“我”这个字对对“我想吃酸菜鱼”这句话里面每个字的注意力权重和V中“我想吃酸菜鱼”里面每个字的第二维特征进行相乘再求和,依次类推~最终也就得到了(L,768)的结果矩阵,和输入保持一致~

整个过程在草稿纸上画一画简单的矩阵乘就出来了,一目了然~最后上代码:

class BertSelfAttention(nn.Module):

    def __init__(self, config):
        self.query = nn.Linear(config.hidden_size, self.all_head_size) # 输入768, 输出768
        self.key = nn.Linear(config.hidden_size, self.all_head_size) # 输入768, 输出768
        self.value = nn.Linear(config.hidden_size, self.all_head_size) # 输入768, 输出768
    
    def forward(self,hidden_states): # hidden_states 维度是(L, 768)
        Q = self.query(hidden_states)
        K = self.key(hidden_states)
        V = self.value(hidden_states)
        
        attention_scores = torch.matmul(Q, K.transpose(-1, -2))
        attention_scores = attention_scores / math.sqrt(self.attention_head_size)
        attention_probs = nn.Softmax(dim=-1)(attention_scores)


        out = torch.matmul(attention_probs, V)
        return out

4. 为什么叫注意力网络?因为可以看到Q/K/V都是通过同一句话的输入算出来的,按照上面的流程也就是一句话内每个字对其它字(包括自己)的权重分配;那如果不是自注意力呢?简单来说,Q来自于句A,K、V来自于句B即可~ 5. 注意,K/V中,如果同时替换任意两个字的位置,对最终的结果是不会有影响的,至于为什么,可以自己在草稿纸上画一画矩阵乘;也就是说注意力机制是没有位置信息的,不像CNN/RNN/LSTM;这也是为什么要引入位置embeding的原因。 02 

回答二:作者-到处挖坑蒋玉成

其实直接用邱锡鹏老师PPT里的一张图就可以直观理解——假设D是输入序列的内容,完全忽略线性变换的话可以近似认为Q=K=V=D(所以叫做Self-Attention,因为这是输入的序列对它自己的注意力),于是序列中的每一个元素经过Self-Attention之后的表示就可以这样展现:

636e7e64-9025-11ee-939d-92fbcf53809c.jpg

也就是说,The这个词的表示,实际上是整个序列加权求和的结果——权重从哪来?点积之后Softmax得到——这里Softmax(QK)就是求权重的体现。我们知道,向量点积的值可以表征词与词之间的相似性,而此处的“整个序列”包括The这个词自己(再一次强调这是Self-Attention),所以最后输出的词的表示,其“主要成分”就主要地包含它自身和跟它相似的词的表示,其他无关的词的表示对应的权重就会比较低。 03

回答三:作者-渠梁

首先附上链接:张俊林:深度学习中的注意力模型(2017版)(https://zhuanlan.zhihu.com/p/37601161) 。这个几乎是我读到过的讲解Attention最为透彻的篇章之一了。 Q(Querry)代表查询值,对应Decoder的H(t-1)状态。这里要正确理解H(t-1),想要解码出t时刻的输出,你送入Decoder的必然有前一时刻计算出的隐状态。好了,所谓查询,就是你要拿着这个Decoder中的H(t-1)去和Encoder中各个时刻的隐状态[H(1), H(2), ... , H(T)](也就是各个Key)去比,也就是二者计算相似度(对应于文献中的各种energy函数)。最后算出来的结果用Softmax归一化,这个算出来的权重就是带有注意力机制的权重,其实在翻译任务中,Key和Value是相等的。在Transformer的实现源码中,Key和Value的初始值也是相等的。有了这个权重之后,就可以用这个权重对Value进行加权求和,生成的这个新的向量就是带有注意力机制的语义向量 Context vector,而这个语义向量会权衡Target与Source的token与token的关系,从而实现解码输出时,与Source中“真正有决定意义”的token关联。 姑且画蛇添足的再说几句:

首先,Attention机制是由Encoder-Decoder架构而来,且最初是用于完成NLP领域中的翻译(Translation)任务。那么输入输出就是非常明显的 Source-Target的对应关系,经典的Seq2Seq结构是从Encoder生成出一个语义向量(Contextvector)而不再变化,然后将这个语义向量送入Decoder配合解码输出。这种方法的最大问题就是这个语义向量,我们是希望它一成不变好呢?还是它最好能配合Decoder动态调整自己,来使Target中的某些token与Source中的真正“有决定意义”的token关联起来好呢? 这就是为什么会有Attention机制的原因。说到底,Attention机制就是想生成会动态变化的语义向量来配合解码输出。而新贵 Self-Attention则是为了解决Target与Source各自内部token与token的关系。在Transformer中,这两种注意力机制得到了有机的统一,释放出了异常惊人的潜力。

审核编辑:黄飞

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 函数
    +关注

    关注

    3

    文章

    3868

    浏览量

    61309
  • 深度学习
    +关注

    关注

    73

    文章

    5237

    浏览量

    119908

原文标题:【深度学习】如何理解attention中的Q,K,V?

文章出处:【微信号:vision263com,微信公众号:新机器视觉】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    -48V供电怎么理解

    -48V供电怎么理解 现在设计的一个产品需要支持以太网供电,正负48V供电!正48V理解,-48V
    发表于 04-25 16:24

    使用L6207Q Vref最高等级是否可取

    大家好,我对全桥驱动器L6207Q有疑问。关于VREF信号,在我的设计,我将使用最大输出电压高于1V的DAC驱动它。我会避免在DAC输出和L6507Q VREF输入之间插入衰减级。是
    发表于 10-08 11:41

    请问不同Q格式的用这个相乘怎么理解??

    // Q21 = Q21*(GLOBAL_Q-GLOBAL_Q) Tmp1 = _IQmpy(v->K1,(
    发表于 11-22 09:59

    如何理解-48V供电?

    -48V供电怎么理解? 明明是-48V,但很多通信设备用的都是48V供电,怎么理解呢?
    发表于 05-06 22:32

    CMS32F030K6Q6 微32位MCU 原厂代理,价格优势 M0系列

    STM32F030F6P6 VS CMS32F030Y6P6 TSSOP20STM32F030K6T6 VS CMS32F030K6Q6 LQFP32STM32F030K6Q6 vs
    发表于 07-26 17:50

    微CMS32F030K6Q6 CMS32F030K6T6 32位MCU 原厂代理技术支持

    CMS32F030K6T6 CMS32F030K6Q632KB Flash,48MHz,增强型PWM。 广泛应用于四轴飞行器,电机,数字电源、云台、无线充等领域。CMS32F030系列MCU是
    发表于 08-02 16:03

    微32位MCU CMS32F030Y6P6/CMS32F030K6Q6/CMS32F030K6T6...32KB Flash,48MHz

    STM32F030F6P6 VS CMS32F030Y6P6TSSOP20STM32F030K6T6 VS CMS32F030K6Q6 LQFP32STM32F030K6Q6 vs
    发表于 08-05 10:36

    微代理CMS32F030K6Q6代替 STM32F030K6T6 STM32F051K8T6

    6 CMS32F030K6T6MCU是微半导体基于ARM-Cortex M0推出的基础型MCU,主频48MHz, 工作电压1.8V至5.5V,32KB Flash,4KB SRAM,
    发表于 08-17 16:54

    CMS32F030K6Q6

    微代理CMS32F030K6Q6代替STM32F030K6T6CMS32F030 32KB Flash,48MHz,增强型PWM。 广泛应用于四轴飞行器,电机,数字电源、云台、无线充等领域
    发表于 09-14 16:52

    S32K144EVB-Q100和S32K142EVB-Q100有什么区别吗?

    、S32K144EVB-Q100和S32K142EVB-Q100有什么区别吗,我查了两块板子的datasheet,两块板子的特性没有区别。(只有芯片)2. 我可以通过 MC33771C/772C 评估 GUI 下载 S32K142EVB
    发表于 03-27 06:52

    Attention的具体原理详解

    注意力机制即Attention mechanism在序列学习任务上具有巨大的提升作用,在编解码器框架内,通过在编码段加入A模型,对源数据序列进行数据加权变换,或者在解码端引入A模型,对目标数据进行加权变化,可以有效提高序列对序列的自然方式下的系统表现。
    发表于 11-23 10:44 7759次阅读

    为什么要有attention机制,Attention原理

    没有attention机制的encoder-decoder结构通常把encoder的最后一个状态作为decoder的输入(可能作为初始化,也可能作为每一时刻的输入),但是encoder的state
    的头像 发表于 03-06 14:11 1.6w次阅读
    为什么要有<b class='flag-5'>attention</b>机制,<b class='flag-5'>Attention</b>原理

    究竟Self-Attention结构是怎样的?

    当我们处理Thinking这个词时,我们需要计算句子中所有词与它的Attention Score,这就像将当前词作为搜索的query,去和句子中所有词(包含该词本身)的key去匹配,看看相关度有多高。
    的头像 发表于 07-18 14:29 1.6w次阅读
    究竟Self-<b class='flag-5'>Attention</b>结构是怎样的?

    简述深度学习中的Attention机制

    Attention机制在深度学习中得到了广泛的应用,本文通过公式及图片详细讲解attention机制的计算过程及意义,首先从最早引入attention到机器翻译任务(Bahdanau et al. ICLR2014)的方法讲起。
    的头像 发表于 02-22 14:21 1054次阅读
    简述深度学习中的<b class='flag-5'>Attention</b>机制

    Transformer的主要概念

    在本文中,我们将试图把模型简化一点,并逐一介绍里面的核心概念,希望让普通读者也能轻易理解Attention is All You Need: https://arxiv.org/abs
    的头像 发表于 11-03 10:42 371次阅读
    Transformer的主要概念