当前位置: 首页 > news >正文

Transformer模型中的两种掩码

模型训练通常使用 批处理batch来提升训练效率。而实际中Transformer的输入序列(如句子、文本片段)长度往往不一致。为了让这些样本可以组成一个统一的形状 [B, T] 的张量给GPU进行并行计算提高效率,需要将较短的序列填充(pad)到最大长度,比如统一为 T=10。填充内容一般是特殊的 <PAD> 符号,或者对应的 token ID(如 0)。

Transformer在训练和推理时,padding的作用不同。训练阶段,为并行处理多个长度不一的序列,需用padding统一长度,确保模型能一次性处理整个批次。推理阶段,单序列生成时无需padding,模型逐token输出;但若采用批处理推理,仍需padding对齐不同长度的序列。因此,训练时padding必不可少,推理时视处理方式而定。

整个 Transformer 结构中涉及到的 “掩码” 类型一共有两种:① 用于区分同一个 batch 中不同长度序列是否被填充的 key padding mask;② 在训练时,Decoder 中用于模仿推理过程中在编码当前时禁止看到未来信息的 attention mask(也叫做 casual mask 或 future mask)

对于自回归模型来说,我们在训练阶段为了加速模型的训练过程,都是直接使用小批量样本来进行训练,而这就导致了不同样本长度不能进行计算的问题,因而要使用填充操作来使同一个 batch 中的序列长度保持一致。同时,在自注意力机制中,为了防止注意力被分配到 padding 位置上,所以我们需要通过 padding mask 来忽略掉这部分注意力值。

名称核心作用应用模块是否与batch相关典型形状与值示例使用场景
key_padding_mask屏蔽无效的padding符号(如句末填充的占位符)Encoder层、Decoder层的自注意力与交叉注意力✅ 是(每个样本独立)[B, T]
例:[0,0,-inf]
处理变长序列时过滤padding
causal mask
(attention_mask)
防止模型看到未来时刻的信息(保持时序依赖)Decoder层的自注意力❌ 否(全局共享)[T, T]
例:上三角矩阵填充-inf
文本生成、自回归预测任务
import torch
import torch.nn.functional as F# ============== 输入设置 ==============
# 两个示例序列:
# 序列1: [1, 2, 0] (0是填充符号)
# 序列2: [3, 4, 5] (没有填充)
inputs = torch.tensor([[1, 2, 0], [3, 4, 5]])
print("输入序列:")
print(inputs)# ============== 1. 填充掩码 ==============
print("\n== 第一部分: 填充掩码 ==")# 填充掩码标识哪些位置包含填充符(0)
# True = 这个位置应被忽略
# False = 这个位置包含真实数据
key_padding_mask = (inputs == 0)
print("\n填充掩码 (True表示'忽略此位置'):")
print(key_padding_mask)
print("解释: 第一个序列的最后一位是填充符,所以标记为True")# ============== 2. 因果掩码 ==============
print("\n== 第二部分: 因果掩码 ==")# 因果掩码防止token关注未来位置
# 这对GPT等自回归模型至关重要
seq_len = inputs.size(1)# 创建下三角矩阵(包括对角线),1表示可见,0表示被掩盖
causal_mask = torch.tril(torch.ones(seq_len, seq_len))
# 转换为布尔掩码(0->True表示需掩盖,1->False表示可见)
causal_mask = causal_mask == 0
print("\n因果掩码 (True表示'需掩盖'):")
print(causal_mask)
print("解释: 每个位置只能看到自己和之前的位置")# ============== 3. 应用掩码到注意力分数 ==============
print("\n== 第三部分: 应用掩码 ==")# 模拟注意力分数
attn_scores = torch.randn(2, 3, 3)
print("\n原始注意力分数 (随机):")
print(attn_scores)# 应用填充掩码
attn_scores = attn_scores.masked_fill(key_padding_mask.unsqueeze(1),  # [2,3] -> [2,1,3]-1e9  # 非常小的值,softmax后接近0
)# 应用因果掩码
attn_scores = attn_scores.masked_fill(causal_mask.unsqueeze(0),  # [3,3] -> [1,3,3]-1e9
)# 计算最终注意力权重
attn_weights = F.softmax(attn_scores, dim=-1)
print("\n最终注意力权重:")
print(attn_weights)
print("解释: 权重已被两种掩码调整,填充位置和未来位置的权重接近0")

Transformer 中 Decoder 里的 tgt key padding mask 操作其实是不需要的。因为计算损失时只会考虑非padding的字符,padding字符不参与损失计算。参考:Transformer中Decoder真的不需要PaddingMask?QKV到底是怎么来的?

注意力机制和mask掩码示例代码

import torch
import torch.nn as nn# 设置随机种子,确保实验结果可复现
torch.random.manual_seed(42)# 定义模型维度和序列长度
d_model = 7  # 模型的维度
tgt_len = 6  # 目标序列长度
src_len = 5  # 源序列长度# =================== 编码器部分 ===================
# 随机生成源序列的嵌入表示
src_em_input = torch.randn(src_len, d_model)
# 定义线性变换层用于计算Q、K、V
q_proj0 = nn.Linear(d_model, d_model)
k_proj0 = nn.Linear(d_model, d_model)
v_proj0 = nn.Linear(d_model, d_model)
# 计算Q、K、V
q, k, v = q_proj0(src_em_input), k_proj0(src_em_input), v_proj0(src_em_input)
# 创建源序列的填充掩码
src_key_padding_mask = torch.tensor([[False, False, False, True, True]])
# 计算注意力权重
weight = q @ k.transpose(0, 1)  # [src_len, src_len]
print("Encoder attention weight before key padding:")
print(weight)
# 应用填充掩码
weight = weight.masked_fill(src_key_padding_mask, float('-inf'))
print("Encoder attention weight after key padding:")
print(weight)
# 计算softmax值
weight = torch.softmax(weight, dim=-1)  # [src_len, src_len]
# 得到加权后的输出(记忆)
memory = weight @ v  # [src_len, d_model]# =================== 解码器部分 ===================
## ------------------ 带遮罩的自注意力机制
# 随机生成目标序列的嵌入表示
tgt_em_input = torch.randn(tgt_len, d_model)
# 创建目标序列的填充掩码
tgt_key_padding_mask = torch.tensor([[False, False, False, True, True, True]])
# 创建上三角矩阵作为遮罩,防止未来信息泄露
attn_mask = (torch.triu(torch.ones((tgt_len, tgt_len))) == 1).transpose(0, 1)
attn_mask = attn_mask.float().masked_fill(attn_mask == 0, float('-inf')).masked_fill(attn_mask == 1, float(0.))
# 定义线性变换层用于计算Q、K、V
q_proj1 = nn.Linear(d_model, d_model)
k_proj1 = nn.Linear(d_model, d_model)
v_proj1 = nn.Linear(d_model, d_model)
# 计算Q、K、V
q, k, v = q_proj1(tgt_em_input), k_proj1(tgt_em_input), v_proj1(tgt_em_input)  # [tgt_len, d_model]
# 计算注意力权重
weight = q @ k.transpose(0, 1)  # [tgt_len, tgt_len]
weight += attn_mask
print("Decoder masked attention weight before key padding:")
print(weight)# 这里控制是否应用填充掩码
weight = weight.masked_fill(tgt_key_padding_mask, float('-inf'))
print("Decoder masked attention weight after key padding:")
print(weight)weight = torch.softmax(weight, dim=-1)  # [tgt_len, tgt_len]
output = weight @ v  # [tgt_len, tgt_len] @ [tgt_len, d_model]## ------------------ 交叉注意力机制
# 定义线性变换层用于计算Q、K、V
q_proj2 = nn.Linear(d_model, d_model)
k_proj2 = nn.Linear(d_model, d_model)
v_proj2 = nn.Linear(d_model, d_model)
# 计算Q、K、V,其中K和V来自编码器的记忆
q, k, v = q_proj2(output), k_proj2(memory), v_proj2(memory)  # q: [tgt_len, d_model], k,v: [src_len, d_model]
# 计算注意力权重
weight = q @ k.transpose(0, 1)  # [tgt_len, src_len]
# 应用源序列的填充掩码
weight = weight.masked_fill(src_key_padding_mask, float('-inf'))
weight = torch.softmax(weight, dim=-1)
output = weight @ v  # [tgt_len, d_model]# =================== 损失计算 ===================
# 定义目标标签和损失函数
tgt = torch.tensor([1, 2, 3, 0, 0, 0], dtype=torch.long)
loss_fcn = torch.nn.CrossEntropyLoss(ignore_index=0)  # 忽略填充标记(这里为0)的损失计算
loss = loss_fcn(output, tgt)
print(loss)

完整transformer代码

import torch
import torch.nn as nn
import math
from torch.nn import Transformer
from torch.utils.data import Dataset, DataLoader
from torch.nn.utils.rnn import pad_sequence# -------------------- 1. 数据集生成 --------------------
class MyDataset(Dataset):def __init__(self, num_samples=1000, max_len=10, vocab_size=20):"""生成随机长度的数字序列数据集关键点:- 序列长度随机(模拟真实场景的变长序列)- 0被保留为填充符号,因此有效token从1开始"""self.data = []for _ in range(num_samples):# 生成3到max_len之间的随机长度seq_len = torch.randint(3, max_len, (1,)).item()# 生成序列内容(注意:从1开始,0留给填充)sequence = torch.randint(1, vocab_size, (seq_len,))self.data.append(sequence)def __len__(self):return len(self.data)def __getitem__(self, idx):return self.data[idx]# -------------------- 2. 数据处理与填充 --------------------
def collate_fn(batch):"""批处理函数,主要完成:1. 动态填充:将不同长度的序列填充到相同长度2. 生成目标序列(输入右移一位)3. 注意:实际任务中需要根据任务类型调整目标生成方式"""# 对输入进行填充(batch_first=True表示batch维度在前)# padding_value=0 表示用0填充短序列padded_inputs = pad_sequence(batch, batch_first=True, padding_value=0)# 生成目标序列(将输入序列右移一位,末尾补0)# 例如:输入 [1,2,3] → 目标 [2,3,0]targets = pad_sequence([torch.cat([seq[1:], torch.tensor([0])]) for seq in batch],batch_first=True, padding_value=0)return padded_inputs, targets# -------------------- 3. 位置编码 --------------------
class PositionalEncoding(nn.Module):def __init__(self, d_model, max_len=5000):"""位置编码实现:- 使用正弦和余弦函数生成位置编码- 公式:PE(pos,2i) = sin(pos/10000^(2i/d_model))PE(pos,2i+1) = cos(pos/10000^(2i/d_model))"""super().__init__()# 创建位置编码矩阵 (max_len, d_model)pe = torch.zeros(max_len, d_model)# 生成位置序列 (0到max_len-1)position = torch.arange(0, max_len, dtype=torch.float).unsqueeze(1)# 计算div_term用于调整正弦波频率div_term = torch.exp(torch.arange(0, d_model, 2).float() * (-math.log(10000.0) / d_model))# 填充位置编码矩阵pe[:, 0::2] = torch.sin(position * div_term)  # 偶数位置用sinpe[:, 1::2] = torch.cos(position * div_term)  # 奇数位置用cos# 扩展维度:(1, max_len, d_model) 用于后续广播pe = pe.unsqueeze(0)# 注册为缓冲区(不参与训练,但会保存到模型参数中)self.register_buffer('pe', pe)def forward(self, x):"""将位置编码添加到输入嵌入中x的形状:(batch_size, seq_len, d_model)"""# self.pe[:, :x.size(1), :] 自动广播到batch维度x = x + self.pe[:, :x.size(1), :]return x# -------------------- 4. Transformer模型 --------------------
class TransformerModel(nn.Module):def __init__(self, vocab_size, d_model=128, nhead=4, num_layers=2):"""Transformer模型组成:- 嵌入层:将离散token转换为连续向量- 位置编码:添加序列位置信息- Transformer核心层:处理序列关系- 全连接层:输出词表概率分布"""super().__init__()# 嵌入层(注意设置padding_idx=0)self.embedding = nn.Embedding(vocab_size, d_model, padding_idx=0  # 重要!使填充位置的嵌入向量为全零)# 位置编码self.pos_encoder = PositionalEncoding(d_model)# Transformer核心self.transformer = Transformer(d_model=d_model,nhead=nhead,          # 注意力头数(需要能被d_model整除)num_encoder_layers=num_layers,num_decoder_layers=num_layers,batch_first=True      # 使用(batch, seq, feature)格式)# 输出层self.fc = nn.Linear(d_model, vocab_size)def forward(self, src, src_key_padding_mask):"""前向传播过程:1. 嵌入层 → 2. 缩放 → 3. 位置编码 → 4. Transformer处理 → 5. 输出投影注意:本例简化了decoder输入,实际任务需要区分encoder/decoder输入"""# 步骤1:词嵌入(将整数索引转换为向量)# src形状:(batch_size, seq_len) → (batch_size, seq_len, d_model)src_emb = self.embedding(src)# 步骤2:缩放嵌入向量(根据Transformer论文的建议)src_emb = src_emb * math.sqrt(self.embedding.embedding_dim)# 步骤3:添加位置编码src_emb = self.pos_encoder(src_emb)# 步骤4:通过Transformer(这里简化为使用相同输入作为encoder/decoder输入)# 注意:实际任务中decoder应有不同的输入(如右移的目标序列)output = self.transformer(src_emb,            # encoder输入src_emb,            # decoder输入(本例简化处理)src_key_padding_mask=src_key_padding_mask,  # 屏蔽encoder填充位置tgt_key_padding_mask=src_key_padding_mask   # 屏蔽decoder填充位置)# 步骤5:投影到词表空间# 输出形状:(batch_size, seq_len, vocab_size)return self.fc(output)# -------------------- 5. 训练配置 --------------------
vocab_size = 20    # 词表大小(含填充符0)
batch_size = 32    # 批大小
d_model = 128      # 模型维度
epochs = 10        # 训练轮数# 创建数据加载器
dataset = MyDataset()
dataloader = DataLoader(dataset, batch_size=batch_size, collate_fn=collate_fn,  # 使用自定义的批处理函数shuffle=True
)# 初始化模型和优化器
model = TransformerModel(vocab_size)
# 使用交叉熵损失,忽略填充位置(ignore_index=0)
criterion = nn.CrossEntropyLoss(ignore_index=0)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)# -------------------- 6. 训练循环 --------------------
for epoch in range(epochs):total_loss = 0for inputs, targets in dataloader:"""训练步骤详解:1. 生成padding mask2. 前向传播3. 计算损失(忽略填充位置)4. 反向传播"""# 生成padding mask(True表示需要屏蔽的填充位置)# 原理:找出inputs中等于0的位置(即填充位置)mask = (inputs == 0)# 前向传播outputs = model(inputs, src_key_padding_mask=mask)# 计算损失# 将输出展平为(batch_size*seq_len, vocab_size)logits = outputs.view(-1, vocab_size)# 将目标展平为(batch_size*seq_len)labels = targets.view(-1)# 计算交叉熵损失(自动忽略labels为0的位置)loss = criterion(logits, labels)# 反向传播optimizer.zero_grad()  # 清空梯度loss.backward()        # 计算梯度optimizer.step()       # 更新参数total_loss += loss.item()# 打印每轮平均损失avg_loss = total_loss / len(dataloader)print(f"Epoch {epoch+1}/{epochs} | Loss: {avg_loss:.4f}")print("训练完成!")"""
关键概念总结:
1. 动态填充:每个batch独立填充到当前batch的最大长度,节省内存
2. Padding Mask:- 形状:(batch_size, seq_len)- True表示对应位置是填充,需要被注意力机制忽略
3. 位置编码:为每个位置生成唯一编码,使模型感知序列顺序
4. 注意力屏蔽:防止模型关注填充位置和未来信息(解码器)
5. 损失忽略:计算损失时跳过填充位置,避免影响参数更新
"""

相关文章:

Transformer模型中的两种掩码

模型训练通常使用 批处理batch来提升训练效率。而实际中Transformer的输入序列&#xff08;如句子、文本片段&#xff09;长度往往不一致。为了让这些样本可以组成一个统一的形状 [B, T] 的张量给GPU进行并行计算提高效率&#xff0c;需要将较短的序列填充&#xff08;pad&…...

FastAPI-MPC正式发布,新的AI敏捷开发利器

FastAPI-MCP发布&#xff1a;零配置构建微服务控制平台的革命性实践 引言 在微服务架构日益复杂的今天&#xff0c;如何快速实现API接口的标准化管理与可视化控制成为开发者面临的核心挑战。近日&#xff0c;FastAPI-MCP工具的发布引发了技术社区广泛关注&#xff0c;其宣称能…...

Spring Boot 项目基于责任链模式实现复杂接口的解耦和动态编排!

全文目录&#xff1a; 开篇语前言一、责任链模式概述责任链模式的组成部分&#xff1a; 二、责任链模式的核心优势三、使用责任链模式解耦复杂接口1. 定义 Handler 接口2. 实现具体的 Handler3. 创建订单对象4. 在 Spring Boot 中使用责任链模式5. 配置责任链6. 客户端调用 四、…...

学习笔记八——内存管理相关

&#x1f4d8; 目录 内存结构基础&#xff1a;栈、堆、数据段Rust 的内存管理机制&#xff08;对比 C/C、Java&#xff09;Drop&#xff1a;Rust 的自动清理机制Deref&#xff1a;为什么 *x 能访问结构体内部值Rc&#xff1a;多个变量“共享一个资源”怎么办&#xff1f;Weak&…...

Deepseek Bart模型相比Bert的优势

BART&#xff08;Bidirectional and Auto-Regressive Transformers&#xff09;与BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;虽然均基于Transformer架构&#xff0c;但在模型设计、任务适配性和应用场景上存在显著差异。以下是BART…...

Python在糖尿病分类问题上寻找具有最佳 ROC AUC 分数和 PR AUC 分数(决策树、逻辑回归、KNN、SVM)

Python在糖尿病分类问题上寻找具有最佳 ROC AUC 分数和 PR AUC 分数&#xff08;决策树、逻辑回归、KNN、SVM&#xff09; 问题模板解题思路1. 导入必要的库2. 加载数据3. 划分训练集和测试集4. 数据预处理5. 定义算法及其参数6. 存储算法和对应指标7. 训练模型并计算指标8. 找…...

达梦数据库-学习-20-慢SQL优化之CTE等价改写

目录 一、环境信息 二、介绍 三、优化过程 1、原始SQL 2、源SQL执行时间 3、原始SQL执行计划 4、拆分问题 5、过滤性 6、统计信息收集 7、改写思路一 8、改写SQL一 9、改写SQL一的执行计划 10、改写思路二 11、改写SQL二 12、改写SQL二的执行计划 一、环境信息…...

软件生命周期模型:瀑布模型、螺旋模型、迭代模型、敏捷开发、增量模型、快速原型模型

目录 1.软件生命周期 2.软件生命周期模型 2.1瀑布模型 缺点【存在的问题】&#xff1a; 优点&#xff1a; 2.2 螺旋模型 特点&#xff1a; 2.3 迭代模型 优点&#xff1a; 2.4 敏捷开发 2.5 增量模型 增量模型一般和迭代模型一起使用&#xff1a; 2.6 快速原型模型…...

AI agents系列之全面介绍

随着大型语言模型(LLMs)的出现,人工智能(AI)取得了巨大的飞跃。这些强大的系统彻底改变了自然语言处理,但当它们与代理能力结合时,才真正释放出潜力——能够自主地推理、规划和行动。这就是LLM代理大显身手的地方,它们代表了我们与AI交互以及利用AI的方式的范式转变。 …...

Ubuntu 下通过 Docker 部署 WordPress 服务器

最近想恢复写私人博客的习惯&#xff0c;准备搭建一个wordpress。 在这篇博客中&#xff0c;我将记录如何在 Ubuntu 环境下通过 Docker 部署一个 WordPress 服务器。WordPress 是一个流行的内容管理系统&#xff08;CMS&#xff09;&#xff0c;它让用户能够轻松地创建和管理网…...

Elasticsearch生态

目录 Elasticsearch核心概念 Elasticsearch实现全文检索的原理 Elasticsearch打分规则 常用的查询语法 ES数据同步方案 Elasticsearch生态非常丰富&#xff0c;包含了一系列工具和功能&#xff0c;帮助用户处理、分析和可视化数据&#xff0c;Elastic Stack是其核心部分&a…...

idea配置spring MVC项目启动(maven配置完后)

springmvc项目在idea中配置启动总结&#xff0c;下面的内容是在maven配置好后进行的。 配置 Tomcat 服务器 添加 Tomcat 到 IDEA&#xff1a; File → Settings → Build, Execution, Deployment → Application Servers → 点击 → 选择 Tomcat Server。 指定 Tomcat 安装目…...

大模型微调数据集怎么搞?基于easydataset实现文档转换问答对json数据集!

微调的难点之一在与数据集。本文介绍一种将文档转换为问答数据集的方法&#xff0c;超级快&#xff01; 上图左侧是我的原文档&#xff0c;右侧是我基于文档生成的数据集。 原理是通过将文档片段发送给ollama本地模型&#xff0c;然后本地模型生成有关问题&#xff0c;并基于文…...

【排序算法】快速排序

目录 一、递归版本 1.1 hoare版本 问题1&#xff1a;为什么left 和 right指定的数据和key值相等时不能交换&#xff1f; 问题2&#xff1a;为什么跳出循环后right位置的值⼀定不⼤于key&#xff1f; 1.2 挖坑法 1.3 lomuto前后指针版本 二、快排优化 2.1 时间复杂度的计算 2.1.…...

爬虫:IP代理

什么是代理 代理服务器 代理服务器的作用 就是用来转发请求和响应 在爬虫中为何需要使用代理&#xff1f; 有些时候&#xff0c;需要对网站服务器发起高频的请求&#xff0c;网站的服务器会检测到这样的异常现象&#xff0c;则会讲请求对应机器的ip地址加入黑名单&#xff…...

JUC.atomic原子操作类原理分析

摘要 多线程场景下共享变量原子性操作除了可以使用Java自带的synchronized关键字以及AQS锁实现线程同步外&#xff0c;java.util.concurrent.atomic 包下提供了对基本类型封装类(AtomicBoolean|AtomicLong|AtomicReference|AtomicBoolean) 以及对应的数组封装。对于已有的包含…...

【XCP实战】AUTOSAR架构下XCP从0到1开发配置实践

目录 前言 正文 1.CAN功能开发 1.1 DBC的制作及导入 1.2 CanTrcv模块配置 1.3 Can Controller模块配置 1.4 CanIf模块配置 2.XCP模块集成配置配置 2.1.XCP模块配置 2.2.XCP模块的Task Mapping 2.3.XCP模块的初始化 3.在链接文件中定义标定段 4.编写标定相关的测试…...

【STM32】STemWin库,使用template API

目录 CubeMX配置 工程文件配置 Keil配置 STemwin配置 GUIConf.c LCDConf.c 打点函数 修改屏幕分辨率 GUI_X.c 主函数 添加区域填充函数 移植过程中需要一些参考手册&#xff0c;如下 STemwin使用指南 emWin User Guide & Reference Manual CubeMX配置 参考驱…...

Web开发-JavaEE应用动态接口代理原生反序列化危险Invoke重写方法利用链

知识点&#xff1a; 1、安全开发-JavaEE-动态代理&序列化&反序列化 2、安全开发-JavaEE-readObject&toString方法 一、演示案例-WEB开发-JavaEE-动态代理 动态代理 代理模式Java当中最常用的设计模式之一。其特征是代理类与委托类有同样的接口&#xff0c;代理类…...

C语言中while的相关题目

一、题目引入 以下程序中,while循环的循环次数是多少次? 二、代码分析 首先要明确的一点 while循环是当循环条件为真 就会一直循环 不会停止 while中i是小于10的 说明i可以取到0 1 2 3 4 5 6 7 8 9 进入第一个if判断i小于1为真时执行continue i0是为真的 执行continue 后…...

在Ubuntu下交叉编译 Qt 应用程序(完整步骤)

1、下载交叉编译器下&#xff1a; st-example-image-qt wayland-openstlinux-weston-stm32mp1-x86_64-toolchain-3.1-snapshot.sh 通过网盘分享的文件&#xff1a;STM32项目 链接: https://pan.baidu.com/s/1hTvJT2r6czWCrKSuNEZCuw?pwdth7t 提取码: th7t --来自百度网盘超级…...

深入剖析 Axios 的 POST 请求:何时使用 qs 处理数据

在前端开发中&#xff0c;Axios 是一个广泛使用的用于发送 HTTP 请求的库&#xff0c;特别是在处理 POST 请求时&#xff0c;数据的处理方式会直接影响到请求能否正确被后端接收和处理。其中&#xff0c;使用 qs 库对数据进行处理是一个常见的操作点&#xff0c;本文将深入探讨…...

Python中NumPy的随机操作

在数据科学、机器学习和科学计算中&#xff0c;随机数的生成和操作是不可或缺的一部分。NumPy作为Python中强大的数值计算库&#xff0c;提供了丰富的随机数生成工具&#xff0c;能够满足从简单随机数生成到复杂概率分布模拟的多种需求。本文将深入探讨NumPy的随机操作功能&…...

从代码学习深度学习 - 多头注意力 PyTorch 版

文章目录 前言一、多头注意力机制介绍1.1 工作原理1.2 优势1.3 代码实现概述二、代码解析2.1 导入依赖序列掩码函数2.2 掩码 Softmax 函数2.3 缩放点积注意力2.4 张量转换函数2.5 多头注意力模块2.6 测试代码总结前言 在深度学习领域,注意力机制(Attention Mechanism)是自然…...

通过扣子平台工作流将数据写入飞书多维表格

1. 进入扣子平台&#xff0c;并创建工作流扣子 扣子是新一代 AI 大模型智能体开发平台。整合了插件、长短期记忆、工作流、卡片等丰富能力&#xff0c;扣子能帮你低门槛、快速搭建个性化或具备商业价值的智能体&#xff0c;并发布到豆包、飞书等各个平台。https://www.coze.cn…...

python专题2-----用python生成多位,值均是数字的随机数

有很多方法可以用 Python 生成 多位随机数。我将向您介绍几个常用的方法&#xff0c;并解释它们的优缺点&#xff08;此处以4位随机数为例&#xff09;&#xff1a; 1. 使用 random.randint() 这是最简单直接的方法&#xff1a; import randomrandom_number random.randint…...

Mybatis的简单介绍

文章目录 MyBatis 简介 1. MyBatis 核心特点2. MyBatis 核心组件3. MyBatis 基本使用示例(1) 依赖引入&#xff08;Maven&#xff09;(2) 定义 Mapper 接口(3) 定义实体类(4) 在 Service 层调用 4. MyBatis 与 JPA/Hibernate 对比 MyBatis 简介 MyBatis 是一款优秀的 持久层框…...

山东大学软件学院创新项目实训(11)之springboot+vue项目接入deepseekAPI

因为该阶段是前后端搭建阶段&#xff0c;所以没有进大模型的专项训练&#xff0c;所以先用老师给的deepseek接口进行代替 且因为前端设计部分非本人负责且还没有提交到github上&#xff0c;所以目前只能先编写一个简易的界面进行功能的测试 首先进行创建model类 然后创建Cha…...

Qt绘图事件

目录 1.绘图事件 1.1绘图事件 1.2声明一个画家对象 2.画线、画圆、画矩形、画文字 2.1画线 ​编辑 2.2画圆 2.3画矩形 2.4画文字 3.设置画笔 3.1设置画笔颜色 3.2设置画笔宽度 3.3设置画笔风格 4.设置画刷 4.1填色 4.2设置画刷风格 5.绘图高级设置 5.1设置抗锯…...

Linux 内核 BUG: Android 手机 USB 网络共享 故障

众所周知, 窝日常使用 ArchLinux 操作系统, 而 ArchLinux 是一个滚动发行版本, 也就是各个软件包更新很快. 然而, 突然发现, Android 手机的 USB 网络共享功能 BUG 了. 经过一通排查, 发现是 Linux 内核造成的 BUG. 哎, 没办法, 只能自己动手修改内核代码, 修复 BUG 了. 本文…...

程序化广告行业(82/89):解锁行业术语,开启专业交流之门

程序化广告行业&#xff08;82/89&#xff09;&#xff1a;解锁行业术语&#xff0c;开启专业交流之门 在程序化广告这个充满活力与挑战的行业里&#xff0c;持续学习是我们不断进步的动力源泉。一直以来&#xff0c;我都期望能和大家一起深入探索这个领域&#xff0c;共同成长…...

Linux的网络配置的资料

目前有两种方式&#xff0c;network和NetworkManager。 network方式是在CentOS 6及更早版本中引入的配置方法&#xff0c;支持使用配置文件的方式管理网卡的配置。 NetworkManager是在CentOS 7及后续的版本中使用的配置方法&#xff0c;支持使用命令行和图形化界面的方式来管理…...

linux: 文件描述符fd

目录 1.C语言文件操作复习 2.底层的系统调用接口 3.文件描述符的分配规则 4.重定向 1.C语言文件操作复习 文件 内容 属性。所有对文件的操作有两部分&#xff1a;a.对内容的操作&#xff1b;b.对属性的操作。内容是数据&#xff0c;属性其实也是数据-存储文件&#xff0c…...

每天学一个 Linux 命令(16):mkdir

每天学一个 Linux 命令(16):mkdir 命令简介 mkdir(Make Directory)是 Linux 和类 Unix 系统中用于创建新目录的基础命令。它允许用户快速创建单个目录、多级嵌套目录,并能灵活设置目录权限。 主要用途 创建单个目录:快速生成新的空目录。递归创建多级目录:自动生成缺…...

Java微服务注册中心深度解析:环境隔离、分级模型与Eureka/Nacos对比

在微服务架构体系中&#xff0c;注册中心如同神经系统般承担着服务发现与健康管理的核心职能。本文将从生产环境实践出发&#xff0c;系统剖析注册中心的环境隔离策略、分级部署模型&#xff0c;并通过Eureka与Nacos两大主流组件的全方位对比&#xff0c;帮助开发者构建高可用服…...

c++:new关键字

目录 基本语法 使用举例 应用场景 使用 new 时的注意事项 基本语法 Type* ptr new Type;Type 是你要创建的类型&#xff08;可以是基本类型、结构体、类等&#xff09; new Type 表示在堆上创建一个 Type 类型的对象 ptr 是一个指针&#xff0c;指向这个对象 使用举例 …...

理解 MCP 协议的数据传递:HTTP 之上的一层“壳子

以下是以 CSDN 博客的风格记录你对 MCP 协议数据传递的理解和发现&#xff0c;内容涵盖了 MCP 协议基于 HTTP 的本质、JSON-RPC 的“壳子”作用&#xff0c;以及为什么熟悉 HTTP 协议就足以理解 MCP 的数据传递。文章面向技术社区&#xff0c;结构清晰&#xff0c;适合分享。 理…...

word中的mathtype公式编辑时,大(中)括号会存在很大的空白

如下所示&#xff0c;公式编辑的时候发现总会多一个空白&#xff0c;怎么删也删不掉 这主要是公式的分隔符问题&#xff0c;选择&#xff1a;“格式”-“分隔符对齐”&#xff0c;选择第三个可以消除下面的空白 点击“确认”&#xff0c;效果如下所示&#xff1a;...

【Java】查看当前 Java 使用的垃圾回收器

一、查询 Code import java.lang.management.GarbageCollectorMXBean; import java.lang.management.ManagementFactory; import java.util.Arrays; import java.util.List;public class GCTypeDetector {public static void main(String[] args) {List<GarbageCollectorMX…...

Linux编程c/c++程序

前言 我们Windows系统下的idea可以说是非常智能了&#xff0c;集成了各种开发工具&#xff0c;包括并不限于编辑器/编译器/调试器/自动化构建工具/版本控制工具……而在Linux系统中&#xff0c;每个组件之间是相互独立的&#xff0c;每个组件各司其职&#xff0c;共同协作完成…...

【前端网络请求入门】XMLHttpRequest与Fetch保姆级教程

新手学前端时&#xff0c;经常会被「如何让网页和服务器说话」难住。今天我们用最通俗的语言&#xff0c;把浏览器最常用的两种网络请求方式——XMLHttpRequest和Fetch讲清楚&#xff0c;还会带完整的代码示例&#xff0c;跟着敲一遍就能上手&#xff01; 一、先搞懂「网络请求…...

redis单机安装

redis单机安装 下载地址 官网&#xff1a;https://redis.io/下载列表页面&#xff1a;https://download.redis.io/releases/ 说明 版本选择&#xff1a;redis-7.0.0.tar.gz下载地址&#xff1a;https://download.redis.io/releases/redis-7.0.0.tar.gz 安装前准备 在linu…...

从零手写RPC-version0

参考文档 https://github.com/he2121/MyRPCFromZero Version-0 0、写项目第一步&#xff0c;先添加远程仓库 先在 github 上新建仓库&#xff0c;然后将本地新建的项目推送到远程仓库中 由于网上很多教程&#xff0c;所以本节不再赘述&#xff08;可以让 chatGPT给出一个完…...

MOM成功实施分享(八)汽车活塞生产制造MOM建设方案(第二部分)

在制造业数字化转型的浪潮中&#xff0c;方案对活塞积极探索&#xff0c;通过实施一系列数字化举措&#xff0c;在生产管理、供应链协同、质量控制等多个方面取得显著成效&#xff0c;为行业提供了优秀范例。 1.转型背景与目标&#xff1a;活塞在数字化转型前面临诸多挑战&…...

二、Android Studio环境安装

一、下载安装 下载 Android Studio 和应用工具 - Android 开发者 | Android DevelopersAndroid Studio 提供了一些应用构建器以及一个已针对 Android 应用进行优化的集成式开发环境 (IDE)。立即下载 Android Studio。https://developer.android.google.cn/studio?hlzh-c…...

构件与中间件技术:概念、复用、分类及标准全解析

以下是对构件与中间件技术相关内容更详细的介绍&#xff1a; 一、构件与中间件技术的概念 1.构件技术 定义&#xff1a;构件是具有特定功能、可独立部署和替换的软件模块&#xff0c;它遵循一定的规范和接口标准&#xff0c;能够在不同的软件系统中被复用。构件技术就是以构…...

亲手打造可视化故事线管理工具:开发全流程、难点突破与开发过程经验总结

亲手打造可视化故事线管理工具&#xff1a;开发全流程、难点突破与开发过程经验总结 作为还没入门的业余编程爱好者&#xff0c;奋战了2天&#xff0c;借助AI开发一款FLASK小工具&#xff0c;功能还在完善中&#xff08;时间轴可以跟随关联图缩放&#xff0c;加了一个用C键控制…...

CSS 字体学习笔记

在网页设计中&#xff0c;字体的使用对于提升用户体验和页面美观性至关重要。CSS 提供了一系列字体属性&#xff0c;用于控制文本的显示效果。以下是对 CSS 字体属性的详细学习笔记。 一、字体系列&#xff08;font-family&#xff09; 1. 字体系列的分类 在 CSS 中&#xf…...

通过 spring ai 对接 deepseek ai 大模型通过向量数据库,完成 AI 写标书及构建知识库功能的设计与开发

AI写标书及知识库构建详细设计方案 一、系统架构设计 +-------------------+ +-------------------+ +-------------------+ | 用户交互层 | | AI服务层 | | 知识库存储层 | | (Web/API) |---->| (Spring AI) |---…...

cropperjs 2.0裁剪图片后转base64提示“Tainted canvases may not be exported”跨域问题的解决办法。

目录 为什么会有这边文章 辛酸历程&#xff0c;不看也罢 想解决问题&#xff0c;看这里就够了 问题已解决&#xff0c;后边还是废话 为什么会有这边文章 最近&#xff0c;做一个项目需要用在前端实现图片裁剪功能&#xff0c;毋庸置疑&#xff0c;cropperjs是不二选择。当在…...