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

1-3.文本数据建模流程范例

文章最前: 我是Octopus,这个名字来源于我的中文名–章鱼;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github
;这博客是记录我学习的点点滴滴,如果您对 Python、Java、AI、算法有兴趣,可以关注我的动态,一起学习,共同进步。

import os#mac系统上pytorch和matplotlib在jupyter中同时跑需要更改环境变量
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE" 
!pip install gensim 
!pip install torchkeras
import torch 
import gensim
import torchkeras 
print("torch.__version__ = ", torch.__version__)
print("gensim.__version__ = ", gensim.__version__) 
print("torchkeras.__version__ = ", torchkeras.__version__) 
torch.__version__ =  2.0.1
gensim.__version__ =  4.3.1
torchkeras.__version__ =  3.9.3

公众号 算法美食屋 回复关键词:pytorch, 获取本项目源码和所用数据集百度云盘下载链接。


一,准备数据

imdb数据集的目标是根据电影评论的文本内容预测评论的情感标签。

训练集有20000条电影评论文本,测试集有5000条电影评论文本,其中正面评论和负面评论都各占一半。

文本数据预处理较为繁琐,包括文本切词,构建词典,编码转换,序列填充,构建数据管道等等。

此处使用gensim中的词典工具并自定义Dataset。

下面进行演示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

import numpy as np 
import pandas as pd 
import torch MAX_LEN = 200           #每个样本保留200个词的长度
BATCH_SIZE = 20 dftrain = pd.read_csv("./eat_pytorch_datasets/imdb/train.tsv",sep="\t",header = None,names = ["label","text"])
dfval = pd.read_csv("./eat_pytorch_datasets/imdb/test.tsv",sep="\t",header = None,names = ["label","text"])
from gensim import corpora
import string#1,文本切词
def textsplit(text):translator = str.maketrans('', '', string.punctuation)words = text.translate(translator).split(' ')return words#2,构建词典
vocab = corpora.Dictionary((textsplit(text) for text in dftrain['text']))
vocab.filter_extremes(no_below=5,no_above=5000)
special_tokens = {'<pad>': 0, '<unk>': 1}
vocab.patch_with_special_tokens(special_tokens)
vocab_size = len(vocab.token2id) 
print('vocab_size = ',vocab_size)#3,序列填充
def pad(seq,max_length,pad_value=0):n = len(seq)result = seq+[pad_value]*max_lengthreturn result[:max_length]#4,编码转换
def text_pipeline(text):tokens = vocab.doc2idx(textsplit(text))tokens = [x if x>0 else special_tokens['<unk>']  for x in tokens ]result = pad(tokens,MAX_LEN,special_tokens['<pad>'])return result print(text_pipeline("this is an example!")) 
vocab_size =  29924
[145, 77, 569, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

#5,构建管道
from torch.utils.data import Dataset,DataLoaderclass ImdbDataset(Dataset):def __init__(self,df):self.df = dfdef __len__(self):return len(self.df)def __getitem__(self,index):text = self.df["text"].iloc[index]label = torch.tensor([self.df["label"].iloc[index]]).float()tokens = torch.tensor(text_pipeline(text)).int() return tokens,labelds_train = ImdbDataset(dftrain)
ds_val = ImdbDataset(dfval)
dl_train = DataLoader(ds_train,batch_size = 50,shuffle = True)
dl_val = DataLoader(ds_val,batch_size = 50,shuffle = False)
for features,labels in dl_train:break 

二,定义模型

使用Pytorch通常有三种方式构建模型:使用nn.Sequential按层顺序构建模型,继承nn.Module基类构建自定义模型,继承nn.Module基类构建模型并辅助应用模型容器(nn.Sequential,nn.ModuleList,nn.ModuleDict)进行封装。

此处选择使用第三种方式进行构建。

import torch
from torch import nn 
torch.manual_seed(42)
<torch._C.Generator at 0x142700950>
class Net(nn.Module):def __init__(self):super(Net, self).__init__()#设置padding_idx参数后将在训练过程中将填充的token始终赋值为0向量self.embedding = nn.Embedding(num_embeddings = vocab_size,embedding_dim = 3,padding_idx = 0)self.conv = nn.Sequential()self.conv.add_module("conv_1",nn.Conv1d(in_channels = 3,out_channels = 16,kernel_size = 5))self.conv.add_module("pool_1",nn.MaxPool1d(kernel_size = 2))self.conv.add_module("relu_1",nn.ReLU())self.conv.add_module("conv_2",nn.Conv1d(in_channels = 16,out_channels = 128,kernel_size = 2))self.conv.add_module("pool_2",nn.MaxPool1d(kernel_size = 2))self.conv.add_module("relu_2",nn.ReLU())self.dense = nn.Sequential()self.dense.add_module("flatten",nn.Flatten())self.dense.add_module("linear",nn.Linear(6144,1))def forward(self,x):x = self.embedding(x).transpose(1,2)x = self.conv(x)y = self.dense(x)return ynet = Net() 
print(net)
Net((embedding): Embedding(29924, 3, padding_idx=0)(conv): Sequential((conv_1): Conv1d(3, 16, kernel_size=(5,), stride=(1,))(pool_1): MaxPool1d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(relu_1): ReLU()(conv_2): Conv1d(16, 128, kernel_size=(2,), stride=(1,))(pool_2): MaxPool1d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(relu_2): ReLU())(dense): Sequential((flatten): Flatten(start_dim=1, end_dim=-1)(linear): Linear(in_features=6144, out_features=1, bias=True))
)
Net((embedding): Embedding(8813, 3, padding_idx=0)(conv): Sequential((conv_1): Conv1d(3, 16, kernel_size=(5,), stride=(1,))(pool_1): MaxPool1d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(relu_1): ReLU()(conv_2): Conv1d(16, 128, kernel_size=(2,), stride=(1,))(pool_2): MaxPool1d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(relu_2): ReLU())(dense): Sequential((flatten): Flatten(start_dim=1, end_dim=-1)(linear): Linear(in_features=6144, out_features=1, bias=True))
)

from torchkeras import summary 
summary(net,input_data=features);
--------------------------------------------------------------------------
Layer (type)                            Output Shape              Param #
==========================================================================
Embedding-1                             [-1, 200, 3]               89,772
Conv1d-2                               [-1, 16, 196]                  256
MaxPool1d-3                             [-1, 16, 98]                    0
ReLU-4                                  [-1, 16, 98]                    0
Conv1d-5                               [-1, 128, 97]                4,224
MaxPool1d-6                            [-1, 128, 48]                    0
ReLU-7                                 [-1, 128, 48]                    0
Flatten-8                                 [-1, 6144]                    0
Linear-9                                     [-1, 1]                6,145
==========================================================================
Total params: 100,397
Trainable params: 100,397
Non-trainable params: 0
--------------------------------------------------------------------------
Input size (MB): 0.000069
Forward/backward pass size (MB): 0.287788
Params size (MB): 0.382984
Estimated Total Size (MB): 0.670841
--------------------------------------------------------------------------

三,训练模型

训练Pytorch通常需要用户编写自定义训练循环,训练循环的代码风格因人而异。

有3类典型的训练循环代码风格:脚本形式训练循环,函数形式训练循环,类形式训练循环。

此处介绍一种较通用的仿照Keras风格的类形式的训练循环。

该训练循环的代码也是torchkeras库的核心代码。

torchkeras详情: https://github.com/lyhue1991/torchkeras

import os,sys,time
import numpy as np
import pandas as pd
import datetime 
from tqdm import tqdm import torch
from torch import nn 
from copy import deepcopydef printlog(info):nowtime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')print("\n"+"=========="*8 + "%s"%nowtime)print(str(info)+"\n")class StepRunner:def __init__(self, net, loss_fn,stage = "train", metrics_dict = None, optimizer = None, lr_scheduler = None):self.net,self.loss_fn,self.metrics_dict,self.stage = net,loss_fn,metrics_dict,stageself.optimizer,self.lr_scheduler = optimizer,lr_schedulerdef __call__(self, features, labels):#losspreds = self.net(features)loss = self.loss_fn(preds,labels)#backward()if self.optimizer is not None and self.stage=="train":loss.backward()self.optimizer.step()if self.lr_scheduler is not None:self.lr_scheduler.step()self.optimizer.zero_grad()#metricsstep_metrics = {self.stage+"_"+name:metric_fn(preds, labels).item() for name,metric_fn in self.metrics_dict.items()}return loss.item(),step_metricsclass EpochRunner:def __init__(self,steprunner):self.steprunner = steprunnerself.stage = steprunner.stageself.steprunner.net.train() if self.stage=="train" else self.steprunner.net.eval()def __call__(self,dataloader):total_loss,step = 0,0loop = tqdm(enumerate(dataloader), total =len(dataloader))for i, batch in loop: if self.stage=="train":loss, step_metrics = self.steprunner(*batch)else:with torch.no_grad():loss, step_metrics = self.steprunner(*batch)step_log = dict({self.stage+"_loss":loss},**step_metrics)total_loss += lossstep+=1if i!=len(dataloader)-1:loop.set_postfix(**step_log)else:epoch_loss = total_loss/stepepoch_metrics = {self.stage+"_"+name:metric_fn.compute().item() for name,metric_fn in self.steprunner.metrics_dict.items()}epoch_log = dict({self.stage+"_loss":epoch_loss},**epoch_metrics)loop.set_postfix(**epoch_log)for name,metric_fn in self.steprunner.metrics_dict.items():metric_fn.reset()return epoch_logclass KerasModel(torch.nn.Module):def __init__(self,net,loss_fn,metrics_dict=None,optimizer=None,lr_scheduler = None):super().__init__()self.history = {}self.net = netself.loss_fn = loss_fnself.metrics_dict = nn.ModuleDict(metrics_dict) self.optimizer = optimizer if optimizer is not None else torch.optim.Adam(self.parameters(), lr=1e-2)self.lr_scheduler = lr_schedulerdef forward(self, x):if self.net:return self.net.forward(x)else:raise NotImplementedErrordef fit(self, train_data, val_data=None, epochs=10, ckpt_path='checkpoint.pt', patience=5, monitor="val_loss", mode="min"):for epoch in range(1, epochs+1):printlog("Epoch {0} / {1}".format(epoch, epochs))# 1,train -------------------------------------------------  train_step_runner = StepRunner(net = self.net,stage="train",loss_fn = self.loss_fn,metrics_dict=deepcopy(self.metrics_dict),optimizer = self.optimizer, lr_scheduler = self.lr_scheduler)train_epoch_runner = EpochRunner(train_step_runner)train_metrics = train_epoch_runner(train_data)for name, metric in train_metrics.items():self.history[name] = self.history.get(name, []) + [metric]# 2,validate -------------------------------------------------if val_data:val_step_runner = StepRunner(net = self.net,stage="val",loss_fn = self.loss_fn,metrics_dict=deepcopy(self.metrics_dict))val_epoch_runner = EpochRunner(val_step_runner)with torch.no_grad():val_metrics = val_epoch_runner(val_data)val_metrics["epoch"] = epochfor name, metric in val_metrics.items():self.history[name] = self.history.get(name, []) + [metric]# 3,early-stopping -------------------------------------------------if not val_data:continuearr_scores = self.history[monitor]best_score_idx = np.argmax(arr_scores) if mode=="max" else np.argmin(arr_scores)if best_score_idx==len(arr_scores)-1:torch.save(self.net.state_dict(),ckpt_path)print("<<<<<< reach best {0} : {1} >>>>>>".format(monitor,arr_scores[best_score_idx]),file=sys.stderr)if len(arr_scores)-best_score_idx>patience:print("<<<<<< {} without improvement in {} epoch, early stopping >>>>>>".format(monitor,patience),file=sys.stderr)break self.net.load_state_dict(torch.load(ckpt_path))  return pd.DataFrame(self.history)@torch.no_grad()def evaluate(self, val_data):val_step_runner = StepRunner(net = self.net,stage="val",loss_fn = self.loss_fn,metrics_dict=deepcopy(self.metrics_dict))val_epoch_runner = EpochRunner(val_step_runner)val_metrics = val_epoch_runner(val_data)return val_metrics@torch.no_grad()def predict(self, dataloader):self.net.eval()result = torch.cat([self.forward(t[0]) for t in dataloader])return result.data
from torchmetrics import Accuracynet = Net() 
model = KerasModel(net,loss_fn = nn.BCEWithLogitsLoss(),optimizer= torch.optim.Adam(net.parameters(),lr = 0.01),  metrics_dict = {"acc":Accuracy(task='binary')})
model.fit(dl_train,val_data=dl_val,epochs=10,ckpt_path='checkpoint',patience=3,monitor='val_acc',mode='max')
================================================================================2023-08-02 14:20:21
Epoch 1 / 10100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 400/400 [00:10<00:00, 39.28it/s, train_acc=0.496, train_loss=0.701]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 100/100 [00:01<00:00, 51.21it/s, val_acc=0.518, val_loss=0.693]
<<<<<< reach best val_acc : 0.5180000066757202 >>>>>>================================================================================2023-08-02 14:20:33
Epoch 2 / 10100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 400/400 [00:09<00:00, 40.14it/s, train_acc=0.503, train_loss=0.693]
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 100/100 [00:01<00:00, 54.22it/s, val_acc=0.58, val_loss=0.689]
<<<<<< reach best val_acc : 0.5803999900817871 >>>>>>================================================================================2023-08-02 14:20:45
Epoch 3 / 10100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 400/400 [00:10<00:00, 39.46it/s, train_acc=0.69, train_loss=0.58]
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 100/100 [00:01<00:00, 53.84it/s, val_acc=0.781, val_loss=0.47]
<<<<<< reach best val_acc : 0.7807999849319458 >>>>>>================================================================================2023-08-02 14:20:57
Epoch 4 / 10100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 400/400 [00:09<00:00, 40.33it/s, train_acc=0.83, train_loss=0.386]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 100/100 [00:01<00:00, 54.18it/s, val_acc=0.819, val_loss=0.408]
<<<<<< reach best val_acc : 0.8194000124931335 >>>>>>================================================================================2023-08-02 14:21:09
Epoch 5 / 10100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 400/400 [00:09<00:00, 40.63it/s, train_acc=0.893, train_loss=0.262]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 100/100 [00:01<00:00, 55.69it/s, val_acc=0.836, val_loss=0.395]
<<<<<< reach best val_acc : 0.8357999920845032 >>>>>>================================================================================2023-08-02 14:21:21
Epoch 6 / 10100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 400/400 [00:09<00:00, 40.58it/s, train_acc=0.932, train_loss=0.176]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 100/100 [00:01<00:00, 50.93it/s, val_acc=0.828, val_loss=0.456]================================================================================2023-08-02 14:21:33
Epoch 7 / 10100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 400/400 [00:10<00:00, 39.62it/s, train_acc=0.956, train_loss=0.119]
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 100/100 [00:01<00:00, 55.26it/s, val_acc=0.829, val_loss=0.558]================================================================================2023-08-02 14:21:44
Epoch 8 / 10100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 400/400 [00:09<00:00, 40.58it/s, train_acc=0.973, train_loss=0.0754]
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 100/100 [00:01<00:00, 52.91it/s, val_acc=0.823, val_loss=0.67]
<<<<<< val_acc without improvement in 3 epoch, early stopping >>>>>>
train_losstrain_accval_lossval_accepoch
00.7010640.495800.6930450.51801
10.6930600.503350.6886560.58042
20.5798670.690100.4695740.78083
30.3856250.829900.4076330.81944
40.2616530.892600.3949010.83585
50.1759210.932100.4556040.82846
60.1191780.956100.5584300.82867
70.0754090.973300.6701720.82328


四,评估模型

import pandas as pd history = model.history
dfhistory = pd.DataFrame(history) 
dfhistory 
train_losstrain_accval_lossval_accepoch
00.7010640.495800.6930450.51801
10.6930600.503350.6886560.58042
20.5798670.690100.4695740.78083
30.3856250.829900.4076330.81944
40.2616530.892600.3949010.83585
50.1759210.932100.4556040.82846
60.1191780.956100.5584300.82867
70.0754090.973300.6701720.82328
%matplotlib inline
%config InlineBackend.figure_format = 'svg'import matplotlib.pyplot as pltdef plot_metric(dfhistory, metric):train_metrics = dfhistory["train_"+metric]val_metrics = dfhistory['val_'+metric]epochs = range(1, len(train_metrics) + 1)plt.plot(epochs, train_metrics, 'bo--')plt.plot(epochs, val_metrics, 'ro-')plt.title('Training and validation '+ metric)plt.xlabel("Epochs")plt.ylabel(metric)plt.legend(["train_"+metric, 'val_'+metric])plt.show()
plot_metric(dfhistory,"loss")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

plot_metric(dfhistory,"acc")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

# 评估
model.evaluate(dl_val)
100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 100/100 [00:01<00:00, 50.26it/s, val_acc=0.836, val_loss=0.395]{'val_loss': 0.39490113019943235, 'val_acc': 0.8357999920845032}

五,使用模型

def predict(net,dl):net.eval()with torch.no_grad():result = nn.Sigmoid()(torch.cat([net.forward(t[0]) for t in dl]))return(result.data)
y_pred_probs = predict(net,dl_val)
y_pred_probs
tensor([[0.9372],[1.0000],[0.8672],...,[0.5141],[0.4756],[0.9998]])

六,保存模型

#模型权重已经被保存在了ckpt_path='checkpoint.'
net_clone = Net()
net_clone.load_state_dict(torch.load('checkpoint'))
<All keys matched successfully>

如果本书对你有所帮助,想鼓励一下作者,记得给本项目加一颗星星star⭐️,并分享给你的朋友们喔😊!

如果对本书内容理解上有需要进一步和作者交流的地方,欢迎在公众号"算法美食屋"下留言。作者时间和精力有限,会酌情予以回复。

也可以在公众号后台回复关键字:加群,加入读者交流群和大家讨论。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

相关文章:

1-3.文本数据建模流程范例

文章最前&#xff1a; 我是Octopus&#xff0c;这个名字来源于我的中文名–章鱼&#xff1b;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github &#xff1b;这博客是记录我学习的点点滴滴&#xff0c;如果您对 Python、Java、AI、算法有兴趣&#xff0c;可以关注我的…...

【FFmpeg】avformat_alloc_output_context2函数

【FFmpeg】avformat_alloc_output_context2函数 1.avformat_alloc_output_context21.1 初始化AVFormatContext&#xff08;avformat_alloc_context&#xff09;1.2 格式猜测&#xff08;av_guess_format&#xff09;1.2.1 遍历可用的fmt&#xff08;av_muxer_iterate&#xff0…...

Flask 缓存和信号

Flask-Caching Flask-Caching 是 Flask 的一个扩展&#xff0c;它为 Flask 应用提供了缓存支持。缓存是一种优化技术&#xff0c;可以存储那些费时且不经常改变的运算结果&#xff0c;从而加快应用的响应速度。 一、初始化配置 安装 Flask-Caching 扩展&#xff1a; pip3 i…...

基于weixin小程序农场驿站系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;农场资讯管理&#xff0c;用户管理&#xff0c;卖家管理&#xff0c;用户分享管理&#xff0c;分享类型管理&#xff0c;商品信息管理&#xff0c;商品类型管理 开发系统&#xff1a;Windows 架构模式…...

JAVA将List转成Tree树形结构数据和深度优先遍历

引言&#xff1a; 在日常开发中&#xff0c;我们经常会遇到需要将数据库中返回的数据转成树形结构的数据返回&#xff0c;或者需要对转为树结构后的数据绑定层级关系再返回&#xff0c;比如需要统计当前节点下有多少个节点等&#xff0c;因此我们需要封装一个ListToTree的工具类…...

设计模式——开闭、单一职责及里氏替换原则

设计原则是指导软件设计和开发的一系列原则&#xff0c;它们帮助开发者创建出易于维护、扩展和理解的代码。以下是你提到的几个关键设计原则的简要说明&#xff1a; 开闭原则&#xff08;Open/Closed Principle, OCP&#xff09;&#xff1a; 开闭原则由Bertrand Meyer提出&am…...

代码随想录算法训练营第59天:动态[1]

代码随想录算法训练营第59天&#xff1a;动态 两个字符串的删除操作 力扣题目链接(opens new window) 给定两个单词 word1 和 word2&#xff0c;找到使得 word1 和 word2 相同所需的最小步数&#xff0c;每步可以删除任意一个字符串中的一个字符。 示例&#xff1a; 输入: …...

jvm性能监控常用工具

在java的/bin目录下有许多java自带的工具。 我们常用的有 基础工具 jar:创建和管理jar文件 java&#xff1a;java运行工具&#xff0c;用于运行class文件或jar文件 javac&#xff1a;java的编译器 javadoc&#xff1a;java的API文档生成工具 性能监控和故障处理 jps jstat…...

ISP IC/FPGA设计-第一部分-SC130GS摄像头分析-IIC通信(1)

1.摄像头模组 SC130GS通过一个引脚&#xff08;SPI_I2C_MODE&#xff09;选择使用IIC或SPI配置接口&#xff0c;通过查看摄像头模组的原理图&#xff0c;可知是使用IIC接口&#xff1b; 通过手册可知IIC设备地址通过一个引脚控制&#xff0c;查看摄像头模组的原理图&#xff…...

HTTP协议头中X-Forwarded-For是能做什么?

X-Forwarded-For和相关几个头部的理解 $remote_addr 是nginx与客户端进行TCP连接过程中&#xff0c;获得的客户端真实地址. Remote Address 无法伪造&#xff0c;因为建立 TCP 连接需要三次握手&#xff0c;如果伪造了源 IP&#xff0c;无法建立 TCP 连接&#xff0c;更不会有后…...

Linux高并发服务器开发(八)Socket和TCP

文章目录 1 IPV4套接字结构体2 TCP客户端函数 3 TCP服务器流程函数代码粘包 4 三次握手5 四次挥手6 滑动窗口 1 IPV4套接字结构体 2 TCP客户端 特点&#xff1a;出错重传 每次发送数据对方都会回ACK&#xff0c;可靠 tcp是打电话的模型&#xff0c;建立连接 使用连接 关闭连接…...

力扣第220题“存在重复元素 III”

在本篇文章中&#xff0c;我们将详细解读力扣第220题“存在重复元素 III”。通过学习本篇文章&#xff0c;读者将掌握如何使用桶排序和滑动窗口来解决这一问题&#xff0c;并了解相关的复杂度分析和模拟面试问答。每种方法都将配以详细的解释&#xff0c;以便于理解。 问题描述…...

Qt实战项目——贪吃蛇

一、项目介绍 本项目是一个使用Qt框架开发的经典贪吃蛇游戏&#xff0c;旨在通过简单易懂的游戏机制和精美的用户界面&#xff0c;为玩家提供娱乐和编程学习的机会。 游戏展示 二、主要功能 2.1 游戏界面 游戏主要是由三个界面构成&#xff0c;分别是游戏大厅、难度选择和游戏…...

Windows 10,11 Server 2022 Install Docker-Desktop

docker 前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。 docker-compose Compose 是用于定义和运行…...

C++中的RAII(资源获取即初始化)原则

C中的RAII&#xff08;Resource Acquisition Is Initialization&#xff0c;资源获取即初始化&#xff09;原则是一种管理资源、避免资源泄漏的惯用法。RAII是C之父Bjarne Stroustrup提出的设计理念&#xff0c;其核心思想是将资源的获取&#xff08;如动态内存分配、文件句柄、…...

【机器学习】Whisper:开源语音转文本(speech-to-text)大模型实战

目录 一、引言 二、Whisper 模型原理 2.1 模型架构 2.2 语音处理 2.3 文本处理 三、Whisper 模型实战 3.1 环境安装 3.2 模型下载 3.3 模型推理 3.4 完整代码 3.5 模型部署 四、总结 一、引言 上一篇对​​​​​​​ChatTTS文本转语音模型原理和实战进行了讲解&a…...

ubuntu22.04 编译安装openssl C++ library

#--------------------------------------------------------------------------- # openssl C library # https://www.openssl.org/source/index.html #--------------------------------------------------------------------------- cd /opt/download # 下载openssl-3.0.13…...

百度Agent初体验(制作步骤+感想)

现在AI Agent很火&#xff0c;最近注册了一个百度Agent体验了一下&#xff0c;并做了个小实验&#xff0c;拿它和零一万物&#xff08;Yi Large&#xff09;和文心一言&#xff08;ERNIE-4.0-8K-latest&#xff09;阅读了相同的一篇网页资讯&#xff0c;输出资讯摘要&#xff0…...

7-491 3名同学5门课程成绩,输出最好成绩及所在的行和列(二维数组作为函数的参数)

编程:数组存储3名同学5门课程成绩 输出最好成绩及所在的行和列 要求&#xff1a;将输入、查找和打印的功能编写成函数 并将二维数组通过指针参数传递的方式由主函数传递到子函数中 输入格式: 每行输入一个同学的5门课的成绩&#xff0c;每个成绩之间空一格&#xff0c;见输入…...

OpenCloudOS开源的操作系统

OpenCloudOS 是一款开源的操作系统&#xff0c;致力于提供高性能、稳定和安全的操作系统环境&#xff0c;以满足现代计算和应用程序的需求。它结合了现代操作系统设计的最新技术和实践&#xff0c;为开发者和企业提供了一个强大的平台。本文将详细介绍 OpenCloudOS 的背景、特性…...

排序题目:多数元素 II

文章目录 题目标题和出处难度题目描述要求示例数据范围进阶 前言解法一思路和算法代码复杂度分析 解法二思路和算法代码复杂度分析 解法三思路和算法代码复杂度分析 题目 标题和出处 标题&#xff1a;多数元素 II 出处&#xff1a;229. 多数元素 II 难度 3 级 题目描述 …...

<电力行业> - 《第1课:电力行业的五大四小》

1 什么是电力行业的五大四小&#xff1f; 我们常说的电力行业的五大四小&#xff0c;指的是电力行业有实力的公司&#xff0c;分为&#xff1a;较强梯队的五大集团、较弱梯队的四小豪门。 五个实力雄厚的集团&#xff0c;分别是&#xff1a; 中国华能集团公司中国大唐集团公…...

数据库定义语言(DDL)

数据库定义语言&#xff08;DDL&#xff09; 一、数据库操作 1、 查询所有的数据库 SHOW DATABASES;效果截图&#xff1a; 2、使用指定的数据库 use 2403 2403javaee;效果截图&#xff1a; 3、创建数据库 CREATE DATABASE 2404javaee;效果截图&#xff1a; 4、删除数据…...

mybatis实现多表查询

mybatis高级查询【掌握】 1、准备工作 【1】包结构 创建java项目&#xff0c;导入jar包和log4j日志配置文件以及连接数据库的配置文件&#xff1b; 【2】导入SQL脚本 运行资料中的sql脚本&#xff1a;mybatis.sql 【3】创建实体来包&#xff0c;导入资料中的pojo 【4】User…...

数据结构:队列详解 c++信息学奥赛基础知识讲解

目录 一、队列概念 二、队列容器 三、队列操作 四、代码实操 五、队列遍历 六、案例实操 题目描述&#xff1a; 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 详细代码&#xff1a; 一、队列概念 队列是一种特殊的线性…...

硬件开发笔记(二十三):贴片电阻的类别、封装介绍,AD21导入贴片电阻原理图封装库3D模型

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/140110514 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…...

Kafka基本原理详解

&#xff08;一&#xff09;概念理解 Apache Kafka是一种开源的分布式流处理平台&#xff0c;专为高性能、高吞吐量的实时数据处理而设计。它最初由LinkedIn公司开发&#xff0c;旨在解决其网站活动中产生的大量实时数据处理和传输问题&#xff0c;后来于2011年开源&#xff0…...

【Unity】RPG2D龙城纷争(七)关卡编辑器之剧情编辑

更新日期:2024年7月1日。 项目源码:第五章发布(正式开始游戏逻辑的章节) 索引 简介一、剧情编辑1.对话数据集2.对话触发方式3.选择对话角色4.设置对话到关卡5.通关条件简介 严格来说,剧情编辑不在关卡编辑器界面中完成,只不过它仍然属于关卡编辑的范畴。 在我们的设想中…...

uniapp启动页面鉴权页面闪烁问题

在使用uni-app开发app 打包完成后如果没有token&#xff0c;那么就在onLaunch生命周期里面判断用户是否登录并跳转至登录页。 但是在app中页面会先进入首页然后再跳转至登录页&#xff0c;十分影响体验。 处理方法&#xff1a; 使用plus.navigator.closeSplashscreen() 官网…...

全志H616交叉编译工具链的安装与使用

交叉编译的概念 1. 什么是交叉编译&#xff1f; 交叉编译是指在一个平台上生成可以在另一个平台上运行的可执行代码。例如&#xff0c;在Ubuntu Linux上编写代码&#xff0c;并编译生成可在Orange Pi Zero2上运行的可执行文件。这个过程是通过使用一个专门的交叉编译工具链来…...

深入解析Java和Go语言中String与byte数组的转换原理

1.Java String与byte[]互相转换存在的问题 java中&#xff0c;按照byte[] 》string 》byte[]的流程转换后&#xff0c;byte数据与最初的byte不一致。 多说无益&#xff0c;上代码&#xff0c;本地macos机器执行&#xff0c;统一使用的UTF-8编码。 import java.nio.charset.S…...

什么是strcmp函数

目录 开头1.什么是strcmp函数2.strcmp函数里的内部结构3.strcmp函数的实际运用(这里只列举其一)脑筋急转弯 结尾 开头 大家好&#xff0c;我叫这是我58。今天&#xff0c;我们要来认识一下C语言中的strcmp函数。 1.什么是strcmp函数 strcmp函数来自于C语言中的头文件<str…...

Follow Carl To Grow|【LeetCode】491.递增子序列,46.全排列,47.全排列 II

【LeetCode】491.递增子序列 题意&#xff1a;给你一个整数数组 nums &#xff0c;找出并返回所有该数组中不同的递增子序列&#xff0c;递增子序列中 至少有两个元素 。你可以按 任意顺序 返回答案。 数组中可能含有重复元素&#xff0c;如出现两个整数相等&#xff0c;也可以…...

pytorch nn.Embedding 用法和原理

nn.Embedding 是 PyTorch 中的一个模块&#xff0c;用于将离散的输入&#xff08;通常是词或子词的索引&#xff09;映射到连续的向量空间。它在自然语言处理和其他需要处理离散输入的任务中非常常用。以下是 nn.Embedding 的用法和原理。 用法 初始化 nn.Embedding nn.Embed…...

Python中常用的有7种值(数据)的类型及type()语句的用法

目录 0.Python中常用的有7种值&#xff08;数据&#xff09;的类型Python中的数据类型主要有&#xff1a;Number&#xff08;数字&#xff09;、Boolean&#xff08;布尔&#xff09;、String&#xff08;字符串&#xff09;、List&#xff08;列表&#xff09;、Tuple&#xf…...

某配送平台未授权访问和弱口令(附赠nuclei默认密码验证脚本)

找到一个某src的子站&#xff0c;通过信息收集插件&#xff0c;发现ZABBIX-监控系统&#xff0c;可以日一下 使用谷歌搜索历史漏洞&#xff1a;zabbix漏洞 通过目录扫描扫描到后台&#xff0c;谷歌搜索一下有没有默认弱口令 成功进去了&#xff0c;挖洞就是这么简单 搜索文章还…...

01.总览

目录 简介Course 1: Natural Language Processing with Classification and Vector SpaceWeek 1: Sentiment Analysis with Logistic RegressionWeek 2: Sentiment Analysis with Nave BayesWeek 3: Vector Space ModelsWeek 4: Machine Translation and Document Search Cours…...

Linux换源

前言 安装完Linux系统&#xff0c;尽量更换源以提高安装软件的速度。 步骤 备份原始源列表sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak修改sources.list sudo vim /etc/apt/sources.list将内容替换成对应的源 **PS&#xff1a;清华源地址&#xff1a;https:…...

【高考志愿】 化学工程与技术

目录 一、专业概述 二、就业前景 三、就业方向 四、报考注意 五、专业发展与深造 六、化学工程与技术专业排名 七、总结 一、专业概述 化学工程与技术专业&#xff0c;这是一门深具挑战与机遇的综合性学科。它融合了工程技术的实用性和化学原理的严谨性&#xff0c;为毕…...

2024上半年网络与数据安全法规政策、国标、报告合集

事关大局&#xff0c;我国数据安全立法体系已基本形成并逐步细化。数据基础制度建设事关国家发展和安全大局&#xff0c;数据安全治理贯穿构建数据基础制度体系全过程。随着我国数字经济建设进程加快&#xff0c;数据安全立法实现由点到面、由面到体加速构建&#xff0c;目前已…...

基于SpringBoot扶农助农政策管理系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; &#x1f31f;文末获取源码数据库&#x1f31f; 感兴趣的可以先收藏起来&#xff0c;…...

淘宝商铺电话怎么获取?使用爬虫工具采集

访问淘宝商铺是一个合法的行为&#xff0c;你可以使用爬虫工具来提取淘宝商铺的信息。下面是一个基本的Python程序示例&#xff0c;用于使用爬虫工具访问淘宝商铺&#xff1a; import requestsdef get_store_info(store_id):url fhttps://shop{id}.taobao.comresponse reque…...

ModStart:开源免费的PHP企业网站开发建设管理系统

大家好&#xff01;今天我要给大家介绍一款超级强大的开源工具——ModStart&#xff0c;它基于Laravel框架&#xff0c;是PHP企业网站开发建设的绝佳选择&#xff01; 为什么选择ModStart&#xff1f; 模块化设计&#xff1a;ModStart采用模块化设计&#xff0c;内置了众多基…...

npm安装依赖报错——npm ERR gyp verb cli的解决方法

1. 问题描述 1.1 npm安装依赖报错——npm ERR! gyp verb cli npm MARN deprecated axiosQ0.18.1: critical security vuLnerability fixed in v0.21.1. For more information, npm WARN deprecated svg001.3.2: This SVGO version is no Longer supported. upgrade to v2.x.x …...

公网环境使用Potplayer远程访问家中群晖NAS搭建的WebDAV听歌看电影

文章目录 前言1 使用环境要求&#xff1a;2 配置webdav3 测试局域网使用potplayer访问webdav4 内网穿透&#xff0c;映射至公网5 使用固定地址在potplayer访问webdav 前言 本文主要介绍如何在Windows设备使用potplayer播放器远程访问本地局域网的群晖NAS中的影视资源&#xff…...

Forecasting from LiDAR via Future Object Detection

Forecasting from LiDAR via Future Object Detection 基础信息 论文&#xff1a;cvpr2022paper https://openaccess.thecvf.com/content/CVPR2022/papers/Peri_Forecasting_From_LiDAR_via_Future_Object_Detection_CVPR_2022_paper.pdfgithub&#xff1a;https://github.co…...

【unity笔记】五、UI面板TextMeshPro 添加中文字体

Unity 中 TextMeshPro不支持中文字体&#xff0c;下面为解决方法&#xff1a; 准备字体文件&#xff0c;从Windows系统文件的Fonts文件夹里拖一个.ttf文件&#xff08;C盘 > Windows > Fonts &#xff09; 准备字库文件,新建一个文本文件&#xff0c;命名为“字库”&…...

如何在Windows 11上设置默认麦克风和相机?这里有详细步骤

如果你的Windows 11计算机上连接了多个麦克风或网络摄像头&#xff0c;并且希望自动使用特定设备&#xff0c;而不必每次都在设置中乱动&#xff0c;则必须将首选设备设置为默认设备。我们将向你展示如何做到这一点。 如何在Windows 11上更改默认麦克风 有两种方法可以将麦克…...

Flutter循序渐进==>数据结构(列表、映射和集合)和错误处理

导言 填鸭似的教育确实不行&#xff0c;我高中时学过集合&#xff0c;不知道有什么用&#xff0c;毫无兴趣&#xff0c;等到我学了一门编程语言后&#xff0c;才发现集合真的很有用&#xff1b;可以去重&#xff0c;可以看你有我没有的&#xff0c;可以看我有你没有的&#xf…...

泛微E9开发 限制明细表列的值重复

限制明细表列的值重复 1、需求说明2、实现方法3、扩展知识点3.1 修改单个字段值&#xff08;不支持附件类型&#xff09;3.1.1 格式3.1.2 参数3.1.3 案例 3.2 获取明细行所有行标示3.2.1 格式3.2.2 参数说明 1、需求说明 限制明细表的“类型”字段&#xff0c;在同一个流程表单…...

Android 生成 AAR 包

当我们需要在 Android 项目中引用第三方库或模块时&#xff0c;常常会使用 AAR&#xff08;Android Archive&#xff09;包。AAR 包是一种包含了编译后代码、资源文件和清单文件等的二进制文件。 步骤 1&#xff1a;创建一个 Android Library 项目 在 Android Studio 中&#…...

C++ 和C#的差别

首先把眼睛瞪大&#xff0c;然后憋住一口气&#xff0c;读下去&#xff1a; 1、CPP 就是C plus plus的缩写&#xff0c;中国大陆的程序员圈子中通常被读做"C加加"&#xff0c;而西方的程序员通常读做"C plus plus"&#xff0c;它是一种使用非常广泛的计算…...

OpenSSL EVP详解

OpenSSL EVP详解 Chapter1 OpenSSL EVP详解一、EVP基本介绍1. EVP 加密和解密2. EVP 签名和验证3. EVP 加解密文件 二、源码结构2.1 全局函数2.2 BIO扩充2.3 摘要算法EVP封装2.4 对称算法EVP封装2.5 非对称算法EVP封装2.6 基于口令的加密 三、开发实例3.1 示例13.2 示例23.3 示…...

用MySQL+node+vue做一个学生信息管理系统(四):制作增加、删除、修改的组件和对应的路由

1.下载依赖&#xff1a; npm install vue-router 在src目录下新建一个文件夹router&#xff0c;在router文件夹下新建一个文件router.js文件,在component目录下新建增加删除和修改的组件&#xff0c;引入router.js当中 此时的init组件为主页面&#xff08;&#xff08;二、三&…...

【软件测试】Junit单元测试框架 | 注解 | 参数化 | 测试套件

文章目录 Junit单元测试框架1.注解TestDisableBeforeAll、AfterAllBeforeEach、AfterEach 2.参数化单参数CSV获取参数多参数方法获取参数测试用例执行顺序断言 3.测试套件通过class运行测试用例通过包来运行测试用例 Junit单元测试框架 Selenium3是自动化测试框架 Junit5是单元…...

Android中的适配器,你知道是做什么的吗?

&#x1f604;作者简介&#xff1a; 小曾同学.com,一个致力于测试开发的博主⛽️&#xff0c;主要职责&#xff1a;测试开发、CI/CD&#xff0c;日常还会涉及Android开发工作。 如果文章知识点有错误的地方&#xff0c;还请大家指正&#xff0c;让我们一起学习&#xff0c;一起…...

途昂行情,2.5T/26.8万起,2.0T/17.4万起

如果你是SUV车迷,那么大抵上,心里还有一辆终极的大型SUV作为梦想车,试问是不是这样?很多人喜欢宝马X5、也有人喜欢奔驰GLE,可即便现在优惠幅度较高,2.0T的丐版车型也要落地超60万元,可不是随便哪个家庭就能负担的起。但预算在30万内,还是可以选择一辆搭载大V6发动机的中…...

河北进一步完善跨区域排水防涝应急联动机制

河北进一步完善跨区域排水防涝应急联动机制三个应急联动片区实行省内统筹调度6月1日,我省正式进入汛期。从省住房城乡建设厅获悉,我省进一步完善跨区域排水防涝应急联动机制,提高区域协同应急救援能力。按照地理区位,全省划分北部、中部(廊坊、保定、沧州、定州、雄安新区)…...

L3/L4产品准入和上路,9个联合体进入试点

6月4日,工业和信息化部、公安部、住房城乡建设部、交通运输部四部门联合宣布,按照《关于开展智能网联汽车准入和上路通行试点工作的通知》有关工作安排,经相关部门及专家初审和择优评审,已经确定了9个进入试点的联合体。2023年11月,上述四部门联合发布《关于开展智能网联汽…...

salesforce 公式字段 判断一个字段是否在某个多选列表中

在 Salesforce 中&#xff0c;你可以使用公式字段来判断一个字段的值是否在一个多选列表中。这通常涉及使用包含特定值的函数和一些字符串操作。以下是一个常见的方法&#xff1a; 假设你有一个多选列表字段 Multi_Select_Field__c&#xff0c;你想检查这个字段是否包含某个值…...

Java基础学习:深入解析Java中的位运算符

在Java中&#xff0c;位运算符用于对整数类型的值进行位运算。以下是Java中的位运算符&#xff1a; 位与(&)&#xff1a;两位都为1时&#xff0c;结果为1&#xff0c;否则为0。 位或(|)&#xff1a;两位中有1个为1&#xff0c;结果为1。 位非(~)&#xff1a;位的反&#…...

装机必备——截图软件PixPin安装教程

装机必备——截图软件PixPin安装教程 软件下载 软件名称&#xff1a;PixPin 1.5 软件语言&#xff1a;简体中文 软件大小&#xff1a;30.1M 系统要求&#xff1a;Windows7或更高&#xff0c; 64位操作系统 硬件要求&#xff1a;CPU2GHz &#xff0c;RAM2G或更高 下载通道①迅…...