如何理解attention中的Q、K、V?
y直接用torch实现一个SelfAttention来说一说:
1、首先定义三哥线性变换,query,key以及value:
class BertSelfAttention(nn.Module):self.query = nn.Linear(config.hidden_size, self.all_head_size)#输入768,输出768self.key = nn.Linear(config.hidden_size, self.all_head_size)#输入768,输出768self.value = nn.Linear(config.hidden_size, self.all_head_size)#输入768,输出768
注意,这里的query, key, value只是一种操作(线性变换)的名称,实际的Q/K/V是它们三个的输出。
2、假设三种操作的输入都是同一个矩阵(暂且先别管为什么输入是同一个矩阵),这里暂且定为长度为L的句子,每个token的特征维度是768,那么输入就是(L, 768),每一行就是一个字,像这样:

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

代码为:
class BertSelfAttention(nn.Module):def __init__(self, config):self.query = nn.Linear(config.hidden_size, self.all_head_size) # 输入768, 输出768self.key = nn.Linear(config.hidden_size, self.all_head_size) # 输入768, 输出768self.value = nn.Linear(config.hidden_size, self.all_head_size) # 输入768, 输出768def forward(self, hidden_states): #hidden_states维度是(L,768)Q = self.query(hidden_states)K = self.key(hidden_states)V = self.value(hidden_states)
3、然后来实现这个操作:

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

首先用Q的第一行,即“我”字的768特征和K中“我”字的768为特征点乘求和,得到输出(0,0)位置的数值,这个数值就代表了“我想吃酸菜鱼”中“我”字对“我”字的注意力权重;
然后显而易见输出的第一行就是“我”字对“我想吃酸菜鱼”里面每个字的注意力权重;整个结果自然就是“我想吃酸菜鱼”里面每个字对其它字(包括自己)的注意力权重(就是一个数值)了~
② 然后是除以根号dim,这个dim就是768,至于为什么要除以这个数值?主要是为了缩小点积范围,确保softmax梯度稳定性,接着就是为什么要softmax,一种解释是为了保证注意力权重的非负性,同时增加非线性;
③ 再就是刚才的注意力权重和V矩阵乘了,如图:
注意力权重 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, 输出768self.key = nn.Linear(config.hidden_size, self.all_head_size) # 输入768, 输出768self.value = nn.Linear(config.hidden_size, self.all_head_size) # 输入768, 输出768def 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,VK,V来自于句B即可~
5、注意,K/V中,如果同时替换任意两个字的位置,对最终的结果是不会有影响的,至于为什么,可以自己在草稿纸上画一画矩阵乘;也就是说注意力机制是没有位置信息的,不像CNN/RNN/LSTM;这也是为什么要引入位置embedding的原因。
相关文章:
如何理解attention中的Q、K、V?
y直接用torch实现一个SelfAttention来说一说: 1、首先定义三哥线性变换,query,key以及value: class BertSelfAttention(nn.Module):self.query nn.Linear(config.hidden_size, self.all_head_size)#输入768,输出768…...
Redis----取代RabbitMq 和 Kafka的解决方案
背景 已知rabbitmq和kafka作为消息中间件来给程序之间增加异步消息传递功能,这两个中间件都是专业的,功能也很强,但是有的时候过于复杂,对于只有一组消费者的消息队列,使用Redis 就可以轻松搞定。 异步消息队列 读者…...
动态规划之连续乘积最大子数组 连续和最大子数组
一. 连续和最大子数组 给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 子数组 是数组中的一个连续部分。 示例 1: 输入:nums [-2,1,-3,4,-1,2,1,-5,…...
keil在点击debug无法运行(全速运行)
1、今天发现我之前可以debug的程序,在板子上无法debug了,打断点完全没用 2、换了电脑,带板子过去也这样,之前可以运行的代码都debug不了 3、按照网上的方法,都不行,全速运行,单步执行都是灰色…...
go语言-协程
mOS结构体 每一种操作系统不同的线程信息 g给g0栈给g0协程内存中分配的地址,记录函数跳转信息, 单线程循环 0.x版本 1.0版本 多线程循环 操作系统并不知道Goroutine的存在 操作系统线程执行一个调度循环,顺序执行Goroutine 调度循环非常…...
如何伪造http头,让后端认为是本地访问
0x00 前言 这个知识点纯粹就是为了ctf准备的,很少有系统会出现这种情况。 0x01 正文 1.host头 如果后端从host取值来判断是否是本地就可以通过此方法进行绕过: host: 127.0.0.12.X-Forwarded-For X-Forwarded-For(XFF)是用来…...
视频剪辑音效处理软件有哪些?视频剪辑软件那个好用
音效是视频剪辑的重要部分,能起到画龙点睛的作用。在短视频平台中,一段出彩的音效能将原本平平无奇的视频变得生动有趣。那么,视频剪辑音效处理软件有哪些?本文会给大家介绍好用的音效处理软件,同时也会介绍视频剪辑音…...
搭建STM32F407的Freertos系统(基于STM32CubeMX)
本人长期开发Linux、Windows上应用软件,一直以来MCU开发有所接触,但较少(最近项目需要,小公司么,都得会,被逼的),好在有STM32CubeMX这样工具,貌似就是我想要的工具。 本次…...
vite 配置自动补全文件的后缀名
vite 不建议自动补全,文件的后缀名的 const Home ()>import("/views/Home.vue");文件是必须要加上 .vue 的后缀名的 如果 想要像 webpack 一样的不用写, 可以在vite.config.js中配置如下就可以了...
基于Spring Boot的人才公寓管理系统设计与实现(Java+spring boot+MySQL)
获取源码或者论文请私信博主 演示视频: 基于Spring Boot的人才公寓管理系统设计与实现(Javaspring bootMySQL) 使用技术: 前端:html css javascript jQuery ajax thymeleaf 微信小程序 后端:Java spring…...
Python 编写函数
文章目录 条件语句循环语句自定义函数函数参数的传递类型函数的参数传入方法 lambda, map, filter, reduce 函数try-except 语句调试一些常用的内置函数 条件语句 编写程序时,经常用到一些条件或判断,需要用到 if 语句,它的字面意思是&#…...
C# Solidworks二次开发:创建距离配合以及移动组件API详解
今天要讲的文章是关于如何创建距离配合和移动组件的API详解。 (1)创建配合API,CreateMate() 这个API的解释是根据指定的特性数据对象来创建配合,也就可以理解为输入什么样的特征对象就可以创建出什么配合,这个API的输…...
Excel:通过Lookup函数提取指定文本关键词
函数公式:LOOKUP(9^9,FIND($G 2 : 2: 2:G 6 , C 2 ) , 6,C2), 6,C2),G 2 : 2: 2:G$6) 公式解释: lookup第一参数为9^9:代表的是一个极大值的数据,查询位置里面最接近这一个值的数据;lookup第二参数用find函数代替&am…...
sql:SQL优化知识点记录(六)
(1)索引优化1 查看一下有没有建立索引: 用到索引中的一个:type中的ref决定访问性能 用到索引中的两个:通过key_len的长度可以看出来,比第一个大一点。或者通过ref:中用到了两个常量const 用到了…...
C#搭建WebSocket服务实现通讯
在学习使用websocket之前我们先了解一下websocket: WebSocket是一种在单个TCP连接上进行全双工通信的通信协议。与HTTP协议不同,它允许服务器主动向客户端发送数据,而不需要客户端明确地请求。这使得WebSocket非常适合需要实时或持续通信的应…...
eclipse/STS(Spring Tool Suite)安装CDT环境(C/C++)
在线安装 help -> eclipse marketplace 可以发现,我所使用eclipse给我推荐安装的CDT是10.5版本 离线安装 下载离线安装包 下载地址:https://github.com/eclipse-cdt/cdt/blob/main/Downloads.md 可以看到利息安装包主要有如下四大类,…...
Python爬虫抓取经过JS加密的API数据的实现步骤
随着互联网的快速发展,越来越多的网站和应用程序提供了API接口,方便开发者获取数据。然而,为了保护数据的安全性和防止漏洞,一些API接口采用了JS加密技术这种加密技术使得数据在传输过程中更加安全,但也给爬虫开发带来…...
Nacos基础(2)——nacos的服务器和命名空间 springBoot整合nacos 多个nacos配置的情况
目录 引出nacos服务器和命名空间Nacos服务器命名空间 springBoot整合nacosspringcloud Alibaba 版本与springcloud对应关系引包配置maincontroller 报错以及解决【报错】错误:缺少服务名称报错:9848端口未开放 启动测试引入多个nacos配置多个配置的情况没…...
Win7设备和打印机里空白,0个对象,但是可以打印的处理办法
呉師傅 你是不是遇到过Win7系统打开设备和打印机的时候显示是空白的,0个设备的情况?要怎么操作才能解决这一问题呢,下面就分享一下如何处理这个问题的小方法大家可以尝试一下。 问题如下: 解决方法: 1、点击桌面左下…...
Python基础学习第六天:Python 数据类型
内置数据类型 在编程中,数据类型是一个重要的概念。 变量可以存储不同类型的数据,并且不同类型可以执行不同的操作。 在这些类别中,Python 默认拥有以下内置数据类型: 获取数据类型 您可以使用 type() 函数获取任何对象的数据…...
用随机森林实现手写大写字母识别的完整实践
1. 项目概述:用随机森林搞定手写信件识别,这事儿比你想象中更接地气 “How To Perform Letter Recognition in Python Using Random Forest Classifier”——这个标题乍看像教科书里的章节名,但实际拆开来看,它直指一个非常典型、…...
快速开发AI客服原型时如何利用Taotoken分钟级接入多模型
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 快速开发AI客服原型时如何利用Taotoken分钟级接入多模型 在探索和构建AI客服原型时,开发者常常面临一个核心矛盾&#…...
Unity版本降级实战指南:从2021.1回退到2019.4的四步硬核操作
1. 为什么Unity版本降级不是“回退安装”那么简单 在Unity项目开发中,很多人把“降级”理解成卸载新版本、重装旧版本、再拖进工程——就像换手机系统时刷回上个固件。但Unity的版本管理机制远比这复杂得多。我第一次遇到从2021.1.7f1c1往回降到2019.4.17f1c1的问题…...
JMeter+DeepSeek实现性能测试报告自动化与智能脚本生成
1. 这不是“AI写报告”,而是把性能测试工程师从重复劳动里解放出来的实操路径 你有没有过这样的经历:凌晨两点还在手动整理JMeter的.jtl结果文件,Excel里堆着几十列响应时间、错误率、吞吐量,再复制粘贴到Word里写“本次压测在200…...
SoC性能深度解析:从CPU/GPU到互连与内存子系统的系统性认知
1. 项目概述:从“黑盒”到“白盒”的SoC认知跃迁在芯片设计领域,尤其是面向移动设备、物联网终端和各类嵌入式系统,SoC(System on Chip,片上系统)早已成为绝对的核心。我们常常会听到这样的讨论:…...
用 5 款全栈电商微系统打通你的前后端核心逻辑链路(附级联 Prompt)
各位大前端、全栈开发以及正在寻求技术进阶的同仁们,大家好。在日常的技术社区里,我们经常能看到各种流于表面的前端 UI 静态页或者几行代码拼凑的后端 CRUD 示例。但真正能在一个全栈工程师的履历中起到定海神针作用的,往往是那些功能内敛、…...
书匠策AI实测揭秘:毕业论文全流程竟然能这样“偷懒“?
各位同学,我是一个专门教别人写论文的博主。说实话,每次看到评论区有人问"论文到底怎么开头",我都想穿越屏幕去帮他敲键盘。 但今天不一样,我要给你们安利一个我自己偷偷用了好几次的工具——书匠策AI。注意࿰…...
用MATLAB手把手仿真超外差混频:从160MHz射频到40MHz中频的完整信号处理流程
MATLAB实战:超外差混频从160MHz射频到40MHz中频的工程级仿真指南 在无线通信系统设计中,超外差接收机架构因其优异的灵敏度和选择性,至今仍是射频前端的主流方案。本文将带您用MATLAB完整复现这一经典结构中的混频与滤波过程,特别…...
AI 超声波口罩机智能功率 MOSFET 完整选型方案
随着 AI 视觉检测与自适应控制技术深度集成,现代超声波口罩机对功率 MOSFET 提出更高要求:高频谐振效率、低损耗长寿命、高可靠精密驱动。微碧半导体(VBsemi)基于先进 SGT 及 Trench 工艺,为您提供覆盖超声波发生器、传…...
ElevenLabs云南话语音定制化指南(独家披露官方未公开的phoneme alignment bypass技巧)
更多请点击: https://codechina.net 第一章:ElevenLabs云南话语音定制化全景概览 ElevenLabs 作为全球领先的AI语音合成平台,原生支持英语、西班牙语、法语等数十种主流语言,但尚未在官方API中直接开放云南话(属西南…...
