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

基于DenseNet网络实现Cifar-10数据集分类

目录

  • 1.作者介绍
  • 2.Cifar-10数据集介绍
  • 3.Densenet网络模型
    • 3.1网络背景
    • 3.2网络结构
      • 3.2.1Dense Block
      • 3.2.2Bottleneck层
      • 3.2.3Transition层
      • 3.2.4压缩
  • 4.代码实现
    • 4.1数据加载
    • 4.2建立 DenseNet 网络模型
    • 4.3模型训练
    • 4.4训练代码
    • 4.5测试代码
  • 参考链接

1.作者介绍

吴思雨,女,西安工程大学电子信息学院,2023级研究生
研究方向:机器视觉与人工智能
电子邮件:2879944563@qq.com
陈梦丹,女,西安工程大学电子信息学院,2022级研究生
研究方向:机器视觉与人工智能
电子邮件:1169738496@qq.com

2.Cifar-10数据集介绍

Cifar-10数据集由10个类别的60000张32x32彩色图像组成,每个类别有6000张图像。有50000个训练图像和10000个测试图像。
数据集分为五个训练批次和一个测试批次,每个批次有10000张图像。测试批次恰好包含从每个类别中随机选择的1000幅图像。训练批包含按随机顺序排列的剩余图像,但某些训练批可能包含来自一个类的图像多于另一类的图像。在它们之间,训练批次恰好包含每个类的5000个图像。
以下是数据集中的类,以及每个类的10张随机图像:
在这里插入图片描述
这些类是完全不同的。汽车和卡车之间没有重叠。“汽车”包括轿车,SUV,诸如此类的东西。“卡车”只包括大卡车。两者都不包括皮卡。
Cifar-10官网下载链接:http://www.cs.toronto.edu/~kriz/cifar.html
Cifar-10数据集有三个版本,本文采用的是第一个版本:Cifar-10 python version。
在这里插入图片描述

3.Densenet网络模型

3.1网络背景

DenseNet(《Densely connected convolutional networks》) 斩获CVPR 2017的最佳论文奖,它的基本思路与ResNet一致,但是在参数和计算成本更少的情形下实现了比ResNet更优的性能,它建立的是前面所有层与后面层的密集连接(即相加变连结),它的名称也是由此而来。
DenseNet的另一大特色是通过特征在通道上的连接来实现特征重用。这些特点让DenseNet的参数量和计算成本都变得更少了,效果也更好了。ResNet解决了深层网络梯度消失问题,它是从深度方向研究的。宽度方向是GoogleNet的Inception。而DenseNet是从feature入手,通过对feature的极致利用能达到更好的效果和减少参数。

3.2网络结构

在这里插入图片描述
上图是一个包含5layer的Dense Block。可以看出Dense Block互相连接所有的层,具体来说就是每一层的输入都来自于它前面所有层的特征图,每一层的输出均会直接连接到它后面所有层的输入。所以对于一个L层的DenseBlock,共包含
L*(L+1)/2 个连接,如果是ResNet的话则为(L-1)2+1。从这里可以看出:相比ResNet,Dense Block采用密集连接。而且Dense Block是直接concat来自不同层的特征图,这可以实现特征重用,提升效率,这一特点是DenseNet与ResNet最主要的区别。
Dense Net的网络结构主要由
Dense Block和Transition*组成;如下图所示。一个DenseNet中有3个或4个DenseBlock。而一个DenseBlock中也会有多个Bottleneck layers。最后的DenseBlock之后是一个global AvgPooling层,然后送入一个softmax分类器,得到每个类别所属分数。
在这里插入图片描述

3.2.1Dense Block

1.Dense connective
为了进一步改善层之间的信息流,提出了一种不同的连接模式:引入了从任何层到所有后续层的直接连接。因此,第l层接收所有先前层的特征图:X0,X1,…Xl-1作为输入:在这里插入图片描述

2.Composite function—复合功能
将 Hℓ(⋅)定义为三个连续运算的复合函数:批量归一化(BN),然后是 ReLU 和一个 3×3的卷积(Conv)。
在这里插入图片描述
在这里插入图片描述其中,ℓ表示第几层;将第ℓ 层的输出表示为Xℓ; [X0,X1,…]表示将第0,1…(ℓ-1)层的特征图进行组合。将非线性变换Hℓ(⋅)定义为三个连续操作的符合函数:BN+ReLU+一个3×3的Conv。
3.Growth rate—增长率
k–DenseNet中的growth rate(增长率),这是一个超参数。一般情况下使用较小的k,就可以得到较佳的性能。假定输入层的特征图的通道数为k0,那么L层输入的channel数为 k0+k*(L-1),因此随着层数增加,尽管k设定得较小,DenseBlock中每一层输入依旧会越来越多。

3.2.2Bottleneck层

尽管每一层仅生成k个输出特征图,但通常具有更多输入。可以在每次3×3卷积之前引入1×1卷积作为瓶颈层,以减少输入特征图的数量,从而提高计算效率。并且将具有此类瓶颈层的网络称为DenseNet-B,瓶颈层如下图所示。
在这里插入图片描述

3.2.3Transition层

当特征图的大小改变时,不能直接连接。然而,卷积网络的重要组成部分是降低特征图大小的下采样层。为了便于在体系结构中进行下采样,将网络划分为多个密集连接的密集块。如下图所示,将块之间的层称为过渡层,它们进行卷积和池化。实验中使用的过渡层包括批处理规范化层和1×1卷积层,然后是一个 2×2的平均池化层。
在这里插入图片描述

3.2.4压缩

为了进一步提高模型的紧凑性,可以减少转换层的特征图数量。引入一个压缩因子θ(0 < θ ≤1),当θ=1时转换层的输入和输出特征数不变,也就是经过转换层后特征数不变;当θ <1时,输入特征图数为m时,输出为⌊θm⌋。将θ<1的DenseNet称为DenseNet-C (在实验中设置θ=0.5)。

4.代码实现

4.1数据加载

CIFAR 数据集可以从官网下载后使用,也可以使用 datasets 类自动加载(如果本地路径没有该文件则自动下载)。大型训练数据集不能一次性加载全部样本来训练,可以使用 Dataloader 类自动加载数据。Dataloader 是一个迭代器,基本功能是传入一个 Dataset 对象,根据参数 batch_size 生成一个 batch 的数据。

4.2建立 DenseNet 网络模型

建立一个 DenseNet 网络模型进行训练,包括三个步骤:
1.实例化 DenseNet 模型对象;
2.设置训练的损失函数;
3.设置训练的优化器。

4.3模型训练

在模型训练过程中,可以使用验证集数据评价训练过程中的模型精度,以便控制训练过程。模型验证就是用验证数据进行模型推理,前向计算得到模型输出,但不反向计算模型误差,因此需要设置 torch.no_grad()。

4.4训练代码

# 经典模型: 使用 DenseNet 模型 进行 CIFAR10 图像分类,使用 Torchvision 预定义模型
# 使用 torchvision.models.densenet.DenseNet 类
# Copyright: youcans@qq.com
# Crated: Huang Shan, 2023/05/20# _*_coding:utf-8_*_
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
from torchvision import transforms, models
from matplotlib import pyplot as plt
import numpy as np# 优化结果写入数据文件
import pandas as pd
def WriteDataFile(epoch_list, loss_list, accu_list, filepath):# print("def WriteDataFile()")optRecord = {"epoch": epoch_list,"train_loss": loss_list,"accuracy": accu_list}dfRecord = pd.DataFrame(optRecord)dfRecord.to_csv(filepath, index=False, encoding="utf_8_sig")print("写入数据文件: %s 完成。" % filepath)returnif __name__ == '__main__':device = torch.device("cuda" if torch.cuda.is_available() else "cpu")print(device)# (1)[0,1]的PILImage 转换为[-1,1]的Tensortransform_train = transforms.Compose([transforms.RandomHorizontalFlip(),  # 随机水平翻转transforms.RandomRotation(10),  # 随机旋转transforms.RandomAffine(0, shear=10, scale=(0.8, 1.2)),transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2),transforms.Resize((32, 32)),  # 图像大小调整为 (w,h)=(3232)transforms.ToTensor(),  # 将图像转换为张量 Tensortransforms.Normalize((0.4914, 0.4822, 0.4465), (0.247, 0.243, 0.261))])# 测试集不需要进行数据增强transform = transforms.Compose([transforms.Resize((32, 32)),  # 图像大小调整为 (w,h)=(3232)transforms.ToTensor(),  # 将图像转换为张量 Tensortransforms.Normalize((0.4914, 0.4822, 0.4465), (0.247, 0.243, 0.261))])# (2) 加载 CIFAR10 数据集batchsize = 128# 加载 CIFAR10 数据集, 如果 root 路径加载失败, 则自动在线下载# 加载 CIFAR10 训练数据集, 50000张训练图片train_set = torchvision.datasets.CIFAR10(root='', train=True,download=True, transform=transform_train)train_loader = torch.utils.data.DataLoader(train_set, batch_size=batchsize)# 加载 CIFAR10 验证数据集, 10000张验证图片test_set = torchvision.datasets.CIFAR10(root='', train=False,download=True, transform=transform)test_loader = torch.utils.data.DataLoader(test_set, batch_size=1000)# 创建生成器,用 next 获取一个批次的数据valid_data_iter = iter(test_loader)  # _SingleProcessDataLoaderIter 对象valid_images, valid_labels = next(valid_data_iter)  # images: [batch,3,224,224], labels: [batch]valid_size = valid_labels.size(0)  # 验证数据集大小,batchprint(valid_images.shape, valid_labels.shape)# 定义类别名称,CIFAR10 数据集的 10个类别classes = ('plane', 'car', 'bird', 'cat', 'deer','dog', 'frog', 'horse', 'ship', 'truck')# (3) 从 torchvision.model 加载预定义模型 DenseNet (不加载模型权值)model = models.DenseNet(num_init_features=32, num_classes=10)  # 实例化 DenseNet 模型类model.to(device)  # 将网络分配到指定的 device中# print(model)# 定义损失函数和优化器criterion = nn.CrossEntropyLoss()  # 定义损失函数 CrossEntropyoptimizer = torch.optim.SGD(model.parameters(), momentum=0.8, lr=0.01)  # 定义优化器 SGD# (4) 训练 DenseNet 网络模型epoch_list = []  # 记录训练轮次loss_list = []  # 记录训练集的损失值accu_list = []  # 记录验证集的准确率num_epochs = 99 # 训练轮次for epoch in range(num_epochs):  # 训练轮次 epochrunning_loss = 0.0  # 每个轮次的累加损失值清零for step, data in enumerate(train_loader, start=0):  # 迭代器加载数据optimizer.zero_grad()  # 损失梯度清零inputs, labels = data  # inputs: [batch,3,224,224] labels: [batch]outputs = model(inputs.to(device))  # 正向传播loss = criterion(outputs, labels.to(device))  # 计算损失函数loss.backward()  # 反向传播optimizer.step()  # 参数更新# 累加训练损失值running_loss += loss.item()# print("\t epoch {}, step {}: loss = {:.4f}".format(epoch, step, loss.item()))if step%100==99:  # 每 100 个 step 打印一次训练信息print("\t epoch {}, step {}: loss = {:.4f}".format(epoch, step, loss.item()))# 计算每个轮次的验证集准确率with torch.no_grad():  # 验证过程, 不计算损失函数梯度outputs_valid = model(valid_images.to(device))  # 模型对验证集进行推理, [batch, 10]pred_labels = torch.max(outputs_valid, dim=1)[1]  # 预测类别, [batch]accuracy = torch.eq(pred_labels, valid_labels.to(device)).sum().item() / valid_size * 100  # 计算准确率print("Epoch {}: train loss={:.4f}, accuracy={:.2f}%".format(epoch, running_loss, accuracy))# 记录训练过程的统计数据epoch_list.append(epoch)  # 记录迭代次数loss_list.append(running_loss)  # 记录训练集的损失函数accu_list.append(accuracy)  # 记录验证集的准确率# 训练结果可视化plt.figure(figsize=(11, 5))plt.suptitle("DenseNet Model in CIFAR10")plt.subplot(121), plt.title("Train loss")plt.plot(epoch_list, loss_list)plt.xlabel('epoch'), plt.ylabel('loss')plt.subplot(122), plt.title("Valid accuracy")plt.plot(epoch_list, accu_list)plt.xlabel('epoch'), plt.ylabel('accuracy')plt.show()# 保存图像文件plt.savefig('/data/Users/wusy/myProject/efficient_densenet_pytorch-master/images')print("Plot saved to /data/Users/wusy/myProject/efficient_densenet_pytorch-master/images")# (5) 保存 DenseNet 网络模型save_path = "/data/Users/wusy/myProject/efficient_densenet_pytorch-master/dir1"#model_cpu = model.cpu()  # 将模型移动到 CPUmodel_path = save_path + ".pth"  # 模型文件路径torch.save(model.state_dict(), model_path)  # 保存模型权值# 优化结果写入数据文件result_path = save_path + ".csv"  # 优化结果文件路径WriteDataFile(epoch_list, loss_list, accu_list, result_path)

经过 20 轮左右的训练,使用验证集中的 1000 张图片进行验证,模型准确率达到 80%。继续训练可以进一步降低训练损失函数值,经过 100轮左右的训练验证集的准确率保持在 80%左右。
在这里插入图片描述## 4.4测试阶段
使用加载的 DenseNet 模型,输入新的图片进行模型推理,可以由模型输出结果确定输入图片所属的类别。从测试集中提取几张图片,或者读取图像文件,进行模型推理,获得图片的分类类别。在提取图片或读取文件时,要注意对图片格式和图片大小进行适当的转换。
从测试集中提取图片,结果如下:
在这里插入图片描述
读取图像文件,结果如下
在这里插入图片描述

4.5测试代码

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
from torchvision import transforms, models
from matplotlib import pyplot as plt
import numpy as npdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")  # 检测并指定设备if __name__ == '__main__':device = torch.device("cuda" if torch.cuda.is_available() else "cpu")print(device)# (1)[0,1]的PILImage 转换为[-1,1]的Tensortransform_train = transforms.Compose([transforms.RandomHorizontalFlip(),  # 随机水平翻转transforms.RandomRotation(10),  # 随机旋转transforms.RandomAffine(0, shear=10, scale=(0.8, 1.2)),transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2),transforms.Resize((32, 32)),  # 图像大小调整为 (w,h)=(3232)transforms.ToTensor(),  # 将图像转换为张量 Tensortransforms.Normalize((0.4914, 0.4822, 0.4465), (0.247, 0.243, 0.261))])# 测试集不需要进行数据增强transform = transforms.Compose([transforms.Resize((32, 32)),  # 图像大小调整为 (w,h)=(3232)transforms.ToTensor(),  # 将图像转换为张量 Tensortransforms.Normalize((0.4914, 0.4822, 0.4465), (0.247, 0.243, 0.261))])# (2) 加载 CIFAR10 数据集batchsize = 128# 加载 CIFAR10 数据集, 如果 root 路径加载失败, 则自动在线下载# 加载 CIFAR10 训练数据集, 50000张训练图片# 加载 CIFAR10 验证数据集, 10000张验证图片test_set = torchvision.datasets.CIFAR10(root='/cifar-10-python.tar.gz', train=False,download=True, transform=transform)test_loader = torch.utils.data.DataLoader(test_set, batch_size=1000)# 创建生成器,用 next 获取一个批次的数据valid_data_iter = iter(test_loader)  # _SingleProcessDataLoaderIter 对象valid_images, valid_labels = next(valid_data_iter)  # images: [batch,3,224,224], labels: [batch]valid_size = valid_labels.size(0)  # 验证数据集大小,batchprint(valid_images.shape, valid_labels.shape)# 定义类别名称,CIFAR10 数据集的 10个类别classes = ('plane', 'car', 'bird', 'cat', 'deer','dog', 'frog', 'horse', 'ship', 'truck')# (3) 从 torchvision.model 加载预定义模型 DenseNet (不加载模型权值)model = models.DenseNet(num_init_features=32, num_classes=10)  # 实例化 DenseNet 模型类model.to(device)  # 将网络分配到指定的 device中# print(model)# 定义损失函数和优化器criterion = nn.CrossEntropyLoss()  # 定义损失函数 CrossEntropyoptimizer = torch.optim.SGD(model.parameters(), momentum=0.8, lr=0.01)  # 定义优化器 SGD# 加载 DenseNet 预训练模型# model = DenseNet(num_classes=10)  # 实例化 DenseNet 网络模型model = models.DenseNet(num_init_features=32, num_classes=10)  # 实例化 DenseNet 模型类model.to(device)  # 将网络分配到指定的device中model_path = '/dir.pth'model.load_state_dict(torch.load(model_path))model.eval()  # 模型推理模式# 模型检测
correct = 0
total = 0
for data in test_loader:  # 迭代器加载测试数据集imgs, labels = data  # torch.Size([batch,3,32,32) torch.Size([batch])# print(imgs.shape, labels.shape)outputs = model(imgs.to(device))  # 正向传播, 模型推理, [batch, 10]labels_pred = torch.max(outputs, dim=1)[1]  # 模型预测的类别 [batch]# _, labels_pred = torch.max(outputs.data, 1)total += labels.size(0)correct += torch.eq(labels_pred, labels.to(device)).sum().item()
accuracy = 100. * correct / total
print("Test samples: {}".format(total))
print("Test accuracy={:.2f}%".format(accuracy))# 提取测试集图片进行模型推理
batch = 8  # 批次大小
data_set = torchvision.datasets.CIFAR10(root='/cifar-10-python.tar.gz', train=False, download=True, transform=None)
plt.figure(figsize=(9, 6))
for i in range(batch):imgPIL = data_set[i][0]  # 提取 PIL 图片label = data_set[i][1]  # 提取 图片标签# 预处理/模型推理/后处理imgTrans = transform(imgPIL)  # 预处理变换, torch.Size([3,32,32])imgBatch = torch.unsqueeze(imgTrans, 0)  # 转为批处理,torch.Size([batch=1,3,32,32])outputs = model(imgBatch.to(device))  # 模型推理, 返回 [batch=1, 10]indexes = torch.max(outputs, dim=1)[1]  # 注意 [batch=1], device = 'deviceindex = indexes[0].item()  # 预测类别,整数# 绘制第 i 张图片imgNP = np.array(imgPIL)  # PIL -> Numpyout_text = "label:{}/model:{}".format(classes[label], classes[index])plt.subplot(2, 4, i+1)plt.imshow(imgNP)plt.title(out_text)plt.axis('off')
plt.tight_layout()
plt.show()
plt.savefig('/images1')# 读取图像文件进行模型推理
from PIL import Image
filePath = ''  # 数据文件的地址和文件名
imgPIL = Image.open(filePath)  # PIL 读取图像文件, <class 'PIL.Image.Image'># 预处理/模型推理/后处理
imgTrans = transform(imgPIL)  # 预处理变换, torch.Size([3, 224, 224])
imgBatch = torch.unsqueeze(imgTrans, 0)  # 转为批处理,torch.Size([batch=1, 3, 224, 224])
outputs = model(imgBatch.to(device))  # 模型推理, 返回 [batch=1, 10]
indexes = torch.max(outputs, dim=1)[1]  # 注意 [batch=1], device = 'device
percentages = nn.functional.softmax(outputs, dim=1)[0] * 100
index = indexes[0].item()  # 预测类别,整数
percent = percentages[index].item()  # 预测类别的概率,浮点数# 绘制第 i 张图片
imgNP = np.array(imgPIL)  # PIL -> Numpy
out_text = "Prediction:{}, {}, {:.2f}%".format(index, classes[index], percent)
print(out_text)
plt.imshow(imgNP)
plt.title(out_text)
plt.axis('off')
plt.tight_layout()
# 保存图像到指定路径
output_image_path = '/prediction_result.jpg'
plt.savefig(output_image_path, bbox_inches='tight', pad_inches=0)
plt.show()

参考链接

[1]DenseNet 模型-CIFAR10图像分类: http://t.csdnimg.cn/InzLt
[2]经典神经网络论文超详细解读: http://t.csdnimg.cn/jVmaw

相关文章:

基于DenseNet网络实现Cifar-10数据集分类

目录 1.作者介绍2.Cifar-10数据集介绍3.Densenet网络模型3.1网络背景3.2网络结构3.2.1Dense Block3.2.2Bottleneck层3.2.3Transition层3.2.4压缩 4.代码实现4.1数据加载4.2建立 DenseNet 网络模型4.3模型训练4.4训练代码4.5测试代码 参考链接 1.作者介绍 吴思雨&#xff0c;女…...

我的“工具”库

#使用到的工具# { 网页版的VScode&#xff1a; www.vscode.dev} {网页版JSON文件编辑器&#xff1a; JSON Editor Online: edit JSON, format JSON, query JSON &#xff5d; {网页版XML文件编辑器: Best Online XML Viewer, XML Formatter, XML Editor, Analyser, Be…...

Pytorch常用函数用法归纳:Tensor张量之间的计算

1.torch.add() (1)函数原型: torch.add(input, other, alpha, out) (2)参数说明: 参数名称参数类型参数说明inputtorch.Tensor表示参与运算的第一个输入Tensor张量othertorch.Tensor或者Number表示参与运算的第二个输入Tensor张量或标量alphaNumber, optional一个可选的缩放…...

小公司要求真高

大家好&#xff0c;我是白露啊。 最近看到一个爽文帖&#xff0c;标题就是——“小公司要求真高”。 事情是这样的&#xff0c;一家的小公司在拿到简历之后&#xff0c;HR直接对楼主说&#xff1a;“你不合适&#xff0c;简历不行。” 言外之意就是嫌弃简历单薄&#xff0c;看…...

进阶篇02——索引

概述 结构 B树索引 在这里推荐一个可以将个各种数据结构可视化的网站&#xff1a;数据结构可视化 哈希索引 相关的一个面试题 分类 聚集索引和二级索引&#xff08;非聚集索引&#xff09; 思考题&#xff1a;索引思考题 创建索引语法 如果一个索引关联多个字段&#xff…...

三:SpringBoot的helloworld和使用Springboot的优点以及快速创建Springboot应用

三&#xff1a;SpringBoot的helloworld和使用Springboot的优点以及快速创建Springboot应用 一&#xff1a;HelloWorld [我们创建的是maven项目或者直接创建一个Spring] 1.1&#xff1a;创建一个maven 项目&#xff08;1】&#xff1a;需要自己手动写一个SpringBoot 的启动类同…...

网络仿真方法综述

目录 1. 引言 2.仿真器介绍 2.1 NS-2 2.2 NS-3 2.3 OPNET 2.4 GNS3 3.仿真对比 4.结论 参考文献 1. 引言 网络仿真是指使用计算机模拟网络系统的行为和性能的过程。在网络仿真中&#xff0c;可以建立一个虚拟的网络环境&#xff0c;并通过模拟各种网络设备、协议和应用程…...

Android-Q升级-Camera记录

目录 代码环境 建立Android Q使用的camera仓 Camera底层适配 camx 原生接口变化 其他编译问题 chi-cdk 数据类型不匹配 case未加break的报错 libalRnBRT_GL_GBWRAPPER链接问题 vidhance编译错误 libarcsat链接问题 vendor/qcom/proprietary prebuilt_HY11 调试cam…...

Android studio如何导入项目

打开解压好的安装包 找到build.gradle文件 打开查看gradle版本 下载对应的gradle版本Index of /gradle/&#xff08;镜像网站&#xff09; 下载all的对应压缩包 配置gradle的环境变量 新建GRADLE_HOME 将GRADLE_HOME加入到path中 将项目在Android studio中打开进行配置 将gr…...

PHP实现一个简单的接口签名方法以及思路分析

文章目录 签名生成说明签名生成示例代码签名校验示例代码 签名生成说明 B项目需要调用A项目的接口&#xff0c;由A项目为B项目分配 AccessKey 和 SecretKey&#xff0c;用于接口加密&#xff0c;确保不易被穷举&#xff0c;生成算法不易被猜测。 最终需要确保包含签名的参数只…...

StartAI”梦想合伙人 ”招募计划

我们正火热招募AI设计师产品合伙人&#xff01;如果你对AI技术充满好奇&#xff0c;对设计有着独特的见解和热情&#xff0c;亦或者你想在日常的设计工作中提高效率&#xff0c;无论你是电商设计师、UI设计师、建筑师、插画师等其他各类设计领域的人才。那么这就是你不容错过的…...

记录:podman安装redis

Linux系统上安装redis&#xff1a; podman pull redis # 拉取最新的redis版本 podman images # 查看所有本地的镜像&#xff0c;包括刚拉取的redis镜像mkdir -p /etc/redis/conf /etc/redis/data # 创建2个目录文件&#xff0c;保存redis的数据和配置文件 tou…...

TrinityCore启动报错: MySQL library version (8.0.37 id 80037) does not match

TrinityCore启动的时候报错&#xff1a; TrinityCore/src/server/database/Database/DatabaseWorkerPool.cpp:73 in DatabaseWorkerPool FATAL ERROR: Used MySQL library version (8.0.37 id 80037) does not match the version id used to compile TrinityCore (id 80036). S…...

代码随想三刷字符串篇

代码随想三刷字符串篇 344. 反转字符串题目代码541. 反转字符串 II题目代码54. 替换数字(第八期模拟笔试)题目代码151. 反转字符串中的单词题目代码55. 右旋字符串(第八期模拟笔试题目代码28. 实现 strStr()题目代码459.重复的子字符串题目代码344. 反转字符串 题目 链接 …...

华为支持手指关节手势的原理

华为的指关节手势有指关节截屏、指关节录屏、指关节区域截屏、指关节分屏等。该技术的实现是靠触控结合了其他一些传感器实现的。 华为的专利&#xff1a; 一种手势控制方法、装置、终端设备和存储介质——华为技术有限公司 专利中提到以往终端设备对于手势的识别都是基于位置和…...

Flink的简单学习五

一 动态表与连续查询 1.1 动态表 1.是flink的支持流数据Table API 和SQL的核心概念。动态表随时间的变化而变化 2.在流上面定义的表在内部是没有数据的 1.2 连续查询 1.永远不会停止&#xff0c;结果是一张动态表 二 Flink SQL 2.1 sql行 1.先启动启动flink集群 yarn-see…...

C++|哈希应用->位图

目录 一、概念 1.1原理分析&#xff1a; 1.2效率分析&#xff1a; 二、模拟实现 2.1位图框架初始化空间 2.2映射 2.3清零 2.4判断 2.5测试代码 三、位图扩展应用 一、概念 位图&#xff0c;本质上也是一个数组&#xff0c;通过哈希思想构造的一种数据结构&#xff0c…...

Rust 实战丨SSE(Server-Sent Events)

&#x1f4cc; SSE&#xff08;Server-Sent Events&#xff09;是一种允许服务器向客户端浏览器推送信息的技术。它是 HTML5 的一部分&#xff0c;专门用于建立一个单向的从服务器到客户端的通信连接。SSE的使用场景非常广泛&#xff0c;包括实时消息推送、实时通知更新等。 S…...

Django API开发实战:前后端分离、Restful风格与DRF序列化器详解

系列文章目录 Django入门全攻略&#xff1a;从零搭建你的第一个Web项目Django ORM入门指南&#xff1a;从概念到实践&#xff0c;掌握模型创建、迁移与视图操作Django ORM实战&#xff1a;模型字段与元选项配置&#xff0c;以及链式过滤与QF查询详解Django ORM深度游&#xff…...

React基础教程:TodoList案例

todoList案例——增加 定义状态 // 定义状态state {list: ["kevin", "book", "paul"]}利用ul遍历list数组 <ul>{this.state.list.map(item ><li style{{fontWeight: "bold", fontSize: "20px"}} key{item.i…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

Spring是如何解决Bean的循环依赖:三级缓存机制

1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间‌互相持有对方引用‌,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

libfmt: 现代C++的格式化工具库介绍与酷炫功能

libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库&#xff0c;提供了高效、安全的文本格式化功能&#xff0c;是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全&#xff1a…...