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

用Pytorch构建一个喵咪识别模型

 本文参加新星计划人工智能(Pytorch)赛道:https://bbs.csdn.net/topics/613989052

目录

一、前言

二、问题阐述及理论流程

2.1问题阐述

2.2猫咪图片识别原理 

三、用PyTorch 实现 

3.1PyTorch介绍

3.2PyTorch 构建模型的五要素

3.3PyTorch 实现的步骤

3.3.1.数据

3.3.2模型

3.3.3损失函数

3.3.4优化器

3.3.5迭代训练

四、我用了哪些方法防止过拟合?

4.1控制网络规模

4.2数据增强

4.3正则化

4.4K 折交叉验证

五、用自己的图片验证

5.1输入数据

5.2代码实现 

5.3结果输出及分析

完整代码


一、前言

        舍友最近养了只猫咪,看起来很好看,但是你绝对想不到它拉的shi巨臭啊,哈哈哈哈,就很离谱。刚好最近在学习Pytorch,心血来潮,就用Pytorch来做个喵咪识别模型并,于是就有了本篇博文。

     

 

二、问题阐述及理论流程

2.1问题阐述

现一共有 259 张图片,总体分为两类:

有猫咪类

无猫咪类 

2.2猫咪图片识别原理 

三、用PyTorch 实现 

3.1PyTorch介绍

  PyTorch 是一个开源的深度学习框架,它的底层基于 Torch ,但实现与运用全部由 python 来完成。该框架主要用于人工智能领域的科学研究与应用开发。

3.2PyTorch 构建模型的五要素

1.数据:包括数据读取,数据清洗,进行数据划分和数据预处理。

2.模型:包括构建模型模块,组织复杂网络,初始化网络参数,定义网络层。

3.损失函数:包括创建损失函数,设置损失函数超参数,要根据不同任务选择合适的损失函数。

4.优化器:包括根据梯度使用某种优化器更新参数,管理模型参数,调整学习率。

5.迭代训练:组织上述 4 个模块进行反复训练。观察训练效果,绘制 Loss/ Accuracy 曲线或者用 TensorBoard 进行可视化分析。

3.3PyTorch 实现的步骤

3.3.1.数据

        在深度学习时会遇到各种不同形式的数据,如文本、图片、音频等,而每种数据又有多种文件类型。因此拿到数据,我们首先应该了解它的内部结构。

  h5py 文件是一种 " Dataset " 和 " Group " 二合一的容器:

  • 「Dataset」: 类似数组组织的数据的集合,像 numpy 数组一样工作;

  • 「Group」: 包含了其它 Dataset 和 其它 Group ,像字典一样工作。


读取下载好的 h5py 文件(以含有 209 张图片的测试集为例)

import h5pyf = h5py.File("/home/tian/dataset/catvnocat/train/train_catvnoncat.h5","r")#"r"代表读取模式
for key in f.keys():print(key)#输出
#list_classes
#train_set_x
#train_set_y

依次打印出这三个" key "下的内容 

print(f["list_classes"])
print(f["train_set_x"])
print(f["train_set_y"])#输出
#<HDF5 dataset "list_classes": shape (2,), type "|S7">
#<HDF5 dataset "train_set_x": shape (209, 64, 64, 3), type "|u1">
#<HDF5 dataset "train_set_y": shape (209,), type "<i8">

可以得到三个 Dataset 的相关信息:

  • list_classes:包含两个元素 ' non-cat ' 和' cat ',代表无猫和有猫这两个大类。

  • train_set_x :一个四维张量,形状为 209 * 64 * 64 * 3。代表一共有 209 张图片,其中每张图片以像素大小为 64 * 64 的三通道矩阵存储信息。

  • train_set_y :一个一维数组,元素全部存储着 209 张图片对应的标签,其中有猫为 1 ,无猫为 0 。


该 h5py 文件的结构如下图所示:

制作数据集

  从torch.utils.data中引入DatasetDataset是能够表示数据集的抽象类,一般有三个方法:

  • 「__init__方法」

    用于类的初始化,负责创建类的实例属性并进行赋值,并在实例化类后自动执行。这里我创建的 MyData 类中包含以下属性:

    • Archive:文件的路径及对文件的操作,只读或写入

    • Image:样本中的图片或者包含全部图片信息的像素矩阵

    • Label:样本中的标签

    • Transform:可能要对数据进行的变换或增强

  • 「__getitem__方法」

    所有子类都必须重写该方法,该方法通过索引(index)或键(key)访问样本,返回值为 样本和标签。

  • 「__len__方法」

    返回数据集的大小。

 

from torch.utils.data import Datasetclass MyDataset(Dataset):def __init__(self, archive , image , label , transform = None ):self.Archive = h5.File(archive, 'r')self.Images = self.Archive[image]self.Labels = self.Archive[label]self.Transform = transformdef __getitem__(self,index):image = self.Images[index]label = self.Labels[index]if self.Transform is not None:image = self.Transforms(image)  return image ,labeldef __len__(self):return len(self.Labels)train_dataset = MyDataset('/home/tian/dataset/catvnocat/train/train_catvnoncat.h5','train_set_x','train_set_y',train_transformer)
test_dataset = MyDataset('/home/tian/dataset/catvnocat/test/test_catvnoncat.h5','test_set_x','test_set_y',test_transformer)

读取数据集

  从torch.utils.data引入DataLoader,它帮助我们从Dataset中加载样本数据。它联合了数据集 Dataset 和采样器 Sampler,使其本身可以像一个迭代器一样工作。前者提供数据来源,后者提供索引。

from torch.utils.data import Dataloadertrain_loader = DataLoader(train_dataset, batch_size = batch_size_train, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size = batch_size_test, shuffle=False)

shuffle = True指的是将样本打乱,一般只针对训练集。

3.3.2模型

  该神经网络采用简单的 2 隐藏层全连接的方式,并在每一层采用 ReLU 函数作为激活函数,最后通过 Softmax 函数输出预测概率,以达到二分类的目的。

class Net(nn.Module):def __init__(self, in_dim, n_hidden_1,n_hidden_2,out_dim):super(Net, self).__init__()self.layer1 = nn.Sequential(nn.Linear(in_dim, n_hidden_1),nn.BatchNorm1d(n_hidden_1), nn.ReLU(True),nn.Dropout(0.25))self.layer2 = nn.Sequential(nn.Linear(n_hidden_1, n_hidden_2),nn.BatchNorm1d(n_hidden_2), nn.ReLU(True),nn.Dropout(0.25))self.layer3 = nn.Sequential(nn.Linear(n_hidden_2, out_dim), nn.Softmax(dim = 1))def forward(self, x):x = self.layer1(x)x = self.layer2(x)x = self.layer3(x)return x

3.3.3损失函数

  交叉熵损失函数是二分类问题常用的损失函数,可以直接在torch.nn里直接调用,其形式为:

criterion = nn.CrossEntropyLoss()

3.3.4优化器

  在 torch.optim中直接调用随机梯度下降法 SGD:

optimizer = optim.SGD(model.parameters(), lr = learning_rate, weight_decay = 1e-4)

3.3.5迭代训练

  一切准备工作就绪,进行迭代训练。也可以根据需要绘制 Loss/ Accuracy 曲线观察 train_loss 和 val_loss,并以此为依据来调试超参数。

for epoch in range(num_epoches+1):model.train()    for data in train_loader:img, label = dataimg = img.view(img.size(0), -1)  img = Variable(img)label = Variable(label)out = model(img.to(torch.float32))loss = criterion(out, label)_, pred = torch.max(out, 1)acc = (pred == label).sum().item() / (len(train_dataset))optimizer.zero_grad()loss.backward()optimizer.step()model.eval()eval_loss = 0eval_acc = 0        for data in test_loader:img, label = dataimg = img.view(img.size(0), -1)out = model(img.to(torch.float32))loss_1 = criterion(out, label)eval_loss += loss_1.data.item()*label.size(0)_, pred = torch.max(out, 1)eval_acc += (pred == label).sum().item() / len(test_dataset)if epoch%50 == 0:train_losses.append(loss.data.item())train_acc.append(acc)test_losses.append(loss_1.data.item())test_acc.append(eval_acc)print('epoch: {}'.format(epoch))print('Train Loss: {:.4}, Train_Acc: {:.4}'.format(loss.data.item(), acc))print('Test Loss: {:.4f}, Test_Acc: {:.4f}'.format(eval_loss / (len(test_dataset)),eval_acc))fig = plt.figure()
plt.plot(train_counter, train_losses, color='blue')
plt.plot(test_counter, test_losses, '--',color='red')
plt.legend(['Train Loss', 'Test Loss'], loc='upper right')
plt.xlabel('number of training examples seen')
plt.ylabel('negative log likelihood loss')fig = plt.figure()
plt.plot(train_counter, train_acc, color='blue')
plt.plot(test_counter, test_acc, '--',color='red')
plt.legend(['Train Acc', 'Test Acc'], loc='lower right')
plt.xlabel('number of training examples seen')
plt.ylabel('Acc')plt.show()

「结果展示」

         可以看到,过拟合的情况没有发生,并且训练集和测试集的准确率都接近 90%,相对于原本的准确率有了较大的提高。

四、我用了哪些方法防止过拟合?

4.1控制网络规模

  当神经网络具有过多的神经元时,训练集中包含的有限信息量不足以训练隐藏层中的所有神经元,很可能导致过拟合。因此要控制网络规模,既不能太宽也不能太深。

4.2数据增强

  样本量少是造成过拟合的主要原因之一,但我们往往很难从源头上解决这一问题。数据增强通过对现有的样本(以图片为例)进行各种不同的变换(如随机自定义大小裁剪、随机翻转、随机旋转、增加色彩对比度等),然后适当增加训练迭代次数,从而达到样本量扩张的效果。

  本文采用了以下手段进行数据增强:

  • 对输入图片随机裁剪,将原本像素大小为64的图片裁剪成像素大小为48的图片

  • 在水平方向上对一半的图片进行随机翻转

  • 在垂直方向上对一半的图片进行随机翻转

  • 对图在一定角度内进行旋转

from torchvision import transformstrain_transformer = transforms.Compose([transforms.ToPILImage(),transforms.RandomResizedCrop(48),transforms.RandomHorizontalFlip(), transforms.RandomRotation((-15, 15)),transforms.ToTensor(),transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])test_transformer = transforms.Compose([transforms.ToPILImage(),transforms.Resize(48),transforms.ToTensor(),transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])

 测试集大多数情况下不进行数据增强,这里为了适应训练集数据增强后的图片大小对测试集进行了尺寸缩放,同样变为像素大小为的图片。

4.3正则化

  • 「Drop_out」

  作为常用的预防过拟合的方法之一,它的主要思想是让隐藏层的节点在每次迭代时有一定几率失效,从而避免对某个节点的强依赖,让反向传播的修正值可以更加平衡的分布到各个参数上。也在一定程度上降低了网络复杂度。

  • 「weight_decay」

  过拟合时模型会拟合很多位置较偏的点,导致拟合函数在某些小区间剧烈变化,权重 w 的绝对值很大。此方法通过控制权重 w 的大小来缓解过拟合的情况。

4.4K 折交叉验证

  以模型调优的思路来缓解过拟合。在训练每种模型时,通过k折交叉验证得到k组不同的训练集和测试集,并将每组的误差平均作为衡量模型泛化能力的准则,从而选择出泛化能力最好的(即最不容易发生过拟合)的模型。

kf = KFold(n_splits = 7, shuffle=True)

五、用自己的图片验证

        训练神经网络最终的目的就是为了应用,因此最后一个环节我们用自己的图片来验证“猫咪识别器”的性能如何。


5.1输入数据

有猫咪类

 无猫咪类

 

5.2代码实现 

from PIL import Image
def trans_pic(img_dir,width,height):image = Image.open(img_dir) #打开图片resized_image = image.resize((width, height), Image.ANTIALIAS)data = np.asarray(resized_image)#转换为矩阵image = Image.fromarray(data)  #将之前的矩阵转换为图片#image.show()#调用本地软件显示图片,win10是叫照片的工具return datapath_cat = [r"/home/tian/Pictures/cat_1.jpg",r"/home/tian/Pictures/cat_2.jpg",r"/home/tian/Pictures/cat_3.jpg",r"/home/tian/Pictures/cat_4.jpg",r"/home/tian/Pictures/cat_5.jpg"]path_nocat = [r"/home/tian/Pictures/nocat_1.jpg",r"/home/tian/Pictures/nocat_2.jpg",r"/home/tian/Pictures/nocat_3.jpg",r"/home/tian/Pictures/nocat_4.jpg",r"/home/tian/Pictures/nocat_5.jpg"]for i in range(5): a = test_transformer(trans_pic(path_cat[i],48,48)).view(1, -1)b = test_transformer(trans_pic(path_nocat[i],48,48)).view(1, -1)out_1 = model(a.to(torch.float32))out_2 = model(b.to(torch.float32))_, pred_1= torch.max(out_1, 1)_, pred_2= torch.max(out_2, 1) if pred_1 == 1:print("第",i+1,"张猫咪图片识别正确")if pred_1 == 0:print("第",i+1,"张猫咪图片识别错误")if pred_2 == 1:print("第",i+1,"张非猫咪图片识别错误")if pred_2 == 0:print("第",i+1,"张非猫咪图片识别正确")print("\n")

5.3结果输出及分析

「结果输出」

第 1 张猫咪图片识别正确
第 1 张非猫咪图片识别正确第 2 张猫咪图片识别正确
第 2 张非猫咪图片识别正确第 3 张猫咪图片识别正确
第 3 张非猫咪图片识别错误第 4 张猫咪图片识别正确
第 4 张非猫咪图片识别错误第 5 张猫咪图片识别正确
第 5 张非猫咪图片识别正确

「结果分析」

  • 猫咪图片:都能识别正确。

  • 非猫咪图片:第三张、第四张图片出现了识别错误。

    • 对于风景图这种与猫咪图片差别很大的图片,识别器能轻松地辨别;

    • 对于老虎、老鼠这些与猫咪在特征上有很多相似地方的动物,猫咪识别器显然还不具备能力将他们很好地区分开来。

  因此在图片识别领域,我们总是需要更合适的网络结构、更大规模的数据以及更合适的超参数选择。

完整代码

import numpy as np
import h5py as h5
import torch
from torch.utils.data import Dataset,DataLoader
import torch.nn.functional as F
from torch import nn, optim
from torch.autograd import Variable
from torchvision import datasets, transforms
from matplotlib import pyplot as pltbatch_size_train = 209
batch_size_test = 50
learning_rate = 0.0075
num_epoches = 3500
momentum = 0.5train_transformer = transforms.Compose([transforms.ToPILImage(),transforms.RandomResizedCrop(48),transforms.RandomHorizontalFlip(),transforms.RandomVerticalFlip(),transforms.RandomRotation((-15, 15)),transforms.ToTensor(),transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])test_transformer = transforms.Compose([transforms.ToPILImage(),transforms.Resize(48), transforms.ToTensor(),transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
])class MyDataset(Dataset):def __init__(self, archive,image,label,transform = None):self.archive = h5.File(archive, 'r')self.images = self.archive[image]self.labels = self.archive[label]self.transform = transformdef __getitem__(self,index):image = self.images[index]label = self.labels[index]if self.transform is not None:image = self.transform(image)  return image ,labeldef __len__(self):return len(self.labels)train_dataset = MyDataset('/home/tian/dataset/catvnocat/train/train_catvnoncat.h5','train_set_x','train_set_y',train_transformer)
test_dataset = MyDataset('/home/tian/dataset/catvnocat/test/test_catvnoncat.h5','test_set_x','test_set_y',test_transformer)
train_loader = DataLoader(train_dataset, batch_size=batch_size_train, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size_test, shuffle=False)class Batch_Net(nn.Module):def __init__(self, in_dim, n_hidden_1,n_hidden_2,out_dim):super(Batch_Net, self).__init__()self.layer1 = nn.Sequential(nn.Linear(in_dim, n_hidden_1),nn.BatchNorm1d(n_hidden_1), nn.ReLU(True),nn.Dropout(0.25))#,nn.Dropout(0.3))self.layer2 = nn.Sequential(nn.Linear(n_hidden_1, n_hidden_2),nn.BatchNorm1d(n_hidden_2), nn.ReLU(True),nn.Dropout(0.25))#,nn.Dropout(0.5))#,nn.Dropout(0.3))#,nn.Dropout(0.5))self.layer3 = nn.Sequential(nn.Linear(n_hidden_2, out_dim),nn.Softmax(dim = 1))def forward(self, x):x = self.layer1(x)x = self.layer2(x)x = self.layer3(x)return x#构建模型实例 
model = Batch_Net(48*48*3,90,10,2)criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=learning_rate,weight_decay= 1e-4)train_losses = []
train_acc = []
train_counter = [i * len(train_loader)*50 for i in range(num_epoches // 50 + 1)]
test_losses = []
test_acc = []
test_counter = [i * len(test_loader)*50 for i in range(num_epoches // 50 + 1)]for epoch in range(num_epoches+1):model.train()for data in train_loader:img, label = dataimg = img.view(img.size(0), -1)  img = Variable(img)label = Variable(label)out = model(img.to(torch.float32))loss = criterion(out, label)_, pred = torch.max(out, 1)acc = (pred == label).sum().item() / (len(train_dataset))optimizer.zero_grad()loss.backward()optimizer.step()model.eval()eval_loss = 0eval_acc = 0for data in test_loader:img, label = dataimg = img.view(img.size(0), -1)out = model(img.to(torch.float32))loss_1 = criterion(out, label)eval_loss += loss_1.data.item()*label.size(0)_, pred = torch.max(out, 1)eval_acc += (pred == label).sum().item() / len(test_dataset)if epoch%50 == 0:train_losses.append(loss.data.item())train_acc.append(acc)test_losses.append(loss_1.data.item())test_acc.append(eval_acc)print('epoch: {}'.format(epoch))print('Train Loss: {:.4}, Train_Acc: {:.4}'.format(loss.data.item(), acc))print('Test Loss: {:.4f}, Test_Acc: {:.4f}'.format(eval_loss / (len(test_dataset)),eval_acc))fig = plt.figure()
plt.plot(train_counter, train_losses, color='blue')
plt.plot(test_counter, test_losses, '--',color='red')
plt.legend(['Train Loss', 'Test Loss'], loc='upper right')
plt.xlabel('number of training examples seen')
plt.ylabel('negative log likelihood loss')fig = plt.figure()
plt.plot(train_counter, train_acc, color='blue')
plt.plot(test_counter, test_acc, '--',color='red')
plt.legend(['Train Acc', 'Test Acc'], loc='lower right')
plt.xlabel('number of training examples seen')
plt.ylabel('Acc')plt.show()

相关文章:

用Pytorch构建一个喵咪识别模型

本文参加新星计划人工智能(Pytorch)赛道&#xff1a;https://bbs.csdn.net/topics/613989052 目录 一、前言 二、问题阐述及理论流程 2.1问题阐述 2.2猫咪图片识别原理 三、用PyTorch 实现 3.1PyTorch介绍 3.2PyTorch 构建模型的五要素 3.3PyTorch 实现的步骤 3.3.…...

QT搭建MQTT开发环境

QT搭建MQTT开发环境 第一步、明确安装的QT版本 注意&#xff1a; 从QT5.15.0版本开始&#xff0c;官方不再提供离线版安装包&#xff0c;除非你充钱买商业版。 而在这里我使用的QT版本为5.15.2&#xff0c;在线安装了好久才弄好&#xff0c;还是建议使用离线安装的版本 在这里…...

Python3,5行代码,生成自动排序动图,这操作不比Excel香?

5行代码生成自动排序动图1、引言2、代码实战2.1 pynimate介绍2.2 pynimate安装2.3 代码示例3、总结1、引言 小屌丝&#xff1a;鱼哥&#xff0c;听说你的excel段位又提升了&#xff1f; 小鱼&#xff1a;你这是疑问的语气&#xff1f; 小屌丝&#xff1a;没有~ 吧… 小鱼&…...

【Java SE】变量的本质

目录一. 前言二. 变量(variable)2.1 性质2.2 变量类型2.2.1 核心区别2.3 变量的使用三. 总结一. 前言 一天一个Java小知识点&#xff0c;助力小伙伴更好地入门Java&#xff0c;掌握更深层次的语法。 二. 变量(variable) 2.1 性质 变量本质上就是代表一个”可操作的存储空间”…...

【Android笔记85】Android之使用Camera和MediaRecorder录制视频

这篇文章,主要介绍Android之使用Camera和MediaRecorder录制视频。 目录 一、录制视频 1.1、案例运行效果 1.2、创建Camera对象 1.3、创建MediaRecorder对象...

MySQL集群搭建与高可用性实现:掌握主从复制、多主复制、负载均衡和故障切换技术,让你的MySQL数据库永不宕机!

MySQL集群和高可用性MySQL是一款广泛使用的关系型数据库管理系统&#xff0c;常用于Web应用和企业级应用中。为了提高MySQL的可用性&#xff0c;我们可以通过搭建MySQL集群和实现高可用性来保障数据的稳定性和可靠性。本文将介绍如何搭建MySQL集群和实现高可用性&#xff0c;包…...

收到6家大厂offer,我把问烂了的《Java八股文》打造成3个文档。共1700页!!

前言大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;近期的面试越来越难了&#xff0c;要背的八股文越来越多了&#xff0c;考察得越来越细&#xff0c;越来越底层&#xff0c;明摆着就是想让我们徒手造航母嘛&#xff01;实在是太为难我们这些程序员了。这不&#…...

多线程 (六) 单例模式

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…...

Docker入门到放弃笔记之容器

1、启动容器1.1容器hello world1.2 容器bash终端1.3 后台运行容器是 Docker 三大核心概念之一&#xff0c;其余两个是镜像与仓库。本文主讲容器。简单的说&#xff0c;容器是独立运行的一个或一组应用&#xff0c;以及它们的运行态环境。对应的&#xff0c;虚拟机可以理解为模拟…...

项目二 任务三 训练5 交换机的HSRP技术

在“项目二 任务三 训练4 交换机的DHCP技术”基础上继续完成下列操作&#xff1a; 1、二层交换机50-2的配置 50-2>en 50-2#conf t Enter configuration commands, one per line. End with CNTL/Z. 50-2(config)#int 50-2(config)#interface g 50-2(config)#interface gigab…...

计算机网络复习重点

文章目录计算机网络复习重点第一章 计算机网络和因特网概念与应用1、什么是因特网2、协议protocol3、入网方式4、物理媒介5、数据交换模式6、延时与丢包什么时候发生延时&#xff1f;延时的类型丢包何时发生7、协议层次与模型因特网协议栈TCP / IP模型ISO/OSI参考模型协议数据单…...

算法基础---基础算法

文章目录 快速排序归并排序二分 整数二分浮点数二分高精度 高精度加法高精度减法高精度乘法高精度除法前缀和 一维前缀和二维前缀和差分 一维差分二维差分双指针位运算离散化区间合并一、快速排序 思想&#xff1a;1.首先确定一个分界点&#xff08;随机取任意一点为…...

linux中写定时任务

场景&#xff1a;我们生产环境中有大量的日志记录&#xff0c;但是我们的磁盘没有太大&#xff0c;需要定时清理磁盘 文章目录crond 定时任务详解安装定时任务crontab服务启动与关闭crontab操作crontab 命令test.sh查看日志丢弃linux中的执行日志Linux进入nano模式方式一方式二…...

2023.3.21

6&#xff1a;有序数组中找到num // arr保证有序&#xff0c;在arr数组中寻找num&#xff0c;二分查找public static boolean find(int[] arr, int num) {if(arr null || arr.length 0) {return false;}int L 0;int R arr.length - 1;while (L < R) {int mid (L R) /…...

制作数据库框架

一 利用前端条件组装sql与查询条件的集合public void handle() throws Exception{Map<String,String> requestMap new HashMap();String fromdate requestMap.get("fromdate");String todate requestMap.get("todate");String resultcode reque…...

Winbond W25Qxx SPI FLASH 使用示例(基于沁恒CH32V307单片机)

文章目录目的基础说明使用示例总结目的 Winbond&#xff08;华邦&#xff09;的 W25Qxx 系列 SPI FLASH 是比较常用的芯片&#xff0c;这篇文章将演示单片机中通过SPI使用该芯片的操作过程。 本文使用沁恒官方的开发板 &#xff08;CH32V307-EVT-R1沁恒RISC-V模块MCU赤兔评估…...

贪心算法的原理以及应用

文章目录0、概念0.1.定义0.2.特征0.3.步骤0.4.适用1、与动态规划的联系1.1.区别1.2.联系2、例子3、总结4、引用0、概念 0.1.定义 贪心算法&#xff08;greedy algorithm &#xff0c;又称贪婪算法&#xff09;是指&#xff0c;在对问题求解时&#xff0c;总是做出在当前看来是…...

WebRTC拥塞控制原理之一基本介绍

1 基本原理 WebRTC的拥塞控制模块使用的是基于TCP的拥塞控制算法。它是根据网络带宽和延迟等信息来自适应地调整传输速率的。 具体来说&#xff0c;该模块采用的是基于RFC 3550中的延迟抖动调整算法的改进版本。该算法实施的基本原理是在传输的过程中定期探测网络的质量和延迟…...

选择 .NET 的 n 个理由

自从我们启动快速发展的 .NET 开源和跨平台项目以来&#xff0c;.NET 发生了很大变化。我们重新思考并完善了该平台&#xff0c;添加了专为性能和安全性而设计的新低级功能&#xff0c;以及以生产力为中心的高级功能。Span<T>、硬件内在函数和可为空的引用类型都是示例。…...

spark第三章:工程化代码

系列文章目录 spark第一章&#xff1a;环境安装 spark第二章&#xff1a;sparkcore实例 spark第三章&#xff1a;工程化代码 文章目录系列文章目录前言一、三层架构二、拆分WordCount1.三层拆分2.代码抽取总结前言 我们上一次博客&#xff0c;完成了一些案例的练习&#xff0…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...