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_length
    return 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,DataLoader

class ImdbDataset(Dataset):
    def __init__(self,df):
        self.df = df
    def __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,label
    
ds_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 y
        
net = 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 deepcopy

def 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,stage
        self.optimizer,self.lr_scheduler = optimizer,lr_scheduler
    
    def __call__(self, features, labels):
        #loss
        preds = 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()
            
        #metrics
        step_metrics = {self.stage+"_"+name:metric_fn(preds, labels).item() 
                        for name,metric_fn in self.metrics_dict.items()}
        return loss.item(),step_metrics


class EpochRunner:
    def __init__(self,steprunner):
        self.steprunner = steprunner
        self.stage = steprunner.stage
        self.steprunner.net.train() if self.stage=="train" else self.steprunner.net.eval()
        
    def __call__(self,dataloader):
        total_loss,step = 0,0
        loop = 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 += loss
            step+=1
            if i!=len(dataloader)-1:
                loop.set_postfix(**step_log)
            else:
                epoch_loss = total_loss/step
                epoch_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_log

class KerasModel(torch.nn.Module):
    def __init__(self,net,loss_fn,metrics_dict=None,optimizer=None,lr_scheduler = None):
        super().__init__()
        self.history = {}
        
        self.net = net
        self.loss_fn = loss_fn
        self.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_scheduler

    def forward(self, x):
        if self.net:
            return self.net.forward(x)
        else:
            raise NotImplementedError


    def 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"] = epoch
                for name, metric in val_metrics.items():
                    self.history[name] = self.history.get(name, []) + [metric]
            
            # 3,early-stopping -------------------------------------------------
            if not val_data:
                continue
            arr_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 Accuracy

net = 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 / 10



100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 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 / 10



100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 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 / 10



100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 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 / 10



100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 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 / 10



100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 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 / 10



100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 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 / 10



100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 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 / 10



100%|█████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 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 plt

def 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⭐️,并分享给你的朋友们喔😊!

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/763069.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法笔记:模拟过程(螺旋遍历矩阵)

1 模拟过程 “模拟过程题”通常指的是那些要求编程者通过编写代码来“模拟”或重现某个过程、系统或规则的题目。这类题目往往不涉及复杂的数据结构或高级算法&#xff0c;而是侧重于对给定规则的精确执行和逻辑的清晰表达。 其中螺旋遍历矩阵的题目就是一类典型的模拟过程题…

代码随想录-Day44

322. 零钱兑换 给你一个整数数组 coins &#xff0c;表示不同面额的硬币&#xff1b;以及一个整数 amount &#xff0c;表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额&#xff0c;返回 -1 。 你可以认为每种硬币的数…

ARCGIS python 裁剪栅格函数 arcpy.management.Clip

ARCGIS python 裁剪栅格函数 arcpy.management.Clip 1 功能 裁剪掉栅格数据集、镶嵌数据集或图像服务图层的一部分。 2 使用情况 基于模板范围提取部分栅格数据集&#xff0c;输出与模板范围相交的所有像素使用以 x 和 y 坐标的最小值和最大值确定的包络矩形或使用输出范围文…

商汤上海AI实验室联合发布:自动驾驶全栈式高精度标定工具箱(含车、IMU、相机、激光雷达等的标定)

前言 在自动驾驶技术飞速发展的今天&#xff0c;传感器的精确标定对于确保系统性能至关重要。SensorsCalibration&#xff0c;一个专为自动驾驶车辆设计的标定工具箱&#xff0c;提供了一套全面的解决方案&#xff0c;用于校准包括IMU、激光雷达、摄像头和雷达在内的多种传感器…

Evented PLEG: iSulad 稳态 CPU 利用率降低30%的关键特性

背景 容器技术在不断发展的过程中&#xff0c;已被广泛应用于多种场景。OpenAtom openEuler&#xff08;简称"openEuler"&#xff09; 社区容器引擎项目 iSulad[1]面向 CT、IT 领域的不同需求而生&#xff0c;它具有轻量级、高性能的特点&#xff0c;可以在资源受限…

vue3引入本地静态资源图片

一、单张图片引入 import imgXX from /assets/images/xx.png二、多张图片引入 说明&#xff1a;import.meta.url 是一个 ESM 的原生功能&#xff0c;会暴露当前模块的 URL。将它与原生的 URL 构造器 组合使用 注意&#xff1a;填写自己项目图片存放的路径 /** vite的特殊性…

技术干货丨基于MotionView的虚拟路面疲劳分析

虚拟路面VPG&#xff08;Virtual Proving Ground&#xff09;现在正被广泛应用于汽车的疲劳耐久分析中&#xff0c;相较于传统的道路载荷谱数据采集的疲劳计算方法&#xff0c;虚拟路面VPG技术可以极大地节省载荷谱的获取时间并降低测试成本。 本文将给大家介绍汽车悬挂系统中的…

一文讲解Docker入门到精通

一、引入 1、什么是虚拟化 在计算机中&#xff0c;虚拟化&#xff08;英语&#xff1a;Virtualization&#xff09;是一种资源管理技术&#xff0c;它允许在一台物理机上创建多个独立的虚拟环境&#xff0c;这些环境被称为虚拟机&#xff08;VM&#xff09;。每个虚拟机都可以…

无锁编程——从CPU缓存一致性讲到内存模型(1)

一.前言 1.什么是有锁编程&#xff0c;什么是无锁编程&#xff1f; 在编程中&#xff0c;特别是在并发编程的上下文中&#xff0c;“无锁”和“有锁”是描述线程同步和资源访问控制的两种不同策略。有锁&#xff08;Locked&#xff09;: 有锁编程是指使用锁&#xff08;例如互…

基于JSP技术的校园餐厅管理系统

开头语&#xff1a; 你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果您对校园餐厅管理系统感兴趣或有相关需求&#xff0c;欢迎随时联系我。我的联系方式在文末&#xff0c;期待与您交流&#xff01; 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#x…

MySQL 8 命令安装卸载教程

一、下载MySQL8 下载连接 MySQL :: Download MySQL Community Server 我下载的是当前最新版8.4 二、安装 1.解压 解压到需要安装的位置&#xff0c;例如我的位置&#xff1a; 2.创建配置文件 新建文本文档&#xff0c;复制下面配置文件&#xff08;注意修改路经&#xff09;…

Cesium大屏-vue3注册全局组件

1.需求 说明&#xff1a;产品经理要求开发人员在地图大屏上面随意放置组件&#xff0c;并且需要通过数据库更改其组件大小&#xff0c;位置等&#xff1b;适用于大屏组件中场站视角、任意位置标题等。 2.实现 2.1GlobalComponents.vue 说明&#xff1a;containerList可以通…

javascript 常见设计模式

什么是设计模式? 在软件开发中&#xff0c;设计模式是解决特定问题的经验总结和可复用的解决方案。设计模式可以提高代码的复用性、可维护性和可读性&#xff0c;是提高开发效率的重要手段。 单例模式 1.概念 单例模式 &#xff08;Singleton Pattern&#xff09;&#xf…

ssm校园二手交易平台小程序

设计技术&#xff1a; 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringMybatisSpringMvc微信小程序 工具&#xff1a;IDEA、Maven、Navicat 主要功能&#xff1a; (a) 管理员&#xff1b;管理员进入系统主要功能包括首页&#xff0c;个人中心&…

RedHat9 | 内部YUM本地源服务器搭建

服务器参数 标识公司内部YUM服务器主机名yum-server网络信息192.168.37.1/24网络属性静态地址主要操作用户root 一、基础环境信息配置 修改主机名 [rootyum-server ~]# hostnamectl hostname yum-server添加网络信息 [rootyum-server ~]# nmcli connection modify ens160 …

红黑树模拟

1.红黑树概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但每个节点上增加了一个存储位表示结点的颜色&#xff0c;可以是RED或BLACK。通过任何一条根到叶子节点的途径上各个节点的着色方式的限制&#xff0c;红黑树确保没有一条路径会超过其他路径的二倍&#xff0c;因…

MySQL InnoDB Cluster 高可用集群部署

MySQL InnoDB Cluster 简介 官方文档&#xff1a;https://dev.mysql.com/doc/refman/8.4/en/mysql-innodb-cluster-introduction.html 本章介绍 MySQL InnoDB Cluster&#xff0c;它结合了 MySQL 技术&#xff0c;使您能够部署和管理完整的 MySQL 集成高可用性解决方案。 说…

SOC模块LoRa-STM32WLE5有哪些值得关注

SoC 是片上系统的缩写&#xff0c;是一种集成芯片&#xff0c;集成了计算机或其他电子系统的所有或大部分组件。这些组件通常包括中央处理器 (CPU)、内存、输入/输出接口和辅助存储接口。包含数字、模拟、混合信号和通常的 RF 信号处理功能&#xff0c;具体取决于应用。片上系统…

优质快刊合集!内含TOP刊、CCF推荐期刊!编辑友好,极速发表!

【SciencePub学术】本期给大家推荐的是几本计算机快刊合集&#xff0c;内含优质TOP刊&#xff0c;现在版面已经所剩不多。且均属于我处目前进展很顺的期刊&#xff0c;大家可以放心投稿&#xff01; 计算机工程类 SCI&#xff08;TOP刊 / CCF-C类&#xff09; 【期刊简介】IF…

高斯过程的数学理解

目录 一、说明 二、初步&#xff1a;多元高斯分布 三、 线性回归模型与维度的诅咒 四、高斯过程的数学背景 五、高斯过程的应用&#xff1a;高斯过程回归 5.1 如何拟合和推理高斯过程模型 5.2 示例&#xff1a;一维数据的高斯过程模型 5.3 示例&#xff1a;多维数据的高斯过程模…