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

第N4周:中文文本分类

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍖 原作者:K同学啊

一、预备知识

中文文本分类和英文文本分类都是文本分类,为什么要单独拎出来个中文文本分类呢?
在自然语言处理(NLP)领域,中文处理和英文处理之间存在一些显著的区别,主要由于两种语言的语法、结构和表达方式的不同。以下是一些主要的区别:

  1. 分词(Tokenization)
    • 英文处理通常以空格和标点符号作为分词的天然界限,因此分词相对简单。
    • 中文处理则复杂得多,因为中文书写时词与词之间没有明显的分隔符。中文分词需要识别词语的边界,这通常涉及到复杂的算法和大量的词典资源。
  2. 词性标注(Part-of-Speech Tagging)
    • 英文的词性变化相对规则,例如通过词尾变化可以区分动词的时态和语态。
    • 中文词性标注需要识别每个词的词性,但由于中文词语没有明显的形态变化,这通常需要依赖于上下文信息。
  3. 句法分析(Parsing)
    • 英文的句法结构通常由明确的词汇形态变化和固定的词序来表达。
    • 中文句法结构更多地依赖于词序和功能词来表示,因此中文的句法分析需要考虑到这些因素。
  4. 语义分析(Semantic Analysis)
    • 英文的语义可以通过词汇的词根和词缀来推断。
    • 中文语义分析则需要更多地依赖于词汇的组合和上下文,因为中文词语往往具有多个意义。
  5. 机器翻译(Machine Translation)
    • 英文和其他印欧语系的语言之间由于语法结构相似,机器翻译相对容易。
    • 中文与英文之间的机器翻译更为复杂,需要处理语言结构的不对齐和文化差异。
  6. 语音和发音
    • 英文处理通常涉及到音标和发音规则。
    • 中文处理则涉及到声调,声调的变化会改变词语的意义。
  7. 上下文依赖性
    • 中文更加依赖于上下文来解析词语和句子的意义,因为一个词语可能有多个意思,具体意思需要根据上下文来确定。
    • 英文虽然也有多义词,但上下文依赖性通常没有中文那么强。
  8. 资源和工具
    • 英文NLP有大量的预训练模型、工具和资源可供使用。
    • 中文NLP虽然也有不少资源,但相比英文来说还是较少,尤其是在开源领域。

二、准备工作

1.导入必要的包,检查设备

import torch
import torch.nn as nn
import torchvision
from torchvision import transforms,datasets
import os,PIL,pathlib,warningswarnings.filterwarnings("ignore")
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
device

输出
device(type=‘cuda’)

2.导入数据

import pandas as pdtrain_data = pd.read_csv('./train.csv', sep='\t', header=None)
train_data.head()

输出
在这里插入图片描述

3.构建数据集迭代器

def coustom_data_iter(texts, labels):for x, y in zip(texts, labels):yield x,ytrain_iter = coustom_data_iter(train_data[0].values[:], train_data[1].values[:])

三、数据预处理

1.构建词典

from torchtext.data.utils import get_tokenizer
from torchtext.vocab import build_vocab_from_iterator
import jieba# 中文分词方法
tokenizer = jieba.lcutdef yield_tokens(data_iter):for text,_ in data_iter:yield tokenizer(text)vocab = build_vocab_from_iterator(yield_tokens(train_iter), specials=["<unk>"])
vocab.set_default_index(vocab["<unk>"]) # 设置默认索引,如果找不到单词,则会选择默认索引

输出

在这里插入图片描述

2.抽样检查

vocab(['你','和','他们','一起','上','空调','播放','农历'])

[18, 84, 1752, 444, 146, 43, 4, 44]

label_name = list(set(train_data[1].values[:]))
print(label_name) #打印标签以确认

[‘TVProgram-Play’, ‘Radio-Listen’, ‘Video-Play’, ‘HomeAppliance-Control’, ‘Weather-Query’, ‘Audio-Play’, ‘FilmTele-Play’, ‘Calendar-Query’, ‘Alarm-Update’, ‘Travel-Query’, ‘Music-Play’, ‘Other’]

lambda 表达式的语法为: lambda arguments: expression
其中 arguments 是函数的参数,可以有多个参数,用逗号分隔。expression 是一个表达式,它定义了函数的返回值。
text_pipeline函数:将原始文本数据转换为整数列表,使用之前构建的vocb词表和tokenizer分词器函数。具体来说,它接受一个字符串x作为输入,首先使用tokenizer将其分词,然后将每个词在vocb词表中的索引放入一个列表中返回。
label_pipeline函数:将原始标签数据转换为整数,并使用一个字符xx作为输入,并使用 label_name.index(x) 方法获取 x 在 label_name 列表中的索引作为输出。
lambda表达式通常用于数据预处理阶段,将文本数据转换为可以输入到模型中的索引序列

text_pipeline = lambda x: vocab(tokenizer(x))
label_pipeline = lambda x: label_name.index(x)
print(text_pipeline('我看见看和平精英上战神必备技巧的游戏视频'))
print(label_pipeline('Video-Play'))

[2, 9317, 13, 973, 1079, 146, 7724, 7574, 7793, 1, 186, 28]
2

3.生成数据批次和迭代器

from torch.utils.data import DataLoaderdef collate_batch(batch):label_list, text_list, offsets = [], [], [0]for (_text,_label) in batch:label_list.append(label_pipeline(_label))processed_text = torch.tensor(text_pipeline(_text), dtype=torch.int64)text_list.append(processed_text)offsets.append(processed_text.size(0))label_list = torch.tensor(label_list, dtype=torch.int64)text_list = torch.cat(text_list)offsets = torch.tensor(offsets[:-1]).cumsum(dim=0)  return text_list.to(device), label_list.to(device), offsets.to(device)dataloader = DataLoader(train_iter,batch_size=4,shuffle=False,collate_fn=collate_batch)

这段代码定义了一个collate_batch函数,用于将一批次的文本数据和标签数据整理成一个适合模型训练的格式,并创建一DataLoader对象来迭代处理这些批次数据。

  1. from torch.utils.data import DataLoader 这行代码从torch.utils.data模块中导入DataLoader类,DataLoader是一个迭代器,它允许我们以批量形式加载数据集,并提供数据混洗等功能。
  2. def collate_batch(batch): 这行代码定义了一个名为collate_batch的函数,它接受一个参数batch,这个batch是一个列表,包含了多个文本和标签对。
  3. label_list, text_list, offsets = [], [], [0] 这行代码初始化了三个列表:label_list用于存储标签,text_list用于存储处理后的文本数据,offsets用于存储每个文本数据的偏移量,用于后续的打包操作。
  4. for (_text,_label) in batch: 这个循环遍历batch中的每个元素,每个元素是一个包含文本和标签的元组。
  5. label_list.append(label_pipeline(_label)) 这行代码将每个标签通过label_pipeline函数处理后添加到label_list中。label_pipeline是一个未定义的函数,应该是用来将标签数据转换为模型可接受的格式。
  6. processed_text = torch.tensor(text_pipeline(_text), dtype=torch.int64) ,这行代码将每个文本通过text_pipeline函数处理后转换为PyTorch张量。text_pipeline是一个之前定义的lambda表达式,用于将文本转换为词汇索引列表。
  7. text_list.append(processed_text) 这行代码将处理后的文本张量添加到text_list中。
  8. offsets.append(processed_text.size(0)) 这行代码计算每个文本的长度,并将其作为偏移量添加到offsets列表中。
  9. label_list = torch.tensor(label_list, dtype=torch.int64) 这行代码将label_list列表转换为PyTorch张量。
  10. text_list = torch.cat(text_list): 这行代码使用torch.cat函数将text_list中的所有文本张量沿第一个维度(维度0)拼接成一个大的张量。
  11. offsets = torch.tensor(offsets[:-1]).cumsum(dim=0)这行代码将offsets列表转换为PyTorch张量,并计算其累加和(cumulative sum),这样每个偏移量就表示了对应文本在拼接后张量中的起始位置。
  12. return text_list.to(device), label_list.to(device), offsets.to(device) 这行代码将处理后的文本、标签和偏移量张量移动到定义的设备(如CPU或GPU)上,并作为函数的返回值。
  13. dataloader = DataLoader(train_iter, batch_size=4, shuffle=False, collate_fn=collate_batch)这行代码创建了一个DataLoader对象dataloader,它使用train_iter作为数据源,batch_size设置为4,shuffle设置为False表示不打乱数据顺序,collate_fn设置为collate_batch表示使用自定义的collate_batch函数来整理每个批次的数据。

四、模型构建

1.搭建模型

from torch import nnclass TextClassificationModel(nn.Module):def __init__(self, vocab_size, embed_dim, num_class):super(TextClassificationModel, self).__init__()self.embedding = nn.EmbeddingBag(vocab_size, embed_dim, sparse=False)self.fc = nn.Linear(embed_dim, num_class)self.init_weights()def init_weights(self):initrange = 0.5self.embedding.weight.data.uniform_(-initrange, initrange)  self.fc.weight.data.uniform_(-initrange, initrange)self.fc.bias.data.zero_() def forward(self, text, offsets):embedded = self.embedding(text, offsets)return self.fc(embedded)

这段代码定义了一个用于文本分类的神经网络模型TextClassificationModel,它是一个基于PyTorch的nn.Module

  1. from torch import nn 这行代码从torch库中导入nn模块,这个模块包含了构建神经网络所需的各种层和函数。
  2. class TextClassificationModel(nn.Module): 这行代码定义了一个名为TextClassificationModel的新类,它继承自nn.Module。这意味着这个类会拥有nn.Module的所有方法和属性,包括神经网络的前向传播方法。
  3. def __init__(self, vocab_size, embed_dim, num_class): 这行代码定义了类的初始化方法__init__,它接受三个参数:vocab_size(词汇表的大小),embed_dim(嵌入层的维度),num_class(分类任务的类别数)。
  4. super(TextClassificationModel, self).__init__() 这行代码调用父类nn.Module的初始化方法。
  5. self.embedding = nn.EmbeddingBag(vocab_size, embed_dim, sparse=False) 这行代码创建了一个nn.EmbeddingBag对象,它是一个特殊的嵌入层,可以处理可变长度的序列数据,并且会自动计算所有嵌入向量的平均值。sparse=False表示不使用稀疏权重。
  6. self.fc = nn.Linear(embed_dim, num_class) 这行代码创建了一个全连接层fc,它将嵌入层的输出映射到分类的类别数。
  7. self.init_weights() 这行代码调用了类中定义的init_weights方法,用于初始化模型的权重。
  8. def init_weights(self): 这行代码定义了init_weights方法,用于初始化嵌入层和全连接层的权重。
  9. initrange = 0.5 这行代码定义了初始化范围initrange,用于权重初始化。
  10. self.embedding.weight.data.uniform_(-initrange, initrange)这行代码将嵌入层的权重初始化为在-initrangeinitrange之间的均匀分布。

这段代码是在Pytorch框架下用于初始化神经网络的词嵌入层(embedding layer)权重的一种方法。这里使用了均匀分布的随机值来初始化权重,其作用如下:

  1. self.embedding.weight_data.uniform(-irange, irange): 这是神经网络中的词嵌入层(embedding layer)。词嵌入层的作用是将离散的单词表示为固定大小的连续向量(通常为整数索引)。这些向量捕捉了单词之间的语义关系,并作为网络的输入。
  2. self.embedding.weight_data: 它是词嵌入层的权重矩阵,它的形状为(vocab_size, embedding_dim),其中vocb_size是词汇表的大小,embedding_dim是维度参数。
  3. self.embedding.weight_data.uniform(-irange, irange): 这是一个原地操作(in-place operation),用于将权重矩阵的一个均匀分布进行初始化。均匀分布的分布范围由参数irange决定。
  4. uniform(-irange, irange), intrance(irange): 356度深度学习训练营 通过这种方式初始化词嵌入层的权重,可以使得模型在训练开始时具有一定程度的随机性,有助于避免梯度消失或梯度爆炸等问题。在训练过程中,这些权重将通过优化算法不断更新,以捕捉到更好的单词表示。
  1. self.fc.weight.data.uniform_(-initrange, initrange)这行代码将全连接层的权重初始化为在-initrangeinitrange之间的均匀分布。
  2. self.fc.bias.data.zero_()这行代码将全连接层的偏置初始化为0。
  3. def forward(self, text, offsets): :这行代码定义了模型的前向传播方法forward,它接受文本数据和偏移量作为输入。
  4. embedded = self.embedding(text, offsets) :这行代码使用嵌入层处理文本数据,offsets用于指定每个序列的开始位置。
  5. return self.fc(embedded):这行代码将嵌入层的输出传递给全连接层,并返回最终的分类结果。

2.初始化模型

num_class = len(label_name)
vocab_size = len(vocab)
em_size = 64
model = TextClassificationModel(vocab_size, em_size, num_class).to(device)

3.定义训练和评估的函数

import time
def train(dataloader):model.train()  # 切换为训练模式total_acc, train_loss, total_count = 0, 0, 0log_interval = 50start_time = time.time()for idx, (text, label, offsets) in enumerate(dataloader):predicted_label = model(text, offsets)optimizer.zero_grad()# grad属性归零loss = criterion(predicted_label, label)  # 计算网络输出和真实值之间的差距,label为真实值loss.backward()# 反向传播torch.nn.utils.clip_grad_norm(model.parameters(), 0.1)  # 梯度裁剪optimizer.step()  # 每一步自动更新# 记录acc与losstotal_acc += (predicted_label.argmax(1) == label).sum().item()train_loss += loss.item()total_count += label.size(0)if idx % log_interval == 0 and idx > 0:elapsed = time.time() - start_timeprint('| epoch {:4d} | {:4d}/{:4d} batches | ''train_acc {:4.3f} | train_loss {:4.5f} |'.format(epoch, idx, len(dataloader),total_acc / total_count, train_loss / total_count))total_acc, train_loss, total_count = 0, 0, 0start_time = time.time()def evaluate(dataloader):model.eval()  # 切换为测试模式total_acc, val_loss, total_count = 0, 0, 0with torch.no_grad():for idx, (text, label, offsets) in enumerate(dataloader):predicted_label = model(text, offsets)loss = criterion(predicted_label, label)  # 计算loss值# 记录测试数据total_acc += (predicted_label.argmax(1) == label).sum().item()val_loss += loss.item()total_count += label.size(0)return total_acc / total_count, val_loss / total_count
  1. import time :导入time模块,用于计算训练和评估过程中的时间。
  2. def train(dataloader): 定义一个名为train的函数,它接受一个名为dataloader的参数,这个参数应该是一个数据加载器,用于提供批量数据。
  3. model.train() 将模型设置为训练模式,这对于一些层(如dropout和batch normalization)是必要的。
  4. total_acc, train_loss, total_count = 0, 0, 0 初始化累加器,用于记录整个训练过程中的准确率、损失和总样本数。
  5. log_interval = 50 定义一个日志打印间隔,每50个批次打印一次训练状态。
  6. start_time = time.time() 记录训练开始的时间。
  7. for idx, (text, label, offsets) in enumerate(dataloader): 遍历dataloader中的每个批次,idx是批次的索引,(text, label, offsets)是每个批次的数据。
  8. predicted_label = model(text, offsets) 使用模型对输入的textoffsets进行前向传播,得到预测的标签。
  9. optimizer.zero_grad() 清空模型的梯度,为下一次反向传播做准备。
  10. loss = criterion(predicted_label, label)计算预测标签和真实标签之间的损失。
  11. loss.backward()对损失进行反向传播,计算模型参数的梯度。
  12. torch.nn.utils.clip_grad_norm(model.parameters(), 0.1)对模型的梯度进行裁剪,防止梯度爆炸。

torch.nn.utils.clip_grad_norm(model_parameters(), 1)是一个PyTorch函数,用于在训练神经网络时限制梯度的大小。这种操作被称为梯度裁剪(gradient clipping),可以防止梯度爆炸问题,从而提高神经网络的稳定性和性能。
在这个函数中:

  • model_parameters()表示模型的所有参数。对于一个神经网络,参数通常包括权重和偏置项。
  • 0.1是一个指定的阈值,表示梯度的最大范数(L2范数)。如果计算出的梯度范数超过这个阈值,梯度会被缩放,使其范数等于阈值。梯度裁剪的主要目的是防止梯度爆炸。梯度爆炸通常发生在训练深度神经网络时,尤其是在处理长序列数据的传播网络(RNN)中。当梯度爆炸时,参数可能会变得非常大,导致模型无法收敛或出现数值不稳定。通过限制梯度的大小,梯度裁剪有助于解决这些问题,使模型训练变得更加稳定。
  1. optimizer.step()使用优化器更新模型的参数。
  2. total_acc += (predicted_label.argmax(1) == label).sum().item()累加本次批次的准确率。
  3. train_loss += loss.item()累加本次批次的损失。
  4. total_count += label.size(0)累加本次批次的样本数。
  5. if idx % log_interval == 0 and idx > 0:如果达到日志打印间隔,打印当前的训练状态。
  6. elapsed = time.time() - start_time计算自训练开始以来的时间。
  7. print('| epoch {:4d} | {:4d}/{:4d} batches | train_acc {:4.3f} | train_loss {:4.5f} |'.format(...)打印训练进度、准确率和损失。
  8. total_acc, train_loss, total_count = 0, 0, 0重置累加器,为下一个训练周期做准备。
  9. start_time = time.time()重置开始时间,为下一个训练周期做准备。
  10. def evaluate(dataloader):定义一个名为evaluate的函数,用于评估模型的性能。
  11. model.eval()将模型设置为评估模式,这对于一些层(如dropout和batch normalization)是必要的。
  12. total_acc, val_loss, total_count = 0, 0, 0初始化累加器,用于记录整个评估过程中的准确率、损失和总样本数。
  13. with torch.no_grad():在这个上下文中,所有的计算都不会计算梯度,这样可以节省内存和计算资源。
  14. for idx, (text, label, offsets) in enumerate(dataloader): 遍历dataloader中的每个批次。
  15. predicted_label = model(text, offsets)使用模型进行前向传播,得到预测的标签。
  16. loss = criterion(predicted_label, label)计算预测标签和真实标签之间的损失。
  17. total_acc += (predicted_label.argmax(1) == label).sum().item()累加本次批次的准确率。
  18. val_loss += loss.item()累加本次批次的损失。
  19. total_count += label.size(0)累加本次批次的样本数。
  20. return total_acc / total_count, val_loss / total_count返回整个评估过程中的平均准确率和平均损失。 总的来说,train函数用于训练模型,而evaluate函数用于评估模型的性能。这两个函数都遍历数据加载器中的所有批次,并累加准确率和损失,最后打印或返回这些统计信息。

五、训练模型

1.拆分数据集并运行模型

from torch.utils.data.dataset import random_split
from torchtext.data.functional import to_map_style_dataset# 超参数
EPOCHS = 10  
LR = 5      
BATCH_SIZE = 32criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=LR)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, 1.0, gamma=0.1)
total_accu = None# 构建数据集
train_iter = coustom_data_iter(train_data[0].values[:], train_data[1].values[:])
train_dataset = to_map_style_dataset(train_iter)
split_train_, split_valid_= random_split(train_dataset, [int(len(train_dataset) * 0.8), int(len(train_dataset) * 0.2)])
train_dataloader = DataLoader(split_train_, batch_size=BATCH_SIZE, shuffle=True, collate_fn=collate_batch)
valid_dataloader = DataLoader(split_valid_, batch_size=BATCH_SIZE, shuffle=True, collate_fn=collate_batch)for epoch in range(1, EPOCHS + 1):epoch_start_time = time.time()train(train_dataloader)val_acc, val_loss = evaluate(valid_dataloader)# 获取当前的学习率lr = optimizer.state_dict()['param_groups'][0]['lr']if total_accu is not None and total_accu > val_acc:scheduler.step()else:total_accu = val_accprint('-' * 69)print('| epoch {:1} | time:{:4.2f} ''| valid_acc {:4.3f} | valid_loss {:4.3f} | lr {:6f} '.format(epoch, time.time() - epoch_start_time, val_acc, val_loss, lr))print('-' * 69)

torchtext.data.functional_map style dataset函数的作用是将一个迭代式的数据集(iterable-style dataset)转换为映射为索引的数据集(Map-style dataset)。这个转换使得我们可以通过索引(例如:整数)更方便地访问数据集中的元素。
在PyTorch中,数据集可以分为两种类型:Iterable-style和Map-style。Iterable-style数据集实现了一个迭代器方法,可以用于遍历数据集中的元素,但不支持通过索引访问。而Map-style数据集实现了getitem()和len()方法,可以直接通过索引访问特定元素,并能获取数据集的大小。
TorchText是PyTorch的一个扩展库,专注于处理文本数据。torchtext.data.functional_map_style dataset函数可以帮助我们将一个Iterable-style数据集转换为一个易于操作的Map-style数据集。这样,我们可以通过索引直接访问数据集中特定的样本,从而简化了训练、验证和测试过程中的数据处

在这里插入图片描述

test_acc, test_loss = evaluate(valid_dataloader)
print('模型准确率为:{:5.4f}'.format(test_acc))

模型准确率为:0.8971

2.测试数据

def predict(text, text_pipeline): with torch.no_grad():text = torch.tensor(text_pipeline(text))output = model(text, torch.tensor([0]))return output.argmax(1).item()
ex_text_str1 = "随便播放一首专辑阁楼里的佛里的歌"
ex_text_str2 = "还有双鸭山到淮阴的汽车票吗13号的"
model = model.to("cpu")
print("该文本的类别是:%s" % label_name[predict(ex_text_str1,text_pipeline)])
print("该文本的类别是:%s" % label_name[predict(ex_text_str2,text_pipeline)])

该文本的类别是:Music-Play
该文本的类别是:Travel-Query

相关文章:

第N4周:中文文本分类

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 一、预备知识 中文文本分类和英文文本分类都是文本分类&#xff0c;为什么要单独拎出来个中文文本分类呢&#xff1f; 在自然语言处理&#xff08;NLP&#x…...

【kubernetes】探索k8s集群的pod控制器详解(Deployment、StatefulSet、DaemonSet、Job、CronJob)

目录 一、Pod控制器及其功用 二、pod控制器有多种类型 2.1ReplicaSet 2.1.1ReplicaSet主要三个组件组成 2.2Deployment 2.3DaemonSet 2.4StatefulSet 2.5Job 2.6Cronjob 三、Pod与控制器之间的关系 3.1Deployment 3.2SatefulSet 3.2.1StatefulSet三个组件 3.2.2为…...

直接插入排序

#include <stdio.h>void insert_sort(int arr[], int n) {int i;int j;int tmp;for (i 1; i < n; i){tmp arr[i];j i - 1;// 将要插入的元素与数组中的元素比较&#xff08;从后向前比&#xff09; while (j > 0 && arr[j] > tmp){arr[j 1] arr[…...

esp32s3 nvs 存储过程中使用malloc和free函数的一点困惑

我的项目中&#xff0c;大量使用了malloc()和free()函数&#xff0c;在使用nvs存储之前没有出现问题。 esp32厂家nvs的blob存储的例程中&#xff0c;有使用malloc()和free()&#xff0c;我参照例程写了自己的blob存储函数f&#xff0c;一开始是可以正常使用的&#xff0c;后来…...

除visio以外的几款好用流程图绘制工具

流程图绘制软件在嵌入式软件开发中扮演着重要的角色&#xff0c;它们能够帮助用户清晰、直观地展示工作流程。以下是几款流行的流程图绘制软件及其特点的详细报告&#xff1a; 思维导图MindMaster MindMaster作为一款专业的思维导图软件&#xff0c;不仅具备强大的思维导图制作…...

CentOS 7 64位 常用命令

一、系统管理命令 systemctl start firewalld.service&#xff1a;启动防火墙服务 systemctl stop firewalld.service&#xff1a;停止防火墙服务 systemctl enable firewalld.service&#xff1a;设置防火墙服务开机自启 systemctl disable firewalld.service&#xff1a;禁止…...

ChatGPT-4o抢先体验

速度很快&#xff0c;结果很智能&#xff0c;支持多模态输入输出&#xff0c;感兴趣联系作者。 windows/linux/mac 客户端下载参考&#xff1a;https://github.com/lencx/Noi...

STM32实验之USART串口发送+接受数据(二进制/HEX/文本)

涉及三个实验&#xff1a; 1.USART串口发送和接收数据 我们使用的是将串口封装成为一个Serial.c模块.其中包含了 void Serial_Init(void);//串口初始化 void Serial_SendByte(uint8_t Byte);//串口发送一个字节 void Serial_SendArray(uint8_t *Array,uint16_t Length);//…...

网关(Gateway)- 内置过滤器工厂

官方文档&#xff1a;Spring Cloud Gateway 内置过滤器工厂 AddRequestHeaderGatewayFilterFactory 为请求添加Header Header的名称及值 配置说明 server:port: 8088 spring:application:name: api-gatewaycloud:nacos:discovery:server-addr: 127.0.0.1:8847username: nacos…...

电风扇如何实现跌倒断电保护功能

电风扇作为日常生活中常用的家电产品&#xff0c;为了提升安全性能&#xff0c;在设计上通常会考虑加入跌倒断电保护功能。其中&#xff0c;光电倾倒开关是实现跌倒断电保护功能的关键组件之一。 光电倾倒开关内置红外发光二极管和光敏接收器&#xff0c;其工作原理非常巧妙。…...

编译原理总结

编译器构成 1. 前端分析部分 1.1 词法分析 确定词性&#xff0c;输出为token序列 1.2 语法分析 识别短语 1.3 语义分析 分析短语在句子中的成分 IR中间代码生成 2. 机器无关代码优化 3. 后端综合部分 目标代码生成 机器相关代码优化 4. 其他 全局信息表 异常输出...

JavaScript:从基础到进阶的全面介绍

JavaScript&#xff1a;从基础到进阶的全面介绍 JavaScript&#xff08;简称JS&#xff09;是一种广泛用于Web开发的编程语言。它是一种轻量级的、解释型或即时编译的语言&#xff0c;具有函数优先的特点。JS最初是为了实现网页的动态效果而设计的&#xff0c;如今已发展成为前…...

linux指令-sed

sed 是一个流编辑器&#xff0c;用于对输入流&#xff08;或文件&#xff09;进行基本的文本转换。以下是 sed 命令的详细输出说明文档&#xff1a; 1. 基本语法 sed [OPTIONS]... [SCRIPT] [INPUTFILE...] OPTIONS&#xff1a;可选的命令行选项&#xff0c;如 -i 用于直接修…...

Docker部署青龙面板

青龙面板 文章目录 青龙面板介绍资源列表基础环境一、安装Docker二、安装Docker-Compose三、安装青龙面板3.1、拉取青龙&#xff08;whyour/qinglong&#xff09;镜像3.2、编写docker-compose文件3.3、检查语法启动容器 四、访问青龙面板五、映射本地部署的青龙面板至公网5.1、…...

【LeetCode】每日一题 2024_6_4 将元素分配到两个数组中 II(二分、离散化、树状数组)

文章目录 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01;题目&#xff1a;将元素分配到两个数组中 II题目描述代码与解题思路 每天进步一点点 LeetCode&#xff1f;启动&#xff01;&#xff01;&#xff01; 又有段时间没写每日一题的分享了&#xff0c;原本今…...

JAVA小案例-break练习,随机数,到88停止

JAVA小案例-break练习&#xff0c;随机数&#xff0c;到88停止 代码如下&#xff1a; public class Break {/*** break练习&#xff0c;随机数&#xff0c;到88停止* param args*/public static void main(String[] args) {int count0;//计数器System.out.println("Begi…...

C++第三方库【httplib】断点续传

什么是断点续传 上图是我们平时在浏览器下载文件的场景&#xff0c;下载的本质是数据的传输。当出现网络异常&#xff0c;浏览器异常&#xff0c;或者文件源的服务器异常&#xff0c;下载都可能会终止。而当异常解除后&#xff0c;重新下载文件&#xff0c;我们希望从上一次下载…...

[SaaS] AI+数据,tiktok选品,找达人,看广告数据

TK观察专访丨前阿里“鲁班”创始人用AIGC赋能TikTok获千万融资用AI数据做TikTokhttps://mp.weixin.qq.com/s/xp5UM3ROo48DK4jS9UBMuQ主要还是爬虫做数据的。 商家做内容&#xff1a;1.找达人拍内容&#xff0c;2.商家自己做原生自制内容&#xff0c;3.广告内容。 短视频&…...

A股冲高回落,金属、地产板块领跌,新股N汇成真首日暴涨753%

行情概述 AH股有色金属、教育及地产板块领跌&#xff0c;军工航天及半导体板块逆势走强&#xff1b;锂电池、创新药概念股也走强。创业板新股N汇成真首日暴涨753%&#xff0c;触发二次临停。 周三A股冲高回落&#xff0c;上证指数收跌0.83%&#xff0c;深成指跌0.8%&#xff…...

dns域名解析服务和bond网卡

目录 dns域名解析服务 一、DNS 1、定义 2、以www.baidu.com为例 3、域名体系结构 4、DNS解析使用的协议和端口 5、dns域名解析的过程 6、dns解析的优先级 二、如何实现域名解析 1、域名解析 2、bind配置文件位置 &#xff08;一&#xff09;正向解析 &#xff08;…...

视频生成框架EasyAnimate正式开源!

近期&#xff0c;Sora模型的热度持续上涨&#xff0c;社区中涌现了一些类Sora的开源项目&#xff0c;这些项目均基于Diffusion Transformer结构&#xff0c;使用Transformer结构取代了UNet作为扩散模型的基线&#xff0c;旨在生成更长、更高分辨率、且效果更好的视频。EasyAnim…...

【微机原理与汇编语言】并行接口8255实验

一、实验目的 掌握可编程并行接口芯片8255的工作原理及初始化方法掌握8255在实际应用中的硬件连接及编程应用 二、实验要求 根据实验室现有条件&#xff0c;针对实验任务&#xff0c;设计实验方案并进行实现。 三、实验内容 启动0#计数器&#xff0c;每计5个数&#xff08…...

Oracle表分区的基本使用

什么是表空间 是一个或多个数据文件的集合&#xff0c;所有的数据对象都存放在指定的表空间中&#xff0c;但主要存放的是表&#xff0c;所以称为表空间 什么是表分区 表分区就是把一张大数据的表&#xff0c;根据分区策略进行分区&#xff0c;分区设置完成之后&#xff0c;…...

6月5号作业

设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数 ​ #include <iostream>using namespace std; class Slu { priv…...

中继器、集线器、网桥、交换机、路由器和网关

目录 前言一、中继器、集线器1.1 中继器1.2 集线器 二、网桥、交换机2.1 网桥2.1.1 认识网桥2.1.2 网桥的工作原理2.1.3 生成树网桥 2.2 交换机2.2.1 交换机的特征2.2.2 交换机的交换模式2.2.3 交换机的功能 三、路由器、网关3.1 路由器的介绍3.2 路由器的工作过程3.2.1 前置知…...

揭秘相似矩阵:机器学习算法中的隐形“纽带”

在机器学习领域&#xff0c;数据的处理和分析至关重要。如何有效地从复杂的数据集中提取有价值的信息&#xff0c;是每一个机器学习研究者都在努力探索的问题。相似矩阵&#xff0c;作为衡量数据之间相似性的数学工具&#xff0c;在机器学习算法中扮演着不可或缺的角色。 相似矩…...

攻防世界—webbaby详解

1.ssrf注入漏洞 ssrf&#xff08;服务端请求伪造&#xff09;是一种安全漏洞&#xff0c;攻击者通过该漏洞向受害服务器发出伪造的请求&#xff0c;从而访问并获取服务器上的资源&#xff0c;常见的ssrf攻击场景包括访问内部网络的服务&#xff0c;执行本地文件系统命令&#…...

MySQL中:cmd下输入命令mysql -uroot -p 连接数据库错误

目录 问题cmd下输入命令mysql -uroot -p错误 待续、更新中 问题 cmd下输入命令mysql -uroot -p错误 解决 配置环境变量&#xff1a;高级系统设置——环境变量——系统变量——path编辑——新建——MySQL.exe文件路径&#xff08;如下图所示&#xff09; phpstudy2018软件下&am…...

【开发利器】使用OpenCV算子工作流高效开发

学习《人工智能应用软件开发》&#xff0c;学会所有OpenCV技能就这么简单&#xff01; 做真正的OpenCV开发者&#xff0c;从入门到入职&#xff0c;一步到位&#xff01; OpenCV实验大师Python SDK 基于OpenCV实验大师v1.02版本提供的Python SDK 实现工作流导出与第三方应用集…...

基础数学-求平方根(easy)

一、问题描述 二、实现思路 1.题目不能直接调用Math.sqrt(x) 2.这个题目可以使用二分法来缩小返回值范围 所以我们在left<right时 使 mid (leftright)/21 当mid*mid>x时&#xff0c;说明right范围过大&#xff0c;rightright-1 当mid*mid<x时&#xff0c;说明left范…...

可以做翻译的网站/零食软文范例300字

WebStorm智能 JavaScript IDE WebStorm 是一个现代 JavaScript 生态系统。它包括智能代码完成、动态错误检测、强大的导航和 JavaScript、TypeScript、样式表语言和所有流行框架的重构。 WebStorm 功能 智能编码辅助- WebStorm 为您提供 JavaScript 和编译成 JavaScript 语言、…...

网站开发与维护难吗/怎样推广自己的app

前言通常我们都是使用xtrabackup工具来备份数据库&#xff0c;它是一个专业的备份工具&#xff0c;先来简单介绍下它。Xtrabackuppercona提供的mysql数据库备份工具&#xff0c;惟一开源的能够对innodb和xtradb数据库&#xff0c;它的增量备份不是基于二进制日志文件来还原数据…...

济南美赞网站建设公司/成都互联网公司排名

控制流平坦化是一种JavaScript代码混淆技术&#xff0c;其目的是增加代码的复杂度以防止恶意代码分析和反编译。 该技术通过重新组织代码中的控制流语句&#xff08;如if、for、while语句等&#xff09;来增加代码的复杂性。具体而言&#xff0c;它会将这些语句拆分成多个小的…...

电子商务网站建设项目规划书/郴州seo外包

转自&#xff1a; 1. v-text 作用 &#xff1a; 操作元素中的纯文本 快捷方式 &#xff1a; {{}} 栗子1 简写形式&#xff1a;将v-text""换成{{}} <div id"app">{{ message }} </div> var app new Vue({el : #app, data : { message : hello …...

成都哪里有网络营销活动/长沙的seo网络公司

https://github.com/ethereumjs/ethereumjs-vm 其实这就是怎么自己使用该模块来生成一个类似geth客户端的以太坊虚拟机&#xff0c;然后进行各类区块链操作 SYNOPSIS概要 Implements Ethereums VM in Javascript.用Javascript实现以太坊虚拟机 Fork Support分支支持 Starting w…...

网站开发需要看相关书籍/网页制作步骤

360Webscan&#xff0c;云探安全监测系统是遵循360在总结多年市场经验和客户需求基础上提出的一款面向党政军、金融、教育和互联网用户的基于SaaS的网站应用安全监测服务产品&#xff0c;依赖于360安全大脑&#xff0c;以及360在搜索、终端 安全、网站安全等方面积累的数亿用户…...