【Transformer】手撕Attention
import torch
from torch import nn
import torch.functional as F
import mathX = torch.randn(16,64,512) # B,T,Dd_model = 512 # 模型的维度
n_head = 8 # 注意力头的数量
多头注意力机制

class multi_head_attention(nn.Module): def __init__(self, d_model, n_head): # 调用父类构造函数 super(multi_head_attention, self).__init__() # 保存注意力头的数量和模型的维度 self.n_head = n_head self.d_model = d_model # 定义查询(Q)、键(K)、值(V)的线性变换层 self.w_q = nn.Linear(d_model, d_model) # 输入d_model维度,输出d_model维度 self.w_k = nn.Linear(d_model, d_model) # 输入d_model维度,输出d_model维度 self.w_v = nn.Linear(d_model, d_model) # 输入d_model维度,输出d_model维度 self.w_o = nn.Linear(d_model, d_model) # 输出线性变换层,用来做一个线形缩放 # 定义softmax函数,用于计算注意力得分的归一化 self.softmax = nn.Softmax(dim=-1) # softmax会在最后一维(dim=-1)上操作 def forward(self, q, k, v): # 获取输入查询(q),键(k),值(v)的形状 B, T, D = q.shape # B: batch size, T: sequence length, D: feature dimension (d_model) # 每个注意力头的维度 n_d = self.d_model // self.n_head # 每个头的维度(d_model / n_head) # 将输入的q、k、v通过各自的线性变换层映射到新的空间 q, k, v = self.w_q(q), self.w_k(k), self.w_v(v) # 将q, k, v 按头数进行拆分(reshape),并转置使得各头的计算可以并行 # q, k, v的形状变为 (B, T, n_head, n_d),然后转置变为 (B, n_head, T, n_d) q = q.view(B, T, self.n_head, n_d).transpose(1, 2) # (B, n_head, T, n_d) k = k.view(B, T, self.n_head, n_d).transpose(1, 2) # (B, n_head, T, n_d) v = v.view(B, T, self.n_head, n_d).transpose(1, 2) # (B, n_head, T, n_d) # 计算缩放点积注意力(scaled dot-product attention) score = q @ k.transpose(2, 3) / math.sqrt(n_d) # (B, n_head, T, T) # score是查询q与键k之间的相似度矩阵,进行缩放以防止数值过大 # 生成一个下三角矩阵,用于实现自注意力中的"masking",屏蔽未来的信息 mask = torch.tril(torch.ones(T, T, dtype=bool)) # 生成一个下三角的布尔矩阵 # 使用mask进行屏蔽,mask为0的位置会被填充为一个非常大的负值(-10000) score = score.masked_fill(mask == 0, -10000) # 把mask == 0的位置置为-10000 # 对score进行softmax归一化处理,得到注意力权重 score = self.softmax(score) # (B, n_head, T, T) # 将注意力权重与值(v)相乘,得到加权后的值 score = score @ v # (B, n_head, T, n_d) # 将多个头的结果合并(concatenate),并通过线性层进行映射 # 首先将score的维度变为 (B, T, n_head * n_d),然后通过w_o进行线性变换 x_concate = score.transpose(1, 2).contiguous().view(B, T, self.d_model) # (B, T, d_model) x_output = self.w_o(x_concate) # (B, T, d_model) # 返回最终的输出 return x_output attn = multi_head_attention(d_model, n_head)
Y = attn(X,X,X)
print(Y.shape)
层归一化
# layer norm
class layer_norm(nn.Module): def __init__(self, d_model, eps = 1e-12): super(layer_norm, self).__init__() self.gamma = nn.Parameter(torch.ones(d_model)) self.beta = nn.Parameter(torch.zeros(d_model)) self.eps = eps def forward(self, x): mean = x.mean(-1, keepdim = True) var = x.var(-1, unbiased=False, keepdim = True) out = (x - mean) / torch.sqrt(var + self.eps) out = self.gamma * out + self.beta return out d_model = 512
X = torch.randn(2,5,512) # 2句话, 5个token,词向量512
ln = layer_norm(d_model)
print("d_model: ", d_model)
print(f"ln gamma: {ln.gamma.shape}")
print(f"ln beta: {ln.beta.shape}")
Y_ln = ln(X)
print(Y_ln.shape)
这段代码实现了一个多头注意力机制(Multi-Head Attention),这是Transformer模型中的核心组件之一。多头注意力机制允许模型在处理序列数据时,同时关注序列中不同位置的信息,并且可以从不同的子空间中学习到不同的特征表示。
层归一化
代码解读
1. 初始化部分 (__init__ 方法)
def __init__(self, d_model, n_head):super(multi_head_attention, self).__init__()self.n_head = n_headself.d_model = d_modelself.w_q = nn.Linear(d_model, d_model)self.w_k = nn.Linear(d_model, d_model)self.w_v = nn.Linear(d_model, d_model)self.w_o = nn.Linear(d_model, d_model)self.softmax = nn.Softmax(dim=-1)
d_model:模型的维度,即输入向量的维度。n_head:注意力头的数量。w_q,w_k,w_v:分别是对查询(Query)、键(Key)、值(Value)进行线性变换的层,将输入映射到新的空间。w_o:输出线性变换层,用于将多个头的输出合并并映射回原始维度。softmax:用于对注意力得分进行归一化。
2. 前向传播部分 (forward 方法)
def forward(self, q, k, v):B, T, D = q.shapen_d = self.d_model // self.n_headq, k, v = self.w_q(q), self.w_k(k), self.w_v(v)q = q.view(B, T, self.n_head, n_d).transpose(1, 2)k = k.view(B, T, self.n_head, n_d).transpose(1, 2)v = v.view(B, T, self.n_head, n_d).transpose(1, 2)
B:批量大小(batch size)。T:序列长度(sequence length)。D:特征维度(feature dimension),即d_model。n_d:每个注意力头的维度,等于d_model / n_head。q,k,v:通过线性变换层映射到新的空间后,再按头数进行拆分和转置,以便并行计算。- [[q = q.view(B, T, self.n_head, n_d).transpose(1, 2)]]
score = q @ k.transpose(2, 3) / math.sqrt(n_d)mask = torch.tril(torch.ones(T, T, dtype=bool))score = score.masked_fill(mask == 0, -10000)score = self.softmax(score)
score:计算查询q和键k之间的相似度矩阵,并进行缩放(防止数值过大)。mask:生成一个下三角矩阵,用于屏蔽未来的信息(在自注意力机制中,当前时间步只能看到之前的时间步)。score:通过mask屏蔽未来的信息,并对得分进行softmax归一化,得到注意力权重。- [[mask = torch.tril(torch.ones(T, T, dtype=bool))]]
score = score @ vx_concate = score.transpose(1, 2).contiguous().view(B, T, self.d_model)x_output = self.w_o(x_concate)return x_output
score @ v:将注意力权重与值v相乘,得到加权后的值。x_concate:将多个头的输出合并(concatenate),并通过w_o进行线性变换,得到最终的输出。- [[x_concate = score.transpose(1, 2).contiguous().view(B, T, self.d_model)]]
3. 使用示例
attn = multi_head_attention(d_model, n_head)
Y = attn(X, X, X)
print(Y.shape)
attn:创建一个多头注意力机制的实例。Y = attn(X, X, X):将输入X分别作为查询、键、值传入多头注意力机制,得到输出Y。print(Y.shape):输出Y的形状,通常与输入X的形状相同,即(B, T, d_model)。
总结
这段代码实现了一个完整的多头注意力机制,包括线性变换、缩放点积注意力、掩码处理、softmax归一化、多头结果的合并和最终的线性变换。多头注意力机制是Transformer模型的核心组件,广泛应用于自然语言处理、计算机视觉等领域。
这段代码实现了一个层归一化(Layer Normalization)模块
层归一化是深度学习中常用的一种归一化技术,用于稳定训练过程并加速收敛。
1. 初始化部分 (__init__ 方法)
def __init__(self, d_model, eps=1e-12):super(layer_norm, self).__init__()self.gamma = nn.Parameter(torch.ones(d_model))self.beta = nn.Parameter(torch.zeros(d_model))self.eps = eps
d_model:输入特征的维度(即词向量的维度)。gamma和beta:gamma是可学习的缩放参数,初始值为全1,形状为(d_model,)。beta是可学习的偏移参数,初始值为全0,形状为(d_model,)。- 这两个参数用于对归一化后的数据进行缩放和偏移,以增强模型的表达能力。
eps:一个小常数,用于防止分母为零的情况,通常设置为1e-12。
2. 前向传播部分 (forward 方法)
def forward(self, x):mean = x.mean(-1, keepdim=True)var = x.var(-1, unbiased=False, keepdim=True)out = (x - mean) / torch.sqrt(var + self.eps)out = self.gamma * out + self.betareturn out
-
输入
x:假设x的形状为(B, T, d_model),其中:B是批量大小(batch size)。T是序列长度(sequence length)。d_model是特征维度(即词向量的维度)。
-
步骤 1:计算均值和方差:
mean = x.mean(-1, keepdim=True):沿着最后一个维度(d_model)计算均值,形状为(B, T, 1)。var = x.var(-1, unbiased=False, keepdim=True):沿着最后一个维度计算方差,形状为(B, T, 1)。unbiased=False表示计算方差时不使用无偏估计(即除以n而不是n-1)。
-
步骤 2:归一化:
out = (x - mean) / torch.sqrt(var + self.eps):对输入x进行归一化,减去均值并除以标准差(加上eps防止除零)。
-
步骤 3:缩放和偏移:
out = self.gamma * out + self.beta:对归一化后的数据进行缩放和偏移,gamma和beta是可学习的参数。
-
输出
out:形状与输入x相同,为(B, T, d_model)。
3. 代码运行示例
d_model = 512
X = torch.randn(2, 5, 512) # 2句话, 5个token,词向量512
ln = layer_norm(d_model)
print("d_model: ", d_model)
print(f"ln gamma: {ln.gamma.shape}")
print(f"ln beta: {ln.beta.shape}")
Y_ln = ln(X)
print(Y_ln.shape)
- 输入
X:形状为(2, 5, 512),表示 2 个句子,每个句子有 5 个 token,每个 token 的词向量维度为 512。 ln.gamma和ln.beta:ln.gamma的形状为(512,)。ln.beta的形状为(512,)。
- 输出
Y_ln:形状与输入X相同,为(2, 5, 512)。
4. 层归一化的作用
- 稳定训练:通过对每个样本的特征进行归一化,减少内部协变量偏移(Internal Covariate Shift),从而稳定训练过程。
- 加速收敛:归一化后的数据分布更加稳定,有助于加速模型的收敛。
- 增强表达能力:通过可学习的参数
gamma和beta,模型可以学习到适合当前任务的归一化方式。
5. 与批量归一化(Batch Normalization)的区别
- 批量归一化:沿着批量维度(
B)计算均值和方差,适用于批量较大的情况。 - 层归一化:沿着特征维度(
d_model)计算均值和方差,适用于序列数据(如 NLP 中的句子)或批量较小的情况。
6. 总结
- 这段代码实现了一个层归一化模块,对输入的特征进行归一化,并通过可学习的参数
gamma和beta进行缩放和偏移。 - 层归一化在 Transformer 等模型中广泛应用,用于稳定训练和加速收敛。
- 输入形状为
(B, T, d_model),输出形状与输入相同。
相关文章:
【Transformer】手撕Attention
import torch from torch import nn import torch.functional as F import mathX torch.randn(16,64,512) # B,T,Dd_model 512 # 模型的维度 n_head 8 # 注意力头的数量多头注意力机制 class multi_head_attention(nn.Module): def __init__(self, d_model, n_hea…...
844.比较含退格的字符串
目录 题目思路解法收获 题目 给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true 。# 代表退格字符。 注意:如果对空文本输入退格字符,文本继续为空。 思路 如何解退格之后left…...
图书管理系统 Axios 源码__编辑图书
目录 功能概述: 代码实现(index.js): 代码解析: 图书管理系统中,删除图书功能是核心操作之一。下是基于 HTML、Bootstrap、JavaScript 和 Axios 实现的删除图书功能的详细介绍。 功能概述: …...
LabVIEW纤维集合体微电流测试仪
LabVIEW开发纤维集合体微电流测试仪。该设备精确测量纤维材料在特定电压下的电流变化,以分析纤维的结构、老化及回潮率等属性,对于纤维材料的科学研究及质量控制具有重要意义。 项目背景 在纤维材料的研究与应用中,电学性能是评估其性能…...
Commander 一款命令行自定义命令依赖
一、安装 commander 插件 npm install commander 二、基本用法 1. 创建一个简单的命令行程序 创建一个 JavaScript 文件,例如 mycli.js,并添加以下代码: // 引入 commander 模块并获取 program 对象。const { program } require("…...
Day24 洛谷普及2004(内涵前缀和与差分算法)
零基础洛谷刷题记录 Day01 2024.11.18 Day02 2024.11.25 Day03 2024.11.26 Day04 2024.11.28 Day05 2024.11.29 Day06 2024 12.02 Day07 2024.12.03 Day08 2024 12 05 Day09 2024.12.07 Day10 2024.12.09 Day11 2024.12.10 Day12 2024.12.12 Day13 2024.12.16 Day14 2024.12.1…...
遗传算法与深度学习实战(33)——WGAN详解与实现
遗传算法与深度学习实战(33)——WGAN详解与实现 0. 前言1. 训练生成对抗网络的挑战2. GAN 优化问题2.1 梯度消失2.2 模式崩溃 2.3 无法收敛3 Wasserstein GAN3.1 Wasserstein 损失3.2 使用 Wasserstein 损失改进 DCGAN 小结系列链接 0. 前言 原始的生成…...
gitlab云服务器配置
目录 1、关闭防火墙 2、安装gitlab 3、修改配置 4、查看版本 GitLab终端常用命令 5、访问 1、关闭防火墙 firewall-cmd --state 检查防火墙状态 systemctl stop firewalld.service 停止防火墙 2、安装gitlab xftp中导入安装包 [rootgitlab ~]#mkdir -p /service/tool…...
SAP SD学习笔记27 - 请求计划(开票计划)之1 - 定期请求(定期开票)
上两章讲了贩卖契约(框架协议)的概要,以及贩卖契约中最为常用的 基本契约 - 数量契约和金额契约。 SAP SD学习笔记26 - 贩卖契约(框架协议)的概要,基本契约 - 数量契约_sap 框架协议-CSDN博客 SAP SD学习笔记27 - 贩卖契约(框架…...
HTML DOM 修改 HTML 内容
HTML DOM 修改 HTML 内容 引言 HTML DOM(文档对象模型)是浏览器内部用来解析和操作HTML文档的一种机制。通过DOM,我们可以轻松地修改HTML文档的结构、样式和行为。本文将详细介绍如何使用HTML DOM来修改HTML内容,包括元素的增删改查、属性修改以及事件处理等。 1. HTML …...
基于VMware的ubuntu与vscode建立ssh连接
1.首先安装openssh服务 sudo apt update sudo apt install openssh-server -y 2.启动并检查ssh服务状态 到这里可以按q退出 之后输入命令 : ip a 红色挡住的部分就是我们要的地址,这里就不展示了哈 3.配置vscode 打开vscode 搜索并安装:…...
Flutter Candies 一桶天下
| | | | | | | | 入魔的冬瓜 最近刚入桶的兄弟,有责任心的开发者,对自己的项目会不断进行优化,达到最完美的状态 自定义日历组件 主要功能 支持公历,农历,节气,传统节日,常用节假日 …...
maven如何不把依赖的jar打包到同一个jar?
spring boot项目打jar包部署: 经过以下步骤, 最终会形成maven依赖的多个jar(包括lib下添加的)、 我们编写的程序代码打成一个jar,将程序jar与 依赖jar分开,便于管理: success: 最终…...
HTML5 技术深度解读:本地存储与地理定位的最佳实践
系列文章目录 01-从零开始学 HTML:构建网页的基本框架与技巧 02-HTML常见文本标签解析:从基础到进阶的全面指南 03-HTML从入门到精通:链接与图像标签全解析 04-HTML 列表标签全解析:无序与有序列表的深度应用 05-HTML表格标签全面…...
AIGC技术中常提到的 “嵌入转换到同一个向量空间中”该如何理解
在AIGC(人工智能生成内容)技术中,“嵌入转换到同一个向量空间中”是一个核心概念,其主要目的是将不同类型的输入数据(如文本、图像、音频等)映射到一个统一的连续向量空间中,从而实现数据之间的…...
【机器学习理论】朴素贝叶斯网络
基础知识: 先验概率:对某个事件发生的概率的估计。可以是基于历史数据的估计,可以由专家知识得出等等。一般是单独事件概率。 后验概率:指某件事已经发生,计算事情发生是由某个因素引起的概率。一般是一个条件概率。 …...
Docker 部署 GLPI(IT 资产管理软件系统)
GLPI 简介 GLPI open source tool to manage Helpdesk and IT assets GLPI stands for Gestionnaire Libre de Parc Informatique(法语 资讯设备自由软件 的缩写) is a Free Asset and IT Management Software package, that provides ITIL Service De…...
【Vaadin flow 实战】第5讲-使用常用UI组件绘制页面元素
vaadin flow官方提供的UI组件文档地址是 https://vaadin.com/docs/latest/components这里,我简单实战了官方提供的一些免费的UI组件,使用案例如下: Accordion 手风琴 Accordion 手风琴效果组件 Accordion 手风琴-测试案例代码 Slf4j PageT…...
强化学习 DAY1:什么是 RL、马尔科夫决策、贝尔曼方程
第一部分 RL基础:什么是RL与MRP、MDP 1.1 入门强化学习所需掌握的基本概念 1.1.1 什么是强化学习:依据策略执行动作-感知状态-得到奖励 强化学习里面的概念、公式,相比ML/DL特别多,初学者刚学RL时,很容易被接连不断…...
理解神经网络:Brain.js 背后的核心思想
温馨提示 这篇文章篇幅较长,主要是为后续内容做铺垫和说明。如果你觉得文字太多,可以: 先收藏,等后面文章遇到不懂的地方再回来查阅。直接跳读,重点关注加粗或高亮的部分。放心,这种“文字轰炸”不会常有的,哈哈~ 感谢你的耐心阅读!😊 欢迎来到 brain.js 的学习之旅!…...
【Linux】shell脚本忽略错误继续执行
在 shell 脚本中,可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行,可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令,并忽略错误 rm somefile…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
Linux云原生安全:零信任架构与机密计算
Linux云原生安全:零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言:云原生安全的范式革命 随着云原生技术的普及,安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测,到2025年,零信任架构将成为超…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...
uniapp手机号一键登录保姆级教程(包含前端和后端)
目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号(第三种)后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
代码规范和架构【立芯理论一】(2025.06.08)
1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...
