Day08【基于预训练模型分词器实现交互型文本匹配】
基于预训练模型分词器实现交互型文本匹配
- 目标
- 数据准备
- 参数配置
- 数据处理
- 模型构建
- 主程序
- 测试与评估
- 总结
目标
本文基于预训练模型bert
分词器BertTokenizer
,将输入的文本以文本对的形式,送入到分词器中得到文本对的词嵌入向量,之后经过若干网络层,输出在已知2类别匹配或不匹配的概率分布,从而实现一个简单的句子对级别的匹配任务。
数据准备
预训练模型bert-base-chinese预训练模型
类别标签文件schema.json
{"停机保号": 0,"密码重置": 1,"宽泛业务问题": 2,"亲情号码设置与修改": 3,"固话密码修改": 4,"来电显示开通": 5,"亲情号码查询": 6,"密码修改": 7,"无线套餐变更": 8,"月返费查询": 9,"移动密码修改": 10,"固定宽带服务密码修改": 11,"UIM反查手机号": 12,"有限宽带障碍报修": 13,"畅聊套餐变更": 14,"呼叫转移设置": 15,"短信套餐取消": 16,"套餐余量查询": 17,"紧急停机": 18,"VIP密码修改": 19,"移动密码重置": 20,"彩信套餐变更": 21,"积分查询": 22,"话费查询": 23,"短信套餐开通立即生效": 24,"固话密码重置": 25,"解挂失": 26,"挂失": 27,"无线宽带密码修改": 28
}
训练集数据train.json训练集数据
验证集数据valid.json验证集数据
参数配置
config.py
# -*- coding: utf-8 -*-"""
配置参数信息
"""Config = {"model_path": "model_output","schema_path": "../data/schema.json","train_data_path": "../data/train.json","valid_data_path": "../data/valid.json","pretrain_model_path":r"../../../bert-base-chinese","vocab_path":r"../../../bert-base-chinese/vocab.txt","max_length": 20,"hidden_size": 256,"epoch": 10,"batch_size": 128,"epoch_data_size": 10000, #每轮训练中采样数量"positive_sample_rate":0.5, #正样本比例"optimizer": "adam","learning_rate": 1e-3,
}
数据处理
loader.py
# -*- coding: utf-8 -*-import json
import re
import os
import torch
import random
import logging
from torch.utils.data import Dataset, DataLoader
from collections import defaultdict
from transformers import BertTokenizer
"""
数据加载
"""logging.getLogger("transformers").setLevel(logging.ERROR)class DataGenerator:def __init__(self, data_path, config):self.config = configself.path = data_pathself.tokenizer = load_vocab(config["vocab_path"])self.config["vocab_size"] = len(self.tokenizer.vocab)self.schema = load_schema(config["schema_path"])self.train_data_size = config["epoch_data_size"] #由于采取随机采样,所以需要设定一个采样数量,否则可以一直采self.max_length = config["max_length"]self.data_type = None #用来标识加载的是训练集还是测试集 "train" or "test"self.load()def load(self):self.data = []self.knwb = defaultdict(list)with open(self.path, encoding="utf8") as f:for line in f:line = json.loads(line)#加载训练集if isinstance(line, dict):self.data_type = "train"questions = line["questions"]label = line["target"]for question in questions:self.knwb[self.schema[label]].append(question)#加载测试集else:self.data_type = "test"assert isinstance(line, list)question, label = linelabel_index = torch.LongTensor([self.schema[label]])self.data.append([question, label_index])return#每次加载两个文本,输出他们的拼接后编码def encode_sentence(self, text1, text2):input_id = self.tokenizer.encode(text1, text2,truncation='longest_first',max_length=self.max_length,padding='max_length',)return input_iddef __len__(self):if self.data_type == "train":return self.config["epoch_data_size"]else:assert self.data_type == "test", self.data_typereturn len(self.data)def __getitem__(self, index):if self.data_type == "train":return self.random_train_sample() #随机生成一个训练样本else:return self.data[index]#依照一定概率生成负样本或正样本#负样本从随机两个不同的标准问题中各随机选取一个#正样本从随机一个标准问题中随机选取两个def random_train_sample(self):standard_question_index = list(self.knwb.keys())#随机正样本if random.random() <= self.config["positive_sample_rate"]:p = random.choice(standard_question_index)#如果选取到的标准问下不足两个问题,则无法选取,所以重新随机一次if len(self.knwb[p]) < 2:return self.random_train_sample()else:s1, s2 = random.sample(self.knwb[p], 2)input_ids = self.encode_sentence(s1, s2)input_ids = torch.LongTensor(input_ids)return [input_ids, torch.LongTensor([1])]#随机负样本else:p, n = random.sample(standard_question_index, 2)s1 = random.choice(self.knwb[p])s2 = random.choice(self.knwb[n])input_ids = self.encode_sentence(s1, s2)input_ids = torch.LongTensor(input_ids)return [input_ids, torch.LongTensor([0])]#加载字表或词表
def load_vocab(vocab_path):tokenizer = BertTokenizer(vocab_path)return tokenizer#加载schema
def load_schema(schema_path):with open(schema_path, encoding="utf8") as f:return json.loads(f.read())#用torch自带的DataLoader类封装数据
def load_data(data_path, config, shuffle=True):dg = DataGenerator(data_path, config)dl = DataLoader(dg, batch_size=config["batch_size"], shuffle=shuffle)return dl
这段目的是用于构建一个数据加载和处理系统,主要针对自然语言处理(NLP)任务中的文本对比训练,例如句子相似度、问答匹配等任务。具体来说,代码实现了以下功能:
-
数据加载与解析:
- 通过
DataGenerator
类从指定的文件路径加载数据,支持训练集和测试集的加载。 - 对于训练集数据,支持从标准问题中随机选择问题对,生成正样本(相同标签的两个问题)和负样本(不同标签的两个问题)。
- 对于测试集数据,加载并按序存储问题和标签。
- 通过
-
数据编码:
- 使用
BertTokenizer
对文本进行分词和编码,将输入文本(这里输入的是文本对
)转化为BERT模型可以处理的格式(即input_ids
)。
- 使用
-
正负样本生成:
- 通过
random_train_sample
函数,生成正样本和负样本。正样本是从同一类别中随机选择两个问题,而负样本是从不同类别中各选择一个问题。
- 通过
-
数据批量加载:
- 利用
torch.utils.data.DataLoader
将数据封装成批量加载格式,方便在训练过程中按批次加载数据,提高训练效率。
- 利用
总结
核心目的是为训练深度学习模型(如BERT等基于Transformer的模型)提供高效、灵活的数据加载和处理流程,特别是用于训练包含正负样本对比学习任务的模型。它支持从外部文件加载文本数据,进行编码,并生成带有标签的数据对,以供模型训练和评估使用。
模型构建
model.py
# -*- coding: utf-8 -*-import torch
import torch.nn as nn
from torch.optim import Adam, SGD
from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence
from transformers import BertModel, BertConfig"""
建立网络模型结构
"""class GetFirst(nn.Module):def __init__(self):super(GetFirst, self).__init__()def forward(self, x):return x[0]class SentenceMatchNetwork(nn.Module):def __init__(self, config):super(SentenceMatchNetwork, self).__init__()# 可以用bert,参考下面# pretrain_model_path = config["pretrain_model_path"]# self.bert_encoder = BertModel.from_pretrained(pretrain_model_path)# 常规的embedding + layerhidden_size = config["hidden_size"]#20000应为词表大小,这里借用bert的词表,没有用它精确的数字,因为里面有很多无用词,舍弃一部分,不影响效果self.embedding = nn.Embedding(20000, hidden_size)#一种多层按顺序执行的写法,具体的层可以换#unidirection:batch_size, max_len, hidden_size#bidirection:batch_size, max_len, hidden_size * 2self.encoder = nn.Sequential(nn.LSTM(hidden_size, hidden_size, bidirectional=True, batch_first=True),GetFirst(),nn.ReLU(),nn.Linear(hidden_size * 2, hidden_size), #batch_size, max_len, hidden_sizenn.ReLU(),)self.classify_layer = nn.Linear(hidden_size, 2)self.loss = nn.CrossEntropyLoss()# 同时传入两个句子的拼接编码# 输出一个相似度预测,不匹配的概率def forward(self, input_ids, target=None):# x = self.bert_encoder(input_ids)[1]#input_ids = batch_size, max_lengthx = self.embedding(input_ids) #x:batch_size, max_length, embedding_sizex = self.encoder(x) ##x: batch_size, max_len, hidden_sizex = nn.MaxPool1d(x.shape[1])(x.transpose(1,2)).squeeze()#x: batch_size, hidden_sizex = self.classify_layer(x)#x: batch_size, 2#如果有标签,则计算lossif target is not None:return self.loss(x, target.squeeze())#如果无标签,预测相似度else:return torch.softmax(x, dim=-1)[:, 1] #如果改为x[:,0]则是两句话不匹配的概率def choose_optimizer(config, model):optimizer = config["optimizer"]learning_rate = config["learning_rate"]if optimizer == "adam":return Adam(model.parameters(), lr=learning_rate)elif optimizer == "sgd":return SGD(model.parameters(), lr=learning_rate)
实现一个用于句子匹配任务的神经网络模型,具体结构包括以下部分:
-
GetFirst类:该类用于提取LSTM输出的第一个时间步的结果。它的作用是从LSTM的双向输出中获取第一个词的向量表示。
-
SentenceMatchNetwork类:
- 初始化:该模型首先定义了一个嵌入层(
nn.Embedding
),将输入的单词ID转化为词向量。然后通过双向LSTM进行编码,提取句子的特征。 - 编码器:使用LSTM(
nn.LSTM
)对输入句子进行处理,并应用GetFirst
提取LSTM输出的第一个时间步的特征。接着通过全连接层进行处理和降维。 - 分类层:将LSTM的输出传入一个全连接层,输出两类标签(匹配或不匹配)。使用
CrossEntropyLoss
计算损失。
- 初始化:该模型首先定义了一个嵌入层(
-
forward方法:此方法接收输入句子的ID和标签(如果有)。如果提供了标签,则计算损失;如果没有标签,则返回句子匹配的概率。
-
choose_optimizer函数:根据配置选择优化器(Adam或SGD)及学习率。
主程序
main.py
# -*- coding: utf-8 -*-import torch
import os
import random
import os
import numpy as np
import logging
from config import Config
from model import SentenceMatchNetwork, choose_optimizer
from evaluate import Evaluator
from loader import load_datalogging.basicConfig(level = logging.INFO,format = '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)"""
模型训练主程序
"""def main(config):#创建保存模型的目录if not os.path.isdir(config["model_path"]):os.mkdir(config["model_path"])#加载训练数据train_data = load_data(config["train_data_path"], config)#加载模型model = SentenceMatchNetwork(config)# 标识是否使用gpucuda_flag = torch.cuda.is_available()if cuda_flag:logger.info("gpu可以使用,迁移模型至gpu")model = model.cuda()#加载优化器optimizer = choose_optimizer(config, model)#加载效果测试类evaluator = Evaluator(config, model, logger)#训练for epoch in range(config["epoch"]):epoch += 1model.train()logger.info("epoch %d begin" % epoch)train_loss = []for index, batch_data in enumerate(train_data):optimizer.zero_grad()if cuda_flag: #如果gpu可用则使用gpu加速batch_data = [d.cuda() for d in batch_data]input_ids, labels = batch_dataloss = model(input_ids, labels) #计算losstrain_loss.append(loss.item())#每轮训练一半的时候输出一下loss,观察下降情况if index % int(len(train_data) / 2) == 0:logger.info("batch loss %f" % loss)loss.backward() #梯度计算optimizer.step() #梯度更新logger.info("epoch average loss: %f" % np.mean(train_loss))evaluator.eval(config["epoch"])model_path = os.path.join(config["model_path"], "epoch_%d.pth" % epoch)torch.save(model.state_dict(), model_path)returnif __name__ == "__main__":main(Config)
实现模型训练过程。首先,它加载训练数据并初始化模型,选择是否使用GPU加速。训练过程中,模型计算损失并通过反向传播更新参数,每个epoch结束后输出平均损失值。优化器用于更新模型权重,并通过Evaluator
类评估模型效果。最终,训练完成后,模型权重被保存到指定路径。整个过程确保了训练的高效性和可持续性,适用于深度学习任务中的模型训练与保存。
测试与评估
evaluate.py
# -*- coding: utf-8 -*-
import torch
from loader import load_data
import numpy as np"""
模型效果测试
"""class Evaluator:def __init__(self, config, model, logger):self.config = configself.model = modelself.logger = loggerself.valid_data = load_data(config["valid_data_path"], config, shuffle=False)# 由于效果测试需要训练集当做知识库,再次加载训练集。# 事实上可以通过传参把前面加载的训练集传进来更合理,但是为了主流程代码改动量小,在这里重新加载一遍self.train_data = load_data(config["train_data_path"], config)self.tokenizer = self.train_data.dataset.tokenizerself.stats_dict = {"correct":0, "wrong":0} #用于存储测试结果#将知识库中的问题向量化,为匹配做准备#每轮训练的模型参数不一样,生成的向量也不一样,所以需要每轮测试都重新进行向量化def knwb_to_vector(self):self.question_index_to_standard_question_index = {}self.questions = []for standard_question_index, questions in self.train_data.dataset.knwb.items():for question in questions:#记录问题编号到标准问题标号的映射,用来确认答案是否正确self.question_index_to_standard_question_index[len(self.questions)] = standard_question_indexself.questions.append(question)returndef eval(self, epoch):self.logger.info("开始测试第%d轮模型效果:" % epoch)self.stats_dict = {"correct":0, "wrong":0} #清空前一轮的测试结果self.model.eval()self.knwb_to_vector()for index, batch_data in enumerate(self.valid_data):test_questions, labels = batch_datapredicts = []for test_question in test_questions:input_ids = []for question in self.questions:input_ids.append(self.train_data.dataset.encode_sentence(test_question, question))with torch.no_grad():input_ids = torch.LongTensor(input_ids)if torch.cuda.is_available():input_ids = input_ids.cuda()scores = self.model(input_ids).detach().cpu().tolist()hit_index = np.argmax(scores)# print(hit_index)predicts.append(hit_index)self.write_stats(predicts, labels)self.show_stats()returndef write_stats(self, predicts, labels):assert len(labels) == len(predicts)for hit_index, label in zip(predicts, labels):hit_index = self.question_index_to_standard_question_index[hit_index] #转化成标准问编号if int(hit_index) == int(label):self.stats_dict["correct"] += 1else:self.stats_dict["wrong"] += 1returndef show_stats(self):correct = self.stats_dict["correct"]wrong = self.stats_dict["wrong"]self.logger.info("预测集合条目总量:%d" % (correct +wrong))self.logger.info("预测正确条目:%d,预测错误条目:%d" % (correct, wrong))self.logger.info("预测准确率:%f" % (correct / (correct + wrong)))self.logger.info("--------------------")return
实现一个用于模型效果评估的Evaluator
类。该类初始化时加载了验证数据和训练数据,其中训练数据被当作知识库用于匹配。knwb_to_vector
方法将训练数据中的问题向量化,并建立问题编号与标准问题编号的映射,以便在评估时正确匹配答案。eval
方法执行模型的评估过程,遍历验证数据集并将每个问题与知识库中的问题进行匹配,通过模型预测结果并计算正确与错误的预测。每次评估完成后,write_stats
方法记录正确和错误的预测次数,show_stats
方法则输出最终的评估结果,包括预测正确率。
总结
基于交互型文本匹配,每次都以句子对或文本对输入,输入到交互层,统一编码形式后经过网络层,最后到二分类表示层(当然也可以设置为多种关系,比如中性等,只不过这时数据采样部分的标签也要同步,损失函数也要对应适配),表示文本的配对情况。交互型文本匹配重点把握文本对之间的潜在关系,实际上也是一种对比学习思想。
相关文章:
Day08【基于预训练模型分词器实现交互型文本匹配】
基于预训练模型分词器实现交互型文本匹配 目标数据准备参数配置数据处理模型构建主程序测试与评估总结 目标 本文基于预训练模型bert分词器BertTokenizer,将输入的文本以文本对的形式,送入到分词器中得到文本对的词嵌入向量,之后经过若干网络…...
基于uniapp 实现画板签字
直接上效果图 代码 <template><view class"container"><!-- 签名画布 --><view class"canvas-container"><canvas canvas-id"signCanvas" class"sign-canvas"touchstart"handleTouchStart"touc…...
5.跳表(skiplist)
1. 什么是跳表 -skiplist skiplist 本质上也是一种查找结构,用于解决算法中的查找问题,跟平衡搜索树和哈希表的价值是一样的,可以作为key 或者 key/value 的查找模型。 skiplist ,顾名思义,首先它是一个 list 。实际上…...
GitHub 封禁中国 IP:影响、原因及应对
在技术全球化的当下,代码托管平台如同开发者的 “数字仓库”,而 GitHub 无疑是其中最广为人知的一座。但在 2025 年 4 月 13 日,一则令人震惊的消息在国内开发者社群中炸开了锅 ——GitHub 疑似封禁中国 IP。一时间,这一事件迅速成…...
基于工业操作系统构建企业数字化生态的实践指南
一、工业操作系统选型策略 工业操作系统(IIoT OS)的选型需从功能适配性、技术成熟度、生态兼容性三个维度综合评估。以玉麟科技DIOS平台为例,其 "云端 终端" 架构支持全球设备管理,通过工业知识模型实现设备健康度预测…...
金能电力领跑京东工业安全工器具赛道 2025年首季度数据诠释“头部效应”
金能电力领跑京东工业安全工器具赛道 2025年首季度数据诠释“头部效应” 在2025年第一季度京东工业平台“电料辅件-安全工器具”热销品牌的激烈竞争中,金能电力以一组极具说服力的数据,向行业展示了何为“绝对头部”。从成交金额、销量到流量、客群覆…...
基于大模型的反流食管炎手术全流程风险预测与治疗方案研究报告
目录 一、引言 1.1 研究背景 1.2 研究目的 1.3 研究方法与创新点 二、反流食管炎概述 2.1 定义与发病机制 2.2 临床症状与诊断标准 2.3 流行病学现状 三、大模型技术原理与应用现状 3.1 大模型基本原理 3.2 在医疗领域的应用案例 3.3 用于反流食管炎预测的优势 四…...
探索 C 与 Java/Kotlin 的语言差异:从指针到高阶函数
作为一名熟悉 Java 和 Kotlin 的开发者,初次接触 C/C 时常会遇到一系列概念上的“文化冲击”。本文将从几个关键点出发,帮助你更好地理解 C/C 与 Java/Kotlin 在语言设计上的核心区别。 1. 指向未知类型的指针 void*、结构体指针访问 ->、空指针常量 …...
Redis之缓存过期淘汰策略
面试切入点 Redis内存满了怎么办? redis的默认内存多少?在哪里查看?如何设置修改? 查看redis最大占用内存 打开redis配置文件,设置maxmemory参数,maxmemory是bytes字节类型,注意转换。 redi…...
Rust-引用借用规则
目录 一、概述 二、借用规则 三、详细解释 3.1 第一条规则 3.2 第二条规则 3.3 第三条规则 四、总结 Welcome to Code Blocks blog 本篇文章主要介绍了 [Rust-引用借用规则] ❤博主广交技术好友,喜欢文章的可以关注一下❤ 一、概述 Rust为确保程序在运行时不…...
【报错】解决pytorch出现RuntimeError: An attempt has been made to start a new process...
此错误是由于在 Windows 系统中使用多进程时,没有正确使用 if __name__ __main__: 语句块造成的。在 Windows 里,多进程的启动方式是 spawn,并非 fork,所以必须在主模块中使用 if __name__ __main__: 语句块来避免子进程重复执行…...
游戏引擎学习第228天
对上次的内容进行回顾,并为今天的开发环节做铺垫。 目前大部分功能我们已经完成了,唯一剩下的是一个我们知道存在但目前不会实际触发的 bug。这个 bug 的本质是在某些线程仍然访问一个已经被销毁的游戏模式(mode)之后的状态&…...
Pytorch Hook 技巧
通过 functools.partial 扩展 Pytorch Hook 机制 阅读 atom 文章源码时学习到的技巧,mark一下 通过 functools.partial,开发者无需修改原始函数或 PyTorch 的 Hook 机制,即可实现参数扩展与接口适配,这是 Python 函数式编…...
Python multiprocessing模块介绍
multiprocessing 是 Python 标准库中的一个模块,用于实现多进程并行计算,可以在多核 CPU 上显著提升程序性能,尤其适用于 CPU 密集型任务。Python 的多线程由于 GIL(全局解释器锁)限制,在进行 CPU 密集型任…...
[特殊字符] LoRA微调大模型实践:从MAC到Web的全流程指南
🚀 实践步骤概览 今天我们要在MAC上完成一个完整的AI项目闭环: 微调一个大模型 → 2. 导出模型并部署 → 3. 暴露API给web后端 → 4. 前端展示 🛠️ 微调模型准备 核心配置 框架:LLama-Factory 🏭 算法:…...
第二天 通过脚本控制物体移动和旋转
一、Unity脚本编程基础认知 1.1 为什么说脚本是Unity的灵魂? Unity引擎的核心架构采用ECS(Entity-Component-System)模式,脚本作为组件的具体实现,控制着游戏对象的所有行为。统计显示,一个中等规模的Uni…...
在SpringBoot中访问 static 与 templates 目录下的内容
目录 步骤一:添加 Thymeleaf 依赖 (处理 Templates 目录)步骤二:配置静态资源路径 (可选但建议了解)步骤三:访问不同目录下的 HTML 文件访问 static 目录下的 HTML 文件访问 templates 目录下的 HTML 文件 总结 在使用 Spring Boot 开发 Web …...
常见的 API 设计风格
在软件开发中,常见的 API 设计风格主要有以下几种,每种风格适用于不同的场景和需求: 1. RESTful API (主流) 特点: 基于 HTTP 协议,使用标准方法(GET/POST/PUT/DELETE)资源导向(UR…...
Grass.io项目现状:DePIN亮眼明星,扩张中的AI数据银行
Grass.io项目现状:DePIN亮眼明星,扩张中的AI数据银行 Grass如何在DePIN项目丛林中脱颖而出? 答案在于其"零门槛"策略——用户是基石,其他一切皆为杠杆。 Grass通过"技术+模式"双轮驱动打破行业内卷:零知识证明技术与Solana Layer2架构确保数据真实…...
ERR_PNPM_DLX_NO_BIN No binaries found in tailwindcss
场景复现: 最近在vue3项目中安装了tailwindcss,但是它默认帮我安装的版本是4XX的,导致我执行 npx tailwindcss init -p报错了。 解决方案: 更改tailwindcss的版本为3 pnpm add -D tailwindcss3再次执行生成tailwindcss的初始…...
2025“钉耙编程”中国大学生算法设计春季联赛(6)(1001,1003,1008):1007
不知道为啥,感觉后面的联赛题目有挺多出的是模拟题目(这三道题目难度依次递增) 1001 #include<bits/stdc.h> using namespace std; #define int long long const int op1e97; const int o1e34;inline void solve(){int n,a,b,c;cin>…...
Leetcode 2814. 避免淹死并到达目的地的最短时间
1.题目基本信息 1.1.题目描述 现给定一个 n * m 的索引从 0 开始的二维字符串网格 land,目前你站在为 “S” 的单元格上,你需要到达为 “D” 的单元格。在这片区域上还有另外三种类型的单元格: “.”:这些单元格是空的。 “X”…...
4.15【A】pc homework3~
5 假设read_document函数可以实现读取第m个文件,并返回该文本文档的每行数据 那么考虑双层并行结构,外层为文档级并行,内层为每个文档内的行级并行 动态分配文档任务,避免线程闲置 #include <omp.h> int total_words …...
aslist和list的区别
Arrays.asList和List的主要区别在于它们的固定长度和不可变性、与原始数组的关系、性能以及使用场景。 一、固定长度和不可变性 Arrays.asList:通过Arrays.asList方法创建的List是一个固定长度的List,其长度与原始数组相同。这意味着你不能通过添…...
Notepad++中将文档格式从Windows(CR LF)转换为Unix(LF)
在Windows中用记事本写了一个.sh的Linux运行脚本,是无法直接在Linux中执行,需要首先把文本编码格式转换为Unix的,特别是换行符这些,转换步骤如下: 1、打开文档 在Notepad中打开需要转换的文件。 2、进入文档格式转换…...
控制理论与应用Latex模版/中文Latex
报错1 ! Package CJK Error: Invalid character code. 解决方法: 用记事本打开tex文件 另存为,选择utf-8格式 ! paragraph ended before \mulearg was complete. 备注,控制理论与应用有个自己的模版内容,是通过导入方式调用…...
Linux指令和权限(10-3)
部分指令和权限 一丶指令 1.echo echo的基础作用向显示器输出。作用类似于C语言的printf,C的cout。 1.1 echo 输入内容 – 会显示输出到屏幕的下一行 echo "hello Linux"1.2 echo 输入内容>目标文件 – 向目标文件输出内容(输出重定向&…...
算法堆排序记录
【算法】排序算法之堆排序 - 知乎 应用场景:获取第n个大或者小的数 操作步骤: 1、将数组构造成堆 2、调整根节点为最大堆 ->倒序对每个根节点执行最大化 ->根节点最大化过程中如果发生交换,需要保证子节点也为最大堆(执行…...
2025年第十六届蓝桥杯省赛JavaB组真题回顾
第16届蓝桥杯省赛已经结束了,第一次参加也是坐牢了4个小时,现在还是来总结一下吧(先声明以下的解法,大家可以当作一种思路来看,解法不一定是正解,只是给大家提供一种能够正常想到的思路吧) 试题…...
qt 事件及事件过滤
在 Qt 中,事件是对象与用户或系统交互的基本方式。Qt 通过事件机制使得控件和其他对象可以响应用户的操作(如鼠标点击、键盘输入等),以及其他系统级事件(如窗口大小变化、定时器事件等)。 Qt 事件处理机制…...
RPCRT4!OsfCreateRpcAddress函数分析之AssociationBucketMutexMemory数组的填充
第一部分: 1: kd> p RPCRT4!OsfCreateRpcAddress0x28: 001b:77c0f4f5 e888e5ffff call RPCRT4!OSF_ADDRESS::OSF_ADDRESS (77c0da82) 1: kd> t RPCRT4!OSF_ADDRESS::OSF_ADDRESS: 001b:77c0da82 ?? ??? 1: kd> kc # 00 RPCRT4!…...
lvs + keepalived + dns 高可用
项目题目 实验步骤: 1.规划各自IP地址: 以lb-backup为例,修改ip地址即可 [rootlb-backup ~]# nmcli connection modify ens160 ipv4.addresses 192.168.72.106/24 ipv4.dns 223.5.5.5 ipv4.gateway 192.168.72.2 ipv4.method manual connection.autoc…...
多模态医学AI框架Pathomic Fusion,整合了组织病理学与基因组的特征
小罗碎碎念 在医学AI领域,癌症的精准诊断与预后预测一直是关键研究方向。 这篇文章提出了Pathomic Fusion这一创新框架,致力于解决现有方法的局限。 传统上,癌症诊断依赖组织学与基因组数据,但组织学分析主观易变,基因…...
安卓基础(SQLite)
基础 import sqlite3# 连接到数据库 conn sqlite3.connect(mydatabase.db) cursor conn.cursor()# 执行查询 cursor.execute("SELECT * FROM users") rows cursor.fetchall()for row in rows:print(row)# 关闭连接 conn.close() 创建一个继承自 SQLiteOpenHelpe…...
代码提错分支处理方法
如果你不小心将代码提交到了测试分支,并且希望将这些更改应用到正式分支,同时又不想引入测试分支上的其他未准备好合并的代码,可以按照以下步骤操作: 查看提交记录:首先确认你在测试分支上所做的具体提交。切换到正式…...
OpenGL学习笔记(几何着色器、实例化、抗锯齿)
目录 几何着色器爆破物体法向量可视化 实例化(偏移量存在uniform中)实例化数组(偏移量存在顶点属性中)小行星带 抗锯齿SSAA(Super Sample Anti-aliasing)MSAA(Multi-Sampling Anti-aliasing&…...
Git 学习笔记
这篇笔记记录了我在git学习中常常用到的指令,方便在未来进行查阅。此篇文章也会根据笔者的学习进度持续更新。 网站分享 Git 常用命令大全 Learn Git Branching 基础 $ git init //在当前位置配置一个git版本库 $ git add <file> //将文件添加至…...
浅析停车管理系统接入AI的提升
随着人工智能技术的快速发展,传统停车管理系统正在经历智能化变革。AI技术的引入不仅解决了停车管理中的诸多痛点,更为智慧城市建设提供了重要支撑。本文将从效率提升、体验优化、管理升级三个方面,详细分析AI技术为停车管理系统带来的显著提…...
PCL八叉树聚类
PCL八叉树聚类 主要流程完整代码部分代码解析关键元素解析std::for_each算法Lambda表达式等价 效果 主要流程 读取点云数据:从PCD文件中加载原始点云构建八叉树:对点云进行八叉树空间划分获取体素中心:提取八叉树中所有被占据的体素中…...
微服务最佳实践:全链路可用性保障体系
微服务最佳实践:全链路可用性保障体系 一、流量管控:分级限流与负载均衡 (一)动态限流策略 单机限流:采用令牌桶(允许突发流量,固定速率生成令牌)或漏桶算法(流量整形,固定速率处理请求),如Go的time/rate、Uber的ratelimit库,控制单节点流量峰值。分布式限流:通…...
智慧声防:构筑海滨浴场安全屏障的应急广播系
海滨浴场是夏季旅游的热门目的地,但潮汐变化、离岸流、突发天气、溺水事故等安全隐患时刻威胁着游客安全。传统的安全管理依赖人工瞭望和喊话,存在覆盖范围有限、响应速度慢等问题。“智慧声防”应急广播系统,通过智能化、网络化、多场景协同…...
linux-vi和文件操作
在 Linux 系统的世界里,有一个核心思想贯穿始终,那就是 “万物都是文件”。这一理念极大地简化了系统资源的管理和操作,为用户和开发者提供了统一且高效的交互方式。本文将深入探讨这一理念在 Linux 文件系统中的具体体现,从硬盘分…...
MIT6.S081 - Lab8 Locks(锁优化 | 并发安全)
本篇是 MIT6.S081 2020 操作系统课程 Lab8 的实验笔记,目标是在保证并发安全的前提下,重新设计 内存分配器 和 块缓存 这两个部分代码,提高系统并发性能。 对于有项目经验的同学来说,实验的难度不算高,重点在于找出 “…...
TMS320F28P550SJ9学习笔记15:Lin通信SCI模式结构体寄存器
今日初步认识与配置使用Lin通信SCI模式,用结构体寄存器的方式编程 文章提供完整工程下载、测试效果图 我的单片机平台是这个: LIN通信引脚: LIN通信PIE中断: 这个 PIE Vector Table 表在手册111页: 这是提到LINa的PI…...
JavaWeb 课堂笔记 —— 11 MySQL 多表设计
本系列为笔者学习JavaWeb的课堂笔记,视频资源为B站黑马程序员出品的《黑马程序员JavaWeb开发教程,实现javaweb企业开发全流程(涵盖SpringMyBatisSpringMVCSpringBoot等)》,章节分布参考视频教程,为同样学习…...
2025年最新总结安全基础(面试题)
活动发起人@小虚竹 想对你说: 这是一个以写作博客为目的的创作活动,旨在鼓励大学生博主们挖掘自己的创作潜能,展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴,那么,快来参加吧!我们一起发掘写作的魅力,书写出属于我们的故事。我们诚挚邀请…...
调试chili3d笔记 typescript预习
https://github.com/xiangechen/chili3d 用firefox拓展附加进程 打开开发者 工具,这个网页按f12没反应,手动打开 创建一个立方体可以看到运行了create.box方法,消息来自commandService.ts 位置 太久没写c了,3目都看不懂了 c没有…...
【北交互联-注册/登录安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…...
YOLOv2学习笔记
YOLOv2 背景 YOLOv2是YOLO的第二个版本,其目标是显著提高准确性,同时使其更快 相关改进: 添加了BN层——Batch Norm采用更高分辨率的网络进行分类主干网络的训练 Hi-res classifier去除了全连接层,采用卷积层进行模型的输出&a…...
2025年国企社招欧治链金再生资源入职测评笔试中智赛码平台SHL测试平台Verify认知能力测试
1、欧治链金政治素质测试(中智赛码平台,电脑端作答) 10个单选题、5个多选题、1个问答题 2、欧治链金综合素质测试(SHL测试平台Verify认知能力测试,电脑端作答) 3、欧治链金职业性格测试(中智职…...