|
文章目录1、知识回顾2、Self-attetion实现步骤3、准备输入4、初始化参数5、获取Q,K,V6、计算attentionscores7、计算softmax8、给values乘上scores9、完整代码10、总结🍃作者介绍:双非本科大四网络工程专业在读,阿里云专家博主,专注于Java领域学习,擅长web应用开发、数据结构和算法,初步涉猎人工智能和前端开发。🦅个人主页:@逐梦苍穹📕所属专栏:人工智能🌻gitee地址:xzl的人工智能代码仓库✈您的一键三连,是我创作的最大动力🌹1、知识回顾关于Self-Attention的一系列理论知识,请看我的另外一篇文章:深入剖析Self-Attention自注意力机制【图解】:https://xzl-tech.blog.csdn.net/article/details/141308634这篇文章讲到了self-attention的计算过程,如果不想看那么细致的话,我们还是在这里简单复习一下:那么,需要告诉大家的是,既然是要用代码实现,那肯定是需要以一个矩阵的角度去看待整个self-attention的计算过程,请看下文!2、Self-attetion实现步骤这里我们实现的注意力机制是现在比较流行的点积相乘的注意力机制self-attention机制的实现步骤:准备输入初始化参数获取key,query和value给input1计算attentionscore计算softmax给value乘上score,获得output整个过程都是以矩阵的视角在操作的:3、准备输入本文的关注点在于实现过程,所以数据方面我们采用自定义的方式获取:这样就会得到如下张量:4、初始化参数在我上一篇剖析self-attention机制的文章中提到,整个self-attention的计算过程,需要学习的只有三个参数,那就是q,k,v对应的权重矩阵:这里同样不细讲如何学习,这里的重点在于带大家跑通整个self-attention计算的代码流程,所以初始化参数如下:来看一下输出:5、获取Q,K,V前面初始化了q,k,v对应的权重矩阵,下面获取Q,K,V:如图所示,我们可以得到如下表达式:Q=Wq(Input)Q=W^q(Input)Q=Wq(Input)K=Wk(Input)K=W^k(Input)K=Wk(Input)V=Wv(Input)V=W^v(Input)V=Wv(Input)代码实现:得到结果:6、计算attentionscores我在上一篇讲解self-attention机制的文章中,关于计算attentionscores的过程其实是分步计算的:即分步计算αi,j\alpha_{i,j}αi,j但是在代码实现上,我们上面已经全部矩阵化了,我们得到的不是单独的K1K^1K1或者是K2K^2K2,而是关于KallK^{all}Kall的矩阵(QallQ^{all}Qall和VallV^{all}Vall同理):画成图解就是:所以这里计算的attentionscores用代码表示就是:输出效果:7、计算softmax同样,这里一口气将所有的αi,j\alpha_{i,j}αi,j经过SoftmaxSoftmaxSoftmax处理:代码:输出:代码里面的dim=-1,指定在最后一个维度上应用softmax操作;在二维张量的情况下,dim=-1指的是在每一行(行向量)上计算softmax8、给values乘上scores使用经过softmax后的attentionscore乘以它对应的value值:代码:输出:9、完整代码完整代码,代码即注释:#-*-coding:utf-8-*-#@Author:CSDN@逐梦苍穹#@Time:2024/8/1917:24importtorchfromtorch.nn.functionalimportsoftmax#输入数据x,包含3个输入向量,每个向量有4个维度x=[[1,0,1,0],#输入向量1[0,2,0,2],#输入向量2[1,1,1,1]#输入向量3]#将输入数据转换为PyTorch张量,并设置数据类型为float32x=torch.tensor(x,dtype=torch.float32)#定义键(Key)的权重矩阵,形状为(4,3)w_key=[[0,0,1],[1,1,0],[0,1,0],[1,1,0]]#定义查询(Query)的权重矩阵,形状为(4,3)w_query=[[1,0,1],[1,0,0],[0,0,1],[0,1,1]]#定义值(Value)的权重矩阵,形状为(4,3)w_value=[[0,2,0],[0,3,0],[1,0,3],[1,1,0]]#将权重矩阵转换为PyTorch张量,并设置数据类型为float32w_key=torch.tensor(w_key,dtype=torch.float32)w_query=torch.tensor(w_query,dtype=torch.float32)w_value=torch.tensor(w_value,dtype=torch.float32)#打印权重矩阵以供检查print("w_key:",w_key)print("w_query:",w_query)print("w_value:",w_value)#计算Keys:将输入x与键的权重矩阵相乘,生成键向量keys=w_key@x#计算Queries:将输入x与查询的权重矩阵相乘,生成查询向量querys=w_query@x#计算Values:将输入x与值的权重矩阵相乘,生成值向量values=w_value@x#打印键、查询和值向量以供检查print("Keys:",keys)print("Querys:",querys)print("Values:",values)#计算注意力分数(AttentionScores):通过键和查询向量的点积计算#结果是一个(4,4)的矩阵,其中每个元素表示查询和键之间的相似度attn_scores=keys@querysprint("AttentionScores:",attn_scores)#对注意力分数应用Softmax函数,将其转换为概率分布#Softmax处理后的矩阵形状仍为(4,4),表示每个查询对所有键的关注度attn_scores_softmax=softmax(attn_scores,dim=-1)print("AttentionScoresSoftmax:",attn_scores_softmax)#计算加权后的输出值:将值向量与注意力分数进行加权求和#结果是一个形状为(4,4)的矩阵,表示经过注意力加权后的最终输出output=values@attn_scores_softmaxprint("output:",output)1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727310、总结对全文的代码过程做一个总结:这份代码实现了自注意力机制的核心部分,包括键(Key)、查询(Query)和值(Value)的计算,以及通过注意力分数进行加权求和的过程输入与权重定义输入数据x包含3个向量,每个向量有4个维度定义了三个权重矩阵w_key、w_query和w_value,分别用于生成键、查询和值向量。计算键、查询和值向量将输入x分别与w_key、w_query和w_value相乘,生成对应的键、查询和值向量这个步骤是将输入映射到不同的特征空间,以便进行注意力计算计算注意力分数通过键向量和查询向量的点积计算注意力分数这些分数表示查询向量与键向量之间的相似度,用于决定每个查询向量对不同键向量的关注程度应用Softmax函数对注意力分数进行softmax操作,将这些分数转换为概率分布,确保每个查询对所有键的注意力之和为1这一步将注意力分数变为实际的注意力权重计算加权后的输出值将值向量与注意力权重相乘并求和,得到最终的加权输出这一步模拟了注意力机制如何根据注意力权重聚合输入信息,从而生成最终的上下文表示这些代码完整地展示了自注意力机制的基本工作流程;通过计算注意力分数并对值向量进行加权求和,自注意力机制能够在输入序列中捕捉到相关信息,从而在各种深度学习任务中生成更具上下文感知的输出。
|
|