Bert的使用
一、Data.py
# data负责产生两个dataloader
from torch.utils.data import DataLoader, Dataset
from sklearn.model_selection import train_test_split #给X,Y 和分割比例, 分割出来一个训练集和验证机的X, Y
import torchdef read_file(path):data = []label = []with open(path, "r", encoding="utf-8") as f:for i, line in enumerate(f):if i == 0:continueif i > 200 and i< 7500:continueline = line.strip("\n")line = line.split(",", 1) #把这句话,按照,分割, 1表示分割次数data.append(line[1])label.append(line[0])print("读了%d的数据"%len(data))return data, label# file = "../jiudian.txt"
# read_file(file)
class jdDataset(Dataset):def __init__(self, data, label):self.X = dataself.Y = torch.LongTensor([int(i) for i in label])def __getitem__(self, item):return self.X[item], self.Y[item]def __len__(self):return len(self.Y)def get_data_loader(path, batchsize, val_size=0.2): #读入数据,分割数据。data, label = read_file(path)train_x, val_x, train_y, val_y = train_test_split(data, label, test_size=val_size, shuffle=True, stratify=label)train_set = jdDataset(train_x, train_y)val_set = jdDataset(val_x, val_y)train_loader = DataLoader(train_set, batchsize, shuffle=True)val_loader = DataLoader(val_set, batchsize, shuffle=True)return train_loader, val_loaderif __name__ == "__main__":get_data_loader("../jiudian.txt", 2)
代码逐行解释
导入必要的库
from torch.utils.data import DataLoader, Dataset
from sklearn.model_selection import train_test_split # 给X, Y 和分割比例, 分割出来一个训练集和验证集的X, Y
import torch
DataLoader
和Dataset
:来自torch.utils.data
,用于创建数据加载器和自定义数据集。train_test_split
:来自sklearn.model_selection
,用于将数据集划分为训练集和验证集。torch
:PyTorch 的核心库,用于深度学习模型的构建和训练。
定义读取文件的函数
def read_file(path):data = []label = []with open(path, "r", encoding="utf-8") as f:for i, line in enumerate(f):if i == 0:continueif i > 200 and i < 7500:continueline = line.strip("\n")line = line.split(",", 1) # 把这句话,按照逗号分割, 1表示分割次数data.append(line[1])label.append(line[0])print("读了%d的数据" % len(data))return data, label
read_file
函数:- 打开指定路径的文件并读取每一行。
- 跳过第一行(假设是表头)。
- 忽略第201到7499行的数据。
- 使用
strip("\n")
去除每行末尾的换行符。 - 使用
split(",", 1)
按照第一个逗号分割每行数据,生成包含两个元素的列表。 - 将分割后的第二个元素(即文本数据)添加到
data
列表中,第一个元素(即标签)添加到label
列表中。 - 打印读取的数据条数,并返回
data
和label
。
自定义数据集类
class jdDataset(Dataset):def __init__(self, data, label):self.X = dataself.Y = torch.LongTensor([int(i) for i in label])def __getitem__(self, item):return self.X[item], self.Y[item]def __len__(self):return len(self.Y)
jdDataset
类:- 继承自
torch.utils.data.Dataset
。 - 在
__init__
方法中初始化self.X
和self.Y
,其中self.Y
是将标签转换为torch.LongTensor
类型。 __getitem__
方法用于根据索引获取数据项,返回对应的文本数据和标签。__len__
方法返回数据集的长度。
- 继承自
生成数据加载器
def get_data_loader(path, batchsize, val_size=0.2): # 读入数据,分割数据data, label = read_file(path)train_x, val_x, train_y, val_y = train_test_split(data, label, test_size=val_size, shuffle=True, stratify=label)train_set = jdDataset(train_x, train_y)val_set = jdDataset(val_x, val_y)train_loader = DataLoader(train_set, batchsize, shuffle=True)val_loader = DataLoader(val_set, batchsize, shuffle=True)return train_loader, val_loader
get_data_loader
函数:- 调用
read_file
函数读取数据并获得data
和label
。 - 使用
train_test_split
函数将数据集划分为训练集和验证集。参数包括:test_size
: 验证集的比例,默认为0.2。shuffle
: 是否在分割前打乱数据,默认为True
。stratify
: 根据标签进行分层抽样,确保训练集和验证集中的标签分布一致。
- 创建
jdDataset
实例train_set
和val_set
。 - 使用
DataLoader
创建训练集和验证集的数据加载器。训练集的数据加载器设置为shuffle=True
,以便每次迭代时打乱数据顺序;验证集的数据加载器也设置为shuffle=True
,但在实际应用中通常不需要打乱验证集的数据顺序。 - 返回训练集和验证集的数据加载器。
- 调用
主程序入口
if __name__ == "__main__":get_data_loader("../jiudian.txt", 2)
- 主程序入口:
- 当脚本作为主程序运行时,调用
get_data_loader
函数读取路径为"../jiudian.txt"
的文件,并生成批量大小为2的数据加载器。
- 当脚本作为主程序运行时,调用
详细步骤说明
-
读取文件:
read_file
函数负责从指定路径读取文件内容,并跳过某些特定行(如第一行和第201到7499行),然后将剩余的有效行按逗号分割为标签和文本数据,分别存储在data
和label
列表中。
-
创建自定义数据集:
jdDataset
类继承自Dataset
,实现了__getitem__
和__len__
方法。它将原始数据和标签封装成一个可被DataLoader
使用的对象。
-
数据集划分:
get_data_loader
函数使用train_test_split
将数据集划分为训练集和验证集,并创建相应的jdDataset
实例。
-
创建数据加载器:
- 使用
DataLoader
创建训练集和验证集的数据加载器。训练集的数据加载器设置了shuffle=True
,以便每次迭代时打乱数据顺序;验证集的数据加载器也设置了shuffle=True
,但通常不需要打乱验证集的数据顺序。
- 使用
示例输出
假设 "../jiudian.txt"
文件的内容如下:
id,label,text
1,0,这是一家不错的酒店。
2,1,房间太小了。
...
执行 get_data_loader("../jiudian.txt", 2)
后,程序将读取文件内容,忽略第一行和第201到7499行的数据,然后将剩余的数据按逗号分割为标签和文本数据,并将其划分为训练集和验证集,最后创建对应的数据加载器。
总结
这段代码的主要功能是从文件中读取数据,将其划分为训练集和验证集,并创建相应的数据加载器。通过这种方式,可以方便地将数据提供给深度学习模型进行训练和验证。
二、Model.py
import torch
import torch.nn as nn
from transformers import BertModel, BertTokenizer, BertConfigclass myBertModel(nn.Module):def __init__(self, bert_path, num_class, device):super(myBertModel, self).__init__()self.bert = BertModel.from_pretrained(bert_path)# config = BertConfig.from_pretrained(bert_path)# self.bert = BertModel(config)self.device = deviceself.cls_head = nn.Linear(768, num_class)self.tokenizer = BertTokenizer.from_pretrained(bert_path)def forward(self, text):input = self.tokenizer(text, return_tensors="pt", truncation=True, padding="max_length", max_length=128)input_ids = input["input_ids"].to(self.device)token_type_ids = input['token_type_ids'].to(self.device)attention_mask = input['attention_mask'].to(self.device)sequence_out, pooler_out = self.bert(input_ids=input_ids,token_type_ids=token_type_ids,attention_mask=attention_mask,return_dict=False) #return_dictpred = self.cls_head(pooler_out)return predif __name__ == "__main__":model = myBertModel("../bert-base-chinese", 2)pred = model("今天天气真好")
代码逐行解释
导入必要的库
import torch
import torch.nn as nn
from transformers import BertModel, BertTokenizer, BertConfig
torch
和torch.nn
:PyTorch的核心库,用于构建神经网络。BertModel
,BertTokenizer
,BertConfig
:来自transformers
库,分别用于加载预训练的BERT模型、BERT分词器和BERT配置。
定义自定义BERT模型类
class myBertModel(nn.Module):def __init__(self, bert_path, num_class, device):super(myBertModel, self).__init__()self.bert = BertModel.from_pretrained(bert_path)self.device = deviceself.cls_head = nn.Linear(768, num_class)self.tokenizer = BertTokenizer.from_pretrained(bert_path)
__init__
方法:- 加载预训练的BERT模型。
- 初始化设备(
device
),可以是CPU或GPU。 - 定义分类头(
cls_head
),将BERT输出的768维向量映射到指定的类别数。 - 加载BERT的分词器(
tokenizer
),用于将输入文本转换为BERT模型所需的输入格式。
def forward(self, text):input = self.tokenizer(text, return_tensors="pt", truncation=True, padding="max_length", max_length=128)input_ids = input["input_ids"].to(self.device)token_type_ids = input['token_type_ids'].to(self.device)attention_mask = input['attention_mask'].to(self.device)sequence_out, pooler_out = self.bert(input_ids=input_ids,token_type_ids=token_type_ids,attention_mask=attention_mask,return_dict=False) #return_dictpred = self.cls_head(pooler_out)return pred
forward
方法:- 使用
tokenizer
将输入文本转换为BERT模型所需的输入张量(input_ids
,token_type_ids
,attention_mask
)。 - 将这些张量移动到指定的设备(CPU或GPU)上。
- 调用
self.bert
进行前向传播,得到序列输出(sequence_out
)和池化输出(pooler_out
)。 - 使用分类头(
cls_head
)对池化输出进行线性变换,得到最终的预测结果(pred
)。
- 使用
主程序入口
if __name__ == "__main__":model = myBertModel("../bert-base-chinese", 2, "cpu")pred = model("今天天气真好")print(pred)
- 主程序入口:
- 创建
myBertModel
实例,指定预训练BERT模型路径、类别数和设备。 - 调用模型进行前向传播,传入一条测试文本
"今天天气真好"
,并打印预测结果。
- 创建
三、train.py
import torch
import time
import matplotlib.pyplot as plt
import numpy as np
from tqdm import tqdmdef train_val(para):########################################################model = para['model']train_loader =para['train_loader']val_loader = para['val_loader']scheduler = para['scheduler']optimizer = para['optimizer']loss = para['loss']epoch = para['epoch']device = para['device']save_path = para['save_path']max_acc = para['max_acc']val_epoch = para['val_epoch']#################################################plt_train_loss = []plt_train_acc = []plt_val_loss = []plt_val_acc = []val_rel = []for i in range(epoch):start_time = time.time()model.train()train_loss = 0.0train_acc = 0.0val_acc = 0.0val_loss = 0.0for batch in tqdm(train_loader):model.zero_grad()text, labels = batch[0], batch[1].to(device)pred = model(text)bat_loss = loss(pred, labels)bat_loss.backward()optimizer.step()scheduler.step() #scheduler 调整学习率optimizer.zero_grad()torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) #梯度裁切train_loss += bat_loss.item() #.detach 表示去掉梯度train_acc += np.sum(np.argmax(pred.cpu().data.numpy(),axis=1)== labels.cpu().numpy())plt_train_loss . append(train_loss/train_loader.dataset.__len__())plt_train_acc.append(train_acc/train_loader.dataset.__len__())if i % val_epoch == 0:model.eval()with torch.no_grad():for batch in tqdm(val_loader):val_text, val_labels = batch[0], batch[1].to(device)val_pred = model(val_text)val_bat_loss = loss(val_pred, val_labels)val_loss += val_bat_loss.cpu().item()val_acc += np.sum(np.argmax(val_pred.cpu().data.numpy(), axis=1) == val_labels.cpu().numpy())val_rel.append(val_pred)if val_acc > max_acc:torch.save(model, save_path+str(epoch)+"ckpt")max_acc = val_accplt_val_loss.append(val_loss/val_loader.dataset.__len__())plt_val_acc.append(val_acc/val_loader.dataset.__len__())print('[%03d/%03d] %2.2f sec(s) TrainAcc : %3.6f TrainLoss : %3.6f | valAcc: %3.6f valLoss: %3.6f ' % \(i, epoch, time.time()-start_time, plt_train_acc[-1], plt_train_loss[-1], plt_val_acc[-1], plt_val_loss[-1]))if i % 50 == 0:torch.save(model, save_path+'-epoch:'+str(i)+ '-%.2f'%plt_val_acc[-1])else:plt_val_loss.append(plt_val_loss[-1])plt_val_acc.append(plt_val_acc[-1])print('[%03d/%03d] %2.2f sec(s) TrainAcc : %3.6f TrainLoss : %3.6f ' % \(i, epoch, time.time()-start_time, plt_train_acc[-1], plt_train_loss[-1]))plt.plot(plt_train_loss)plt.plot(plt_val_loss)plt.title('loss')plt.legend(['train', 'val'])plt.show()plt.plot(plt_train_acc)plt.plot(plt_val_acc)plt.title('Accuracy')plt.legend(['train', 'val'])plt.savefig('acc.png')plt.show()
这段代码实现了一个完整的训练和验证循环,用于训练一个深度学习模型。它包括训练过程中的损失和准确率记录、模型保存、学习率调整以及结果的可视化。
代码逐行解释
导入必要的库
import torch
import time
import matplotlib.pyplot as plt
import numpy as np
from tqdm import tqdm
torch
:PyTorch的核心库,用于构建和训练神经网络。time
:用于记录训练时间。matplotlib.pyplot
:用于绘制训练和验证的损失和准确率曲线。numpy
:用于数值计算,特别是处理预测结果和标签的比较。tqdm
:用于显示进度条,方便监控训练过程。
定义训练和验证函数
def train_val(para):
train_val
函数:接受一个包含所有必要参数的字典para
,并在其中进行训练和验证。
参数解析
model = para['model']train_loader = para['train_loader']val_loader = para['val_loader']scheduler = para['scheduler']optimizer = para['optimizer']loss = para['loss']epoch = para['epoch']device = para['device']save_path = para['save_path']max_acc = para['max_acc']val_epoch = para['val_epoch']
model
:要训练的模型。train_loader
和val_loader
:训练集和验证集的数据加载器。scheduler
:学习率调度器。optimizer
:优化器(如Adam、SGD等)。loss
:损失函数(如交叉熵损失)。epoch
:训练的总轮数。device
:设备(CPU或GPU)。save_path
:模型保存路径。max_acc
:当前最高的验证准确率。val_epoch
:每隔多少个epoch进行一次验证。
初始化记录变量
plt_train_loss = []plt_train_acc = []plt_val_loss = []plt_val_acc = []val_rel = []
plt_train_loss
和plt_train_acc
:记录每轮训练的损失和准确率。plt_val_loss
和plt_val_acc
:记录每轮验证的损失和准确率。val_rel
:用于存储验证集的预测结果(未在后续代码中使用)。
训练和验证循环
for i in range(epoch):start_time = time.time()model.train()train_loss = 0.0train_acc = 0.0val_acc = 0.0val_loss = 0.0
- 初始化每轮的损失和准确率:在每个epoch开始时,重置这些变量。
训练阶段
for batch in tqdm(train_loader):model.zero_grad()text, labels = batch[0], batch[1].to(device)pred = model(text)bat_loss = loss(pred, labels)bat_loss.backward()optimizer.step()scheduler.step() # 调整学习率optimizer.zero_grad()torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) # 梯度裁切train_loss += bat_loss.item()train_acc += np.sum(np.argmax(pred.cpu().data.numpy(), axis=1) == labels.cpu().numpy())
tqdm(train_loader)
:显示训练进度条。model.zero_grad()
:清空之前的梯度。text, labels = batch[0], batch[1].to(device)
:将数据和标签移动到指定设备。pred = model(text)
:前向传播得到预测结果。bat_loss = loss(pred, labels)
:计算损失。bat_loss.backward()
:反向传播计算梯度。optimizer.step()
:更新模型参数。scheduler.step()
:调整学习率(根据调度器)。optimizer.zero_grad()
:清空梯度(通常在zero_grad()
之后不需要再次调用)。torch.nn.utils.clip_grad_norm_
:梯度裁切,防止梯度过大导致训练不稳定。train_loss += bat_loss.item()
:累加当前批次的损失。train_acc += np.sum(np.argmax(pred.cpu().data.numpy(), axis=1) == labels.cpu().numpy())
:计算当前批次的准确率。
计算平均损失和准确率并记录
plt_train_loss.append(train_loss / len(train_loader.dataset))plt_train_acc.append(train_acc / len(train_loader.dataset))
plt_train_loss.append(...)
:记录每轮训练的平均损失。plt_train_acc.append(...)
:记录每轮训练的平均准确率。
验证阶段
if i % val_epoch == 0:model.eval()with torch.no_grad():for batch in tqdm(val_loader):val_text, val_labels = batch[0], batch[1].to(device)val_pred = model(val_text)val_bat_loss = loss(val_pred, val_labels)val_loss += val_bat_loss.cpu().item()val_acc += np.sum(np.argmax(val_pred.cpu().data.numpy(), axis=1) == val_labels.cpu().numpy())val_rel.append(val_pred)if val_acc > max_acc:torch.save(model, save_path + str(epoch) + "ckpt")max_acc = val_accplt_val_loss.append(val_loss / len(val_loader.dataset))plt_val_acc.append(val_acc / len(val_loader.dataset))print('[%03d/%03d] %2.2f sec(s) TrainAcc : %3.6f TrainLoss : %3.6f | valAcc: %3.6f valLoss: %3.6f' % \(i, epoch, time.time() - start_time, plt_train_acc[-1], plt_train_loss[-1], plt_val_acc[-1], plt_val_loss[-1]))if i % 50 == 0:torch.save(model, save_path + '-epoch:' + str(i) + '-%.2f' % plt_val_acc[-1])else:plt_val_loss.append(plt_val_loss[-1])plt_val_acc.append(plt_val_acc[-1])print('[%03d/%03d] %2.2f sec(s) TrainAcc : %3.6f TrainLoss : %3.6f' % \(i, epoch, time.time() - start_time, plt_train_acc[-1], plt_train_loss[-1]))
if i % val_epoch == 0:
:每隔val_epoch
轮进行一次验证。model.eval()
:设置模型为评估模式,关闭dropout等训练特定操作。with torch.no_grad():
:禁用梯度计算,节省内存并加速推理。val_text, val_labels = batch[0], batch[1].to(device)
:将验证数据和标签移动到指定设备。val_pred = model(val_text)
:前向传播得到验证预测结果。val_bat_loss = loss(val_pred, val_labels)
:计算验证损失。val_loss += val_bat_loss.cpu().item()
:累加验证损失。val_acc += np.sum(np.argmax(val_pred.cpu().data.numpy(), axis=1) == val_labels.cpu().numpy())
:计算验证准确率。if val_acc > max_acc:
:如果当前验证准确率超过历史最高值,则保存模型。plt_val_loss.append(...)
和plt_val_acc.append(...)
:记录每轮验证的平均损失和准确率。print(...)
:打印当前轮次的训练和验证信息。if i % 50 == 0:
:每隔50轮保存一次模型。
绘制训练和验证曲线
plt.plot(plt_train_loss)plt.plot(plt_val_loss)plt.title('loss')plt.legend(['train', 'val'])plt.show()plt.plot(plt_train_acc)plt.plot(plt_val_acc)plt.title('Accuracy')plt.legend(['train', 'val'])plt.savefig('acc.png')plt.show()
plt.plot(...)
:绘制训练和验证的损失和准确率曲线。plt.title(...)
:设置图表标题。plt.legend(...)
:添加图例。plt.show()
:显示图表。plt.savefig('acc.png')
:保存准确率图表为PNG文件。
相关文章:
Bert的使用
一、Data.py # data负责产生两个dataloader from torch.utils.data import DataLoader, Dataset from sklearn.model_selection import train_test_split #给X,Y 和分割比例, 分割出来一个训练集和验证机的X, Y import torchdef read_file(path):data []label …...
Unity使用UGUI制作无限滑动列表
原理参照上一篇使用NGUI的制作无限滑动列表的文章 Unity 使用NGUI制作无限滑动列表_unity 滑动列表很多物体-CSDN博客 准备工作: 新建一个空物体命名为LoopList,并调整其大小, 并增加Scroll Rect组件(用于滑动)、Re…...
ThinkPHP6用户登录系统的全过程
ThinkPHP6用户登录系统的全过程涉及请求处理、数据传输、路由分发、控制器逻辑、模型验证及中间件协作等多个模块的交互。详细的过程解析如下: 1. 前端请求与路由分发 前端发起请求:用户在前端页面(如Vue组件或HTML表单)输入用户…...
C++全栈聊天项目(2) 单例模式封装Http管理者
完善注册类界面 先在注册类构造函数里添加lineEdit的模式为密码模式 ui->lineEdit_Passwd->setEchoMode(QLineEdit::Password); ui->lineEdit_Confirm->setEchoMode(QLineEdit::Password);我们在注册界面的ui里添加一个widget,widget内部包含一个tip居…...
【鸿蒙开发】OpenHarmony调测工具hdc使用教程(设备开发者)
00. 目录 文章目录 00. 目录01. OpenHarmony概述02. hdc简介03. hdc获取04. option相关的命令05. 查询设备列表的命令06. 服务进程相关命令07. 网络相关的命令08. 文件相关的命令09. 应用相关的命令10. 调试相关的命令11. 常见问题12. 附录 01. OpenHarmony概述 OpenHarmony是…...
ORACLE EBS数据库RELINK方式搭建克隆环境
ORACLE EBS系统的数据库,一般都安装了很多特定功能的小补丁来解决特定的BUG;因此对于已经安装好的系统,想要克隆一套测试环境、搭建一个新的备机做测试等,如果按照生产环境标准,则需要安装大量补丁,带来很大…...
MySQL regexp 命令
REGEXP命令是一种用于进行正则表达式匹配的运算符,允许在查询中使用正则表达式来匹配字符串模式1。 基本语法 基本的语法结构如下: SELECT * FROM table_name WHERE column_name REGEXP pattern; 这里,pattern是你要匹配的正则表达式模…...
前端实习到工作的经历
看了很多人的程序员生涯之路,我突然意识到我也该记录一些东西,因此有感而发。 我是一个24届毕业生,大三下就开始找前端实习,当时学校不让走,我们都是先面着然后准备放假就去。当时周围小伙伴都找好了,考完…...
Vue3——Fragment
文章目录 一、Fragment的核心意义1. 解决Vue2的单根限制问题2. 减少不必要的 DOM 嵌套3. 语义化和结构化 二、Fragment 的实现原理三、Fragment 使用方式1. 基本用法2. 结合条件渲染3. 动态组件 四、实际应用场景1. 列表/表格组件2. 布局组件3. 语义化标签 五、注意事项1. 属性…...
Linux_16进程地址空间
CPU内的寄存器只有一套,但是CPU内寄存器的数据可能会有多份! 一、程序地址空间 下面这个图对应的是内存吗?(实际上是虚拟的进程地址空间) 32位机器内存最大为多少? 32位操作系统的地址总线为32位&#x…...
职坐标机器学习编程实战:调试优化与自动化测试精要
内容概要 在机器学习编程实践中,代码调试优化与自动化测试工具的应用是构建高可靠性系统的核心环节。本书聚焦从数据预处理到模型部署的全流程,通过特征工程优化、训练过程监控及持续集成方案的设计,系统化解决算法工程化中的典型问题。在特…...
git文件过大导致gitea仓库镜像推送失败问题解决(push failed: context deadline exceeded)
问题描述: 今天发现gitea仓库推送到某个镜像仓库的操作几个月前已经报错终止推送了,报错如下: 首先翻译报错提示可知是因为git仓库大小超过1G限制。检查本地.git文件,发现.git文件大小已达到1.13G。确定是.git文件过大导致&…...
llvm数据流分析
llvm数据流分析 1.数据流分析2.LLVM实现2.1.常量传播2.2.活跃性分析 相关参考文档:DataFlowAnalysisIntro、ustc编译原理课程、南大程序分析课程1、南大程序分析课程2。 1.数据流分析 数据流分析在编译优化等程序分析任务上都有重要应用。通常数据流分析可被抽象为…...
Vite为什么选用Rollup打包?
Vite 在生产阶段使用 Rollup 打包,但这不是唯一选择。它的设计背后有明确的权衡和考量,同时开发者也可以选择其他替代方案。 一、为什么 Vite 默认使用 Rollup? 1. Rollup 的核心优势 • Tree-shaking:Rollup 的静态分析能力极强&…...
Docker 入门与实战指南
Docker 入门与实战指南 一、Docker 简介 Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖打包成一个可移植的容器。容器可以在任何安装了 Docker 的环境中运行,确保应用的一致性和可移植性。 1.1 为什么使用 Docker? 环境一…...
C# 常用数据类型
C# 数据类型分为 值类型、引用类型 和 特殊类型,以下是详细分类及对应范围/说明: 一、值类型(Value Types) 值类型直接存储数据,分配在栈内存中,默认不可为 null。 简单类型 整数类型…...
深入解读 JavaScript 中 `this` 的指向机制:覆盖所有场景与底层原理
this 是 JavaScript 中最容易引发困惑的核心概念之一,它的指向在不同场景下呈现截然不同的行为。本文将系统性地解析 this 的所有使用场景,结合代码示例和底层原理,帮助你彻底掌握其运行机制。 一、全局环境下的 this 1. 浏览器环境 在浏览器…...
无人机全景应用解析与技术演进趋势
无人机全景应用解析与技术演进趋势 ——从立体安防到万物互联的空中革命 一、现有应用场景全景解析 (一)公共安全领域 1. 立体安防体系 空中哨兵:搭载 77 GHz 77\text{GHz} 77GHz毫米波雷达(探测距离 5 km 5\text{km} 5km&…...
手写简易Tomcat核心实现:深入理解Servlet容器原理
目录 一、Tomcat概况 1. tomcat全局图 2.项目结构概览 二、实现步骤详解 2.1 基础工具包(com.qcby.util) 2.1.1 ResponseUtil:HTTP响应生成工具 2.1.2 SearchClassUtil:类扫描工具 2.1.3 WebServlet:自定义注解…...
【音视频】ffmpeg命令提取像素格式
1、提取YUV数据 提取yuv数据,并保持分辨率与原视频一致 使用-pix_fmt或-pixel_format指定yuv格式提取数据,并保持原来的分辨率 ffmpeg -i music.mp4 -t "01:00" -pixel_format yuv420p music.yuv提取成功后,可以使用ffplay指定y…...
深度剖析Redis:双写一致性问题及解决方案全景解析
在高并发场景下,缓存与数据库的双写一致性是每个开发者必须直面的核心挑战。本文通过5大解决方案,带你彻底攻克这一技术难关! 一、问题全景图:当缓存遇到数据库 1.1 典型问题场景 // 典型问题代码示例 public void updateProduc…...
Redis----大key、热key解决方案、脑裂问题
文章中相关知识点在往期已经更新过了,如果有友友不理解可翻看往期内容 出现脑裂问题怎么保证集群还是高可用的 什么是脑裂问题 脑裂说的就是当我们的主节点没有挂,但是因为网络延迟较大,然后和主节点相连的哨兵通信较差,之后主…...
Android 调用c++报错 exception of type std::bad_alloc: std::bad_alloc
一、报错信息 terminating with uncaught exception of type std::bad_alloc: std::bad_alloc 查了那部分报错c++代码 szGridSize因为文件太大,初始化溢出了 pEGM->pData = new float[szGridSize]; 解决办法 直接抛出异常,文件太大就失败吧 最后还增加一个日志输出,给…...
【从零开始学习计算机科学】操作系统(五)处理器调度
【从零开始学习计算机科学】操作系统(五)处理器调度 处理器调度一些简单的短程调度算法的思路先来先服务(First-Come-First-Served,FCFS)优先级调度及其变种最短作业优先调度算法(SJF)--非抢占式最短作业优先调度算法(SJF)--抢占式最高响应比优先调度算法轮转调度算法…...
LeetCode1871 跳跃游戏VII
LeetCode 跳跃游戏 IV:二进制字符串的跳跃问题 题目描述 给定一个下标从 0 开始的二进制字符串 s 和两个整数 minJump 和 maxJump。初始时,你位于下标 0 处(保证该位置为 0)。你需要判断是否能到达字符串的最后一个位置…...
ResNet50深度解析:原理、结构与PyTorch实现
ResNet50深度解析:原理、结构与PyTorch实现 1. 引言 ResNet(残差网络)是深度学习领域的一项重大突破,它巧妙解决了深层神经网络训练中的梯度消失/爆炸问题,使得构建和训练更深的网络成为可能。作为计算机视觉领域的里…...
MATLAB 控制系统设计与仿真 - 24
PID 控制器分析- 控制器的形式 连续控制器的结构: 为滤波时间常数,这类PID控制器在MATLAB系统控制工具箱称为并联PID控制器,可由MATLAB提供的pid函数直接输入,格式为: 其他类型的控制器也可以由该函数直接输入&#x…...
数字IC后端设计实现教程 |Innovus ICC2 Routing Pin Access Setting设置方法
默认情况下routing 引擎可以在标准单元可以打孔的任何地方(via region)打孔,甚至工具还会先拉出一块metal,然后再打孔过渡到高层。 随之工艺节点越做越小,标准单元内部的结构也越来越复杂。此时如果还沿用传统工艺的走…...
mysql经典试题共34题
1、准备数据 -- drop drop table if exists dept; drop table if exists emp; drop table if exists salgrade;-- CREATE CREATE TABLE dept (deptno int NOT NULL COMMENT 部门编号,dname varchar(14) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMM…...
网络编程-----服务器(多路复用IO 和 TCP并发模型)
一、单循环服务器模型 1. 核心特征 while(1){newfd accept();recv();close(newfd);}2. 典型应用场景 HTTP短连接服务(早期Apache)CGI快速处理简单测试服务器 3. 综合代码 #include <stdio.h> #include <sys/types.h> /* See NO…...
GitHub 项目版本管理与 Release 发布流程记录
GitHub 项目版本管理与 Release 发布流程记录 1. 项目环境设置 1.1 打开 VS Code 并进入项目目录 E:\adb\Do>code .1.2 配置 Git 用户信息 E:\adb\Do>git config --global user.name "n" E:\adb\Do>git config --global user.email "**gmail.com&q…...
GStreamer —— 2.15、Windows下Qt加载GStreamer库后运行 - “播放教程 1:Playbin 使用“(附:完整源码)
运行效果 介绍 我们已经使用了这个元素,它能够构建一个完整的播放管道,而无需做太多工作。 本教程介绍如何进一步自定义,以防其默认值不适合我们的特定需求。将学习: • 如何确定文件包含多少个流,以及如何切换 其中。…...
Python+DeepSeek:开启AI编程新次元——从自动化到智能创造的实战指南
文章核心价值 技术热点:结合全球最流行的编程语言与国产顶尖AI模型实用场景:覆盖代码开发/数据分析/办公自动化等高频需求流量密码:揭秘大模型在编程中的创造性应用目录结构 环境搭建:5分钟快速接入DeepSeek场景一:AI辅助代码开发(智能补全+调试)场景二:数据分析超级助…...
使用OpenCV和MediaPipe库——驼背检测(姿态监控)
目录 驼背检测的运用 1. 驾驶姿态与疲劳关联分析 2. 行业应用案例 1. 教育场景痛点分析 2. 智能教室系统架构 代码实现思路 1. 初始化与配置 2. MediaPipe和摄像头设置 3. 主循环 4. 资源释放 RGB与BGR的区别 一、本质区别 二、OpenCV的特殊性 内存结构示意图&…...
maven的项目构建
常用构建命令 命令说明mvn clean清理编译结果(删掉target目录)mvn compile编译核心代码,生成target目录mvn test-compile编译测试代码,生成target目录mvn test执行测试方法mvn package打包,生成jar或war文件mvn insta…...
光电感知赋能智能未来 灵途科技护航新质生产力发展
2024年《政府工作报告》将大力推进现代化产业体系建设,加快发展新质生产力作为首要工作任务。这是“新质生产力”首次出现在《政府工作报告》中。 发展新质生产力具体包括 新兴产业 :推动商业航天、低空经济等新兴产业实现安全健康发展。 未来产业 &a…...
文件上传靶场(10--20)
目录 实验环境: 具体内容实现: 第十关(双写绕过): 第十一关:(%00截断,此漏洞在5.2版本中) 正确用法 错误用法 思路: 操作过程: 第十二关…...
deepseek在pycharm中的配置和简单应用
对于最常用的调试python脚本开发环境pycharm,如何接入deepseek是我们窥探ai代码编写的第一步,熟悉起来总没坏处。 1、官网安装pycharm社区版(免费),如果需要安装专业版,需要另外找破解码。 2、安装Ollama…...
Linux 生成静态库
文章目录 前提小知识生成和使用.a库操作步骤 在应用程序中,有一些公共的代码需要反复使用的,可以把这些代码制作成“库文件”;在链接的步骤中,可以让链接器在“库文件”提取到我们需要使用到的代码,复制到生成的可执行…...
yolo-TensorRT相关代码逐步详解-pt转engine
基于TensorRT 的推论运行速度会比仅使用CPU 快40倍,提供精度INT8 和FP16 优化,支援TensorFlow、Caffe、Mxnet、Pytorch 等深度学习框架,其中Mxnet、Pytorch 需先转换为ONNX 格式。 TensorRT的构建流程大致分为几个步骤:创建构建器和网络、解析模型、配置构建参数、构建引擎…...
简记_ MCU管脚的防静电处理
一、分析(一) 接口处的信号要先过 ESD/TVS 管,然后拉到被保护器件; 建个 ESD 电路发生器的模型,代入到我们的电路中去分析: 继电器实现这两个“开关”,并且还会感应出一些额外的RLC寄生。 ES…...
C语言实现算法(二)
以下是 “10个不重复的C语言经典算法案例“,包含可运行代码、开发环境配置及系统要求。所有代码基于标准C语法,已在GCC 9.3.0环境下测试通过。 开发环境配置 编译器:GCC(推荐) Windows:安装 MinGW 或 Visual Studio Linux:sudo apt-get install gcc macOS:通过Xcode Co…...
transformer模型介绍——大语言模型 LLMBook 学习(二)
1. transformer模型 1.1 注意力机制 **注意力机制(Attention Mechanism)**在人工智能中的应用,实际上是对人类认知系统中的注意力机制的一种模拟。它主要模仿了人类在处理信息时的选择性注意(Selective Attention)&a…...
K8s 1.27.1 实战系列(十一)ConfigMap
ConfigMap 是 Kubernetes 中管理非敏感配置的核心资源,通过解耦应用与配置实现灵活性和可维护性。 一、ConfigMap 的核心功能及优势 1、配置解耦 将配置文件(如数据库地址、日志级别)与容器镜像分离,支持动态更新而无需重建镜像。 2、多形式注入 环境变量:将键值…...
下降路径最⼩和(medium)
题目描述: 给你一个 n x n 的 方形 整数数组 matrix ,请你找出并返回通过 matrix 的下降路径 的 最小和 。 下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(…...
数据结构--【顺序表与链表】笔记
顺序表 template <class T> class arrList :public List<T> //表示 arrList 类以公有继承的方式继承自 List<T> 类 //公有继承意味着 List<T> 类的公共成员在 arrList 类中仍然是公共成员,受保护成员在 arrList 类中仍然是受保护成员。 { …...
使用AI一步一步实现若依前端(9)
功能9:退出登录功能 功能8:页面权限控制 功能7:路由全局前置守卫 功能6:动态添加路由记录 功能5:侧边栏菜单动态显示 功能4:首页使用Layout布局 功能3:点击登录按钮实现页面跳转 功能2…...
Excel两列和依次相减
Excel实现左列依次行数的和减去右列依次行数的和: 举例:结余SUM(预付款)-SUM(开支) 公式:SUM($B$2:B2)-SUM($C$2:C2)...
智能合约中权限管理不当
权限管理不当 : 权限管理不当是智能合约中常见的安全问题之一,尤其是在管理员或特定账户被过度赋予权限的情况下。如果合约中的关键功能,如转移资产、修改合约状态或升级合约逻辑,可以被未经授权的实体随意操作,这将构…...
Java糊涂包(Hutool)的安装教程并进行网络爬虫
Hutool的使用教程 1:在官网下载jar模块文件 Central Repository: cn/hutool/hutool-all/5.8.26https://repo1.maven.org/maven2/cn/hutool/hutool-all/5.8.26/ 下载后缀只用jar的文件 2:复制并到idea当中,右键这个模块点击增加到库 3&…...