【计算机视觉基础CV】03-深度学习图像分类实战:鲜花数据集加载与预处理详解
本文将深入介绍鲜花分类数据集的加载与处理方式,同时详细解释代码的每一步骤并给出更丰富的实践建议和拓展思路。以实用为导向,为读者提供从数据组织、预处理、加载到可视化展示的完整过程,并为后续模型训练打下基础。
前言
在计算机视觉的深度学习实践中,数据加载和预处理是至关重要的一步。无论你是初学者,还是有一定经验的从业者,都需要深刻理解如何将原始数据转化为神经网络可接受的输入。PyTorch中的torchvision.datasets
和torchvision.transforms
为我们提供了极大的便利,使图像数据的加载和处理更加高效与简洁。
本文将以“鲜花分类数据集”(一个包含5种不同花卉类别的图像数据集)为例,详细讲述如何使用ImageFolder
类进行数据加载,并通过transforms
对图像进行预处理和数据增强。我们还会深入讨论数据集结构、训练/验证集划分、代码注释和实践建议,并给出详细说明。
数据集简介与结构
本例使用的鲜花分类数据集共包含5种花:雏菊(daisy)、蒲公英(dandelion)、玫瑰(roses)、向日葵(sunflowers)和郁金香(tulips)。数据量约为:
-
训练集(train):3306张图像
-
验证集(val):364张图像
数据已按类别分好目录,每个类别对应一个文件夹,文件夹中存放若干图片文件。结构示意如下:
dataset/flower_datas/├─ train/│ ├─ daisy/ # 雏菊类图像若干张│ ├─ dandelion/ # 蒲公英类图像若干张│ ├─ roses/ # 玫瑰类图像若干张│ ├─ sunflowers/ # 向日葵类图像若干张│ └─ tulips/ # 郁金香类图像若干张└─ val/├─ daisy/├─ dandelion/├─ roses/├─ sunflowers/└─ tulips/
这种目录结构非常适合ImageFolder
数据集类,它会根据子文件夹的名称自动分配类别标签,从0开始编号。例如:
-
daisy -> 0
-
dandelion -> 1
-
roses -> 2
-
sunflowers -> 3
-
tulips -> 4
这样无需手动编码类别映射,简化了流程。
ImageFolder和transform
ImageFolder简介
ImageFolder
是torchvision.datasets
中的一个实用数据类,它假设数据按如下规则组织:
-
root/class_x/xxx.png
-
root/class_x/xxy.png
-
root/class_y/xxz.png
-
...
其中class_x
和class_y
是类名(字符串),ImageFolder
会根据这些类名自动生成类别索引。加载后,每个样本是一个(image, label)
二元组,image
通常会通过transform
转换为Tensor
,label
为整数索引。
transforms的数据预处理功能
torchvision.transforms
提供多种图像处理方法,用来改变图像格式、尺寸、颜色空间和进行数据增强。例如:
-
ToTensor()
:将PIL图像或Numpy数组转换为(C,H,W)
格式的张量,并将像素值归一化到[0,1]之间。 -
Resize((224,224))
:将图像缩放到224x224大小,这通常是预训练模型如ResNet、VGG的标准输入尺寸。 -
RandomHorizontalFlip()
:随机水平翻转图像,用于数据增强,提高模型对翻转不敏感。 -
Normalize(mean, std)
:对图像的每个通道进行归一化,使训练更稳定。
你可以根据需求灵活组合多个变换操作,使用transforms.Compose
将其串联成流水线。
加载鲜花分类数据集的示例代码
下面的代码示例中,我将详细注释每个步骤,为读者提供清晰的思路。该示例以最基本的ToTensor和Resize为主,读者可按需添加更多transform。
import torch
import torchvision
from torchvision.datasets import ImageFolder
from torchvision import transforms
import matplotlib.pyplot as plt# 数据集存放路径,根据实际情况修改
flowers_train_path = '../01.图像分类/dataset/flower_datas/train/'
flowers_val_path = '../01.图像分类/dataset/flower_datas/val/'# 定义数据预处理
# 这里的transforms主要包括:
# 1. ToTensor():将PIL图片或numpy数组转为Tensor,并将像素值归一化到[0,1]区间。
# 2. Resize((224,224)):将所有图片大小统一为224x224,以匹配后续卷积神经网络的输入要求。
# 对于实际训练,更建议加入数据增强手段(如随机裁剪、翻转、归一化等),
# 但本例先展示基本流程。
dataset_transform = transforms.Compose([transforms.ToTensor(),transforms.Resize((224,224))
])# 使用ImageFolder加载训练集和验证集
# ImageFolder会扫描指定目录下的子文件夹,并以子文件夹名称作为类别。
flowers_train = ImageFolder(root=flowers_train_path, transform=dataset_transform)
flowers_val = ImageFolder(root=flowers_val_path, transform=dataset_transform)# 打印样本数量
print("训练集样本数:", len(flowers_train))
print("验证集样本数:", len(flowers_val))# flowers_train.classes属性包含类别名称列表,如['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips']
print("类别名称列表:", flowers_train.classes)# 获取单个样本进行查看
# __getitem__(index)返回(img, label),img是Tensor,label是int
sample_index = 3000
sample_img, sample_label = flowers_train[sample_index]print("样本索引:", sample_index)
print("类别标签索引:", sample_label, "类别名称:", flowers_train.classes[sample_label])
print("图像Tensor尺寸:", sample_img.shape) # 期望为[3,224,224]# 可视化图像
# Matplotlib的imshow要求图像为(H,W,C),而Tensor是(C,H,W),需要permute调整维度顺序。
plt.imshow(sample_img.permute(1,2,0))
plt.title(flowers_train.classes[sample_label])
plt.show()
代码输出:
关于训练集、验证集和测试集的说明
本数据集中已提前将数据分为train
和val
两个目录:
-
train/
:训练集,用于模型训练过程中反向传播和参数更新。 -
val/
:验证集,用于在训练中间进行性能评估,不参与参数更新,仅用于选择超参数或判断训练是否过拟合。
有些数据集还会提供test/
测试集,用于最终评估模型在未知数据上的表现,但本例中未提供,如有需要可自行分割数据或从其他来源获取。
DataLoader的引入
仅有ImageFolder
还不够,为了在训练时批量读取数据并进行迭代,我们通常会将数据集对象传入DataLoader
中。
DataLoader
的作用是:
-
按指定的batch_size从Dataset中抽取样本构成mini-batch。
-
可设置
shuffle=True
来随机打乱样本顺序,防止模型记住样本顺序。 -
使用
num_workers
参数并行加速数据加载。
示例(可选代码):
from torch.utils.data import DataLoaderbatch_size = 32
# 定义训练集和验证集的DataLoader
train_loader = DataLoader(flowers_train, batch_size=batch_size, shuffle=True, num_workers=2)
val_loader = DataLoader(flowers_val, batch_size=batch_size, shuffle=False, num_workers=2)# 测试一下加载结果
images, labels = next(iter(train_loader))
print("一个batch的图像尺寸:", images.shape) # [batch_size, 3, 224, 224]
print("对应的标签:", labels) # 张量形式,如tensor([0, 1, 3, ...])
有了DataLoader,我们在训练模型时,就可以轻松迭代数据:
for epoch in range(1):for batch_images, batch_labels in train_loader:# 在这里将batch_images, batch_labels输入模型进行训练print("一个batch的图像尺寸:", batch_images.shape) # [batch_size, 3, 224, 224]print("对应的标签:", batch_labels) # 张量形式,如tensor([0, 1, 3, ...])passbreak
我们可以打印一下第一个batch 和最后一个batch的标签
batch_count = 0
first_batch_images, first_batch_labels = None, None
last_batch_images, last_batch_labels = None, Nonefor epoch in range(1):for batch_images, batch_labels in train_loader:batch_count += 1# 保存第一个batchif batch_count == 1:first_batch_images, first_batch_labels = batch_images, batch_labelsprint("第一个batch的图像尺寸:", batch_images.shape)print("第一个batch的标签:", batch_labels)# 每次循环都会更新last_batchlast_batch_images, last_batch_labels = batch_images, batch_labelsbreak # 只进行一次epoch的训练,移除这行会进行多个epoch的训练# 打印最后一个batch
print("最后一个batch的图像尺寸:", last_batch_images.shape)
print("最后一个batch的标签:", last_batch_labels)# 打印总共的batch数量
print("总共的batch数量:", batch_count)
数据增强策略的拓展
实际训练中,为提高模型的泛化能力,我们常加入数据增强操作。这些操作对训练集图像进行随机变换,如随机剪裁、翻转、颜色抖动、归一化等。这样模型不会过度记忆特定图像的像素分布,而会学习更有泛化性的特征。
一个常用的transform示例:
# 定义训练集的图像预处理流程
train_transform = transforms.Compose([# 随机裁剪并缩放图像到224x224的尺寸,裁剪的区域大小是随机的transforms.RandomResizedCrop(224), # 随机进行水平翻转,用于数据增强,提升模型的泛化能力transforms.RandomHorizontalFlip(),# 将图像转换为Tensor类型,PyTorch要求输入为Tensor格式transforms.ToTensor(),# 进行图像的标准化处理。根据ImageNet数据集的均值和标准差进行归一化,# 使得不同的通道(RGB)具有相同的尺度,便于训练。transforms.Normalize(mean=[0.485,0.456,0.406], std=[0.229,0.224,0.225])
])# 定义验证集的图像预处理流程
val_transform = transforms.Compose([# 将图像的最短边缩放到256像素,保持长宽比例不变transforms.Resize(256), # 从缩放后的图像中进行中心裁剪,裁剪出224x224的区域,这样图像的尺寸就一致了transforms.CenterCrop(224),# 将图像转换为Tensor类型,PyTorch要求输入为Tensor格式transforms.ToTensor(),# 进行图像的标准化处理。根据ImageNet数据集的均值和标准差进行归一化,# 使得不同的通道(RGB)具有相同的尺度,便于训练。transforms.Normalize(mean=[0.485,0.456,0.406], std=[0.229,0.224,0.225])
])# 使用定义的transform对训练集和验证集进行图像预处理
# flowers_train_path和flowers_val_path是训练集和验证集图像所在的路径
flowers_train = ImageFolder(flowers_train_path, transform=train_transform) # 训练集
flowers_val = ImageFolder(flowers_val_path, transform=val_transform) # 验证集
在此示例中,Normalize
的参数是使用ImageNet数据集的均值和标准差,这在使用ImageNet预训练模型时是常规操作。对于自定义数据集,你也可以先统计本数据集的均值和方差,再进行归一化。
我们可以打印一下变化前后的图像区别
import os
import random
import numpy as np # 需要导入numpy
import matplotlib.pyplot as plt
from PIL import Image
from torchvision import transforms
from torchvision.datasets import ImageFolder# 定义训练集的图像预处理流程
train_transform = transforms.Compose([transforms.RandomResizedCrop(224),transforms.RandomHorizontalFlip(),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])# 定义图像数据集路径
train_image_folder = '/Users/coyi/PycharmProjects/coyi_pythonProject/01.图像分类/dataset/flower_datas/train/'# 使用ImageFolder加载数据集
dataset = ImageFolder(train_image_folder, transform=None)# 随机选取一张图片
random_idx = random.randint(0, len(dataset) - 1)
image, label = dataset[random_idx]# 显示原始图像
plt.figure(figsize=(5,5))
plt.title("Original Image")
plt.imshow(image)
plt.axis('off') # 不显示坐标轴
plt.show()# 应用train_transform变换
transformed_image = train_transform(image)# 反标准化(Undo normalization)以恢复图片的原始视觉效果,因为训练的时候需要标准化
inv_normalize = transforms.Normalize(mean=[-0.485, -0.456, -0.406], std=[1/0.229, 1/0.224, 1/0.225])
unnormalized_image = inv_normalize(transformed_image)# 将Tensor转回PIL图像进行显示
unnormalized_image = unnormalized_image.permute(1, 2, 0).numpy() # 转换为HWC格式
unnormalized_image = np.clip(unnormalized_image, 0, 1) # 限制值在[0, 1]之间,以符合视觉输出# 显示变换后的图像
plt.figure(figsize=(5,5))
plt.title("Transformed Image")
plt.imshow(unnormalized_image)
plt.axis('off') # 不显示坐标轴
plt.show()
输出:
备注: 为了显示图片,我对处理后的图片进行了反标准化,实际上训练的时候是不需要反标准化的
为什么要反标准化?
标准化是一个常见的预处理步骤,目的是让模型训练时更稳定,通常是将像素值转换到均值为0、标准差为1的范围。这可以帮助模型更好地收敛,并且消除不同通道(例如RGB)的尺度差异。
然而,标准化后的图像不适合直接用于可视化,因为它们的像素值已经不在[0, 1]的范围内,可能会变成负数或大于1。反标准化的目的是恢复图像的原始视觉效果,让它们的像素值回到原始的视觉范围。
不反标准化可以吗?
在可视化时不反标准化是可以的,但你会看到经过标准化后的图像没有直观的可视化效果,因为图像的像素值会偏离 [0, 1] 的可视化范围。这会导致显示的图像看起来可能是“失真”的,例如图像会变得非常暗、非常亮,或者有一些不自然的颜色。
简而言之:
• 反标准化是为了恢复图像的原始视觉效果,使得图像显示更符合人类的感知。
• **np.clip()**是为了确保图像的像素值在[0, 1]范围内,符合图像显示的要求。
示例:
假设标准化之后,你得到了一个像素值为 -0.5 或 1.5 的图像像素。这时,如果不进行 np.clip(),直接用 matplotlib 显示,可能会看到图像出现异常的颜色或显示不出来。而通过 np.clip(),将这些像素值限制在[0, 1]的范围内,可以确保图像能正确显示。
类别分布与标签可解释性
flowers_train.classes
或flowers_val.classes
可以查看类名列表。例如:
这意味着模型预测结果中的label=0代表daisy,label=1代表dandelion,以此类推。当我们预测模型输出为label=3
时,就可以将其解释为sunflowers。这种可读性非常有助于后期分析和调试。
如果想查看具体每类样本数量,可手动统计,例如:
通过查看类别分布,我们可了解数据是否偏斜(某些类样本过多或过少),从而采取相应措施(如类均衡采样、权重平衡等)。
实战建议和下一步计划
-
数据准备完成后做什么? 通常下一步就是定义和加载模型(如预训练的ResNet18),然后编写训练循环对模型进行微调或从头训练。在训练循环中,
train_loader
提供批数据,val_loader
则用于评估模型在验证集上的表现。 -
调试DataLoader是否正确工作: 在正式训练前,尝试可视化几个batch的数据样本,确保图像大小、颜色正确,标签映射无误。如果出现图像显示不正确或标签偏移,及时检查目录结构和transform流程。
-
善用数据增强: 当验证集精度停滞不前或出现过拟合时,尝试加入更多数据增强手段(如
RandomRotation
、ColorJitter
、RandomGrayscale
等)提升泛化性能。 -
硬件加速: 在加载大规模数据时,合理增加
num_workers
可以提高数据读取速度(依赖操作系统和硬件条件)。同时,如果是分布式训练,也需考虑分布式Sampler和合适的数据划分策略。 -
定制Dataset: 如果你的数据不遵循
ImageFolder
的结构,也可以自行定义Dataset
类,通过实现__len__
和__getitem__
方法来自定义数据加载流程。但对像本例这样已按类分文件夹的数据集,ImageFolder
无疑是最简单高效的方案。
小结
在本文中,我们从零出发,详细介绍了如何使用PyTorch的ImageFolder
和transforms
加载和预处理鲜花分类数据集。主要点包括:
-
数据集组织结构:子文件夹命名为类名,便于ImageFolder自动识别类别。
-
使用transforms对图像进行ToTensor和Resize等变换,以满足神经网络输入要求。
-
通过可视化样本和打印类别信息确认数据加载的正确性。
-
引入DataLoader批量采样和迭代数据,为后续训练循环奠定基础。
-
展望数据增强、Normalize以及预训练模型迁移学习等实战技巧。
数据加载与预处理是深度学习项目不可或缺的步骤。掌握这些技能,能够让你在模型开发和实验中更加得心应手。未来你可以尝试更多高级技巧,如自定义transforms、对数据集进行统计分析、探索更复杂的增强策略和分布式数据加载方法。
达成这些基础后,你就可以开始定义模型(如使用torchvision.models.resnet18(pretrained=True)
加载预训练模型)、设置损失函数(如CrossEntropyLoss)、选择优化器(如Adam或SGD),并在训练循环中快速迭代提升模型性能。
希望本文介绍,能为你对CV数据加载与预处理的理解添砖加瓦,帮助你在图像分类任务中迈出稳健的一步。
如果你遇到了什么问题,或者想了解某些方面的知识,欢迎在评论区留言
相关文章:
【计算机视觉基础CV】03-深度学习图像分类实战:鲜花数据集加载与预处理详解
本文将深入介绍鲜花分类数据集的加载与处理方式,同时详细解释代码的每一步骤并给出更丰富的实践建议和拓展思路。以实用为导向,为读者提供从数据组织、预处理、加载到可视化展示的完整过程,并为后续模型训练打下基础。 前言 在计算机视觉的深…...
Android实现RecyclerView边缘渐变效果
Android实现RecyclerView边缘渐变效果 1.前言: 是指在RecyclerView中实现淡入淡出效果的边缘效果。通过这种效果,可以使RecyclerView的边缘在滚动时逐渐淡出或淡入,以提升用户体验。 2.Recyclerview属性: 2.1、requiresFading…...
springboot结合AES和国密SM4进行接口加密
api接口加密 1.为什么需要api接口加密呢? 1.防止爬虫 2.防止数据被串改 3.确保数据安全 2.如何实现接口加密呢? 3.我们可以使用哪些加密算法来加密呢? AES 密码学中的高级加密标准(Advanced Encryption Standard,…...
后端项目java中字符串、集合、日期时间常用方法
我这里只介绍了项目中最常用的哈,比如像集合有很多,但我们最常用的就是ArrayList。 然后我这里会以javascript中的字符串、数组的方法为基准来实现,有些方法js和java会有些区别也会介绍 字符串 每次修改 String 对象都会创建一个新的对象,而 StringBuffer 可以在同一个对象…...
前端框架Vue的路由机制
大家好,我是G探险者。 最近在调试前端代码的时候,遇到一个问题。首先我们有一个门户页面,该页面里面有很多的豆腐块,每个豆腐块会配置一个系统的跳转连接。 我的系统就是其中一个豆腐块,我第一次登录进来之后…...
flutter 快速实现侧边栏
首先我们写一个侧边栏工具类,示例如下: import package:flutter/material.dart;class Sidebar extends StatelessWidget {overrideWidget build(BuildContext context) {return Drawer(child: ListView(padding: EdgeInsets.zero,children: <Widget&…...
华为数通最新题库 H12-821 HCIP稳定过人中
以下是成绩单和考试人员 HCIP H12-831 HCIP H12-725 安全中级...
算法训练第二十三天|93. 复原 IP 地址 78. 子集 90. 子集 II
93. 复原 IP 地址--分割 题目 有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 . 分隔。 例如:"0.1.2.201" 和 "192.168.1.1" 是 有效 IP 地址&…...
JS,递归,处理树形数据组件,模糊查询树形结构数据字段
JS递归如何模糊查询树形结构数据,根据数据中的某一个字段值,模糊匹配 直接拿去使用就行 function filterTreeLabel(arr, label) {let result []arr.forEach((item) > {// if (String(item.POBJECT_NAME).toLowerCase().indexOf(label)!-1) {if (String(item.P…...
前端大数字精度丢失?Choerodon UI 大数字解决方案:精确性与灵活性的结合!
01 引言 在企业项目开发中,数据的精确性是关键。Choerodon UI 的大数字解决方案,通过其高精度计算、数据一致性维护、灵活的数据交互、国际化支持、兼容性保障、定制化格式化等优势,为开发人员提供了一个强大的武器库,以确保在处…...
matlab凸包检测
% 创建一个3D点集 points [1 2 3; 4 5 6; 7 8 9; 10 11 12; 13 14 15]; % 使用convhull函数计算凸包 hull convhull(points); % 输出凸包点的索引 disp(Convex Hull Indices:); disp(hull); % 绘制点集和凸包 figure; scatter3(points(:,1), points(:,2), points(:,3),…...
单节点calico性能优化
在单节点上部署calicov3273后,发现资源占用 修改calico以下配置是资源消耗降低 1、因为是单节点,没有跨节点pod网段组网需要,禁用overlay方式网络(ipip,vxlan),使用route方式网络 配置calico-node的环境变量 CALICO_IPV4POOL_I…...
【芯片设计- RTL 数字逻辑设计入门 番外篇 7.1 -- 基于ATE的IC测试原理】
文章目录 ATE 测试概述Opens/Shorts测试Leakage测试AC测试转自:漫谈大千世界 漫谈大千世界 2024年10月23日 23:17 湖北 ATE 测试概述 ATE(Automatic Test Equipment)是用于检测集成电路(IC)功能完整性的自动测试设备。它在半导体产业中扮演着至关重要的角色,主要用于检…...
oracle 导入数据提示跳过表
imp system/orclorcl fileD:\oracle_back.dmp fully showy logD:\oracle_log.log 今天用上面的命令往 oracle 中导入数据出现一个奇怪的问题 就是所有导入的表都提示 正在跳过表XXX 最后提示成功终止导入, 没有出现警告。 最后select一个表也没导入进来 怪哉怪哉!…...
鸿蒙开发(15)案例 排行榜
排行榜 准备图片 定义案例需要的数据模型 创建Models文件, //定义app需要的数据模型export class FruitData{name:string;vote:string;id:string;constructor(id:string,name:string,vote:string,) {this.id idthis.name namethis.vote vote}}排行榜头部 创…...
【Java Web】Axios实现前后端数据异步交互
目录 一、Promise概述 二、Promise基本用法 三、async和await关键字 四、Axios介绍 4.1 Axios基本用法 4.2 Axios简化用法之get和post方法 五、Axios拦截器 六、跨域问题处理 一、Promise概述 axios是代替原生的ajax实现前后端数据交互的一套新解决方案,而…...
SLAAC如何工作?
SLAAC如何工作? IPv6无状态地址自动配置(SLAAC)-常见问题 - 苍然满关中 - 博客园 https://support.huawei.com/enterprise/zh/doc/EDOC1100323788?sectionj00shttps://www.zhihu.com/question/6691553243/answer/57023796400 主机在启动或接口UP后,发…...
微信小程序UI自动化测试实践 !
微信小程序UI自动化测试实践 引言: 随着微信小程序的快速发展,越来越多的企业和开发者开始开发小程序来满足用户的需求。而在开发小程序的过程中,UI自动化测试是一个必不可少的环节,可以帮助开发者减少人工测试的工作量ÿ…...
代码随想录-笔记-其七
我们来到了贪心算法的章节。 贪心算法和其他部分不太一样的是,他更多的是突出一种思路:通过求局部最优解来求全局最优解。因为只是一个大的思想逻辑,针对不同题型总是有不同的解决方案,所以贪心算法也不想其他算法那样有一个很经…...
react身份证回显
1. 处理身份证号的函数 function getAgeSexAndBirthdate(idCard: string): { sex: 男 | 女 | null; birthdate: Date | null } {if (idCard.length ! 18) {console.error(身份证号码必须是18位。);return { sex: null, birthdate: null };}// 提取出生年月日const year parse…...
Hibernate、JPA、Spring DATA JPA、Hibernate 代理和架构
大家好,今天,我们将讨论 Hibernate 和 JPA 架构。 在开始我们的文章之前,我想回答一个重要的问题:为什么我们需要使用 Hibernate、Eclipse Link、EF core 等 ORM 工具? 事实上,这是一个非常好的问题。我们…...
leetcode----mysql
1179. 重新格式化部门表 - 力扣(LeetCode) 表 Department: ------------------------ | Column Name | Type | ------------------------ | id | int | | revenue | int | | month | varchar | ----…...
盛元广通畜牧与水产品检验技术研究所LIMS系统
一、系统概述 盛元广通畜牧与水产品检验技术研究所LIMS系统集成了检测流程管理、样品管理、仪器设备管理、质量控制、数据记录与分析、合规性管理等功能于一体,能够帮助实验室实现全流程的数字化管理。在水产、畜牧产品的质检实验室中,LIMS系统通过引入…...
EXCEL文件解析
[Excel文件名].xlsx (解压后) │ ├── _rels │ └── .rels (定义关系文件) ├── docProps │ ├── app.xml (应用程序属性) │ └── core.xml (核心文档属性) ├── xl │ ├── _rels │ │ └── workbook.xml.rels (工作簿关系文件) │ ├── …...
【C++】- 掌握STL List类:带你探索双向链表的魅力
文章目录 前言:一.list的介绍及使用1. list的介绍2. list的使用2.1 list的构造2.2 list iterator的使用2.3 list capacity2.4 list element access2.5 list modifiers2.6 list的迭代器失效 二.list的模拟实现1. list的节点2. list的成员变量3.list迭代器相关问题3.1…...
开源 AI 智能名片 S2B2C 商城小程序中运营与产品的关系剖析
摘要:本文聚焦于开源 AI 智能名片 S2B2C 商城小程序,深入探讨其中运营与产品之间的关系。通过分析运营与产品的多种关系认知,阐述在该特定小程序情境下运营与产品相互依存、相互作用的机制,包括运营对产品的需求以及产品对运营的依…...
flask_socketio 以继承 Namespace方式实现一个网页聊天应用
点击进入上一篇,可作为参考 实验环境 python 用的是3.11.11 其他环境可以通过这种方式一键安装: pip install flask3.1.0 Flask-SocketIO5.4.1 gevent-websocket0.10.1 -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple pip list 详情如下&am…...
DePIN潜力项目Spheron解读:激活闲置硬件,赋能Web3与AI
DePIN赛道作为今年加密资本关注的热点之一,不仅吸引了大量资金涌入,还凭借其灵活的资源调配、高效的运作方式和可靠的安全性能,逐渐渗透到多个领域和项目中。例如,Helium的无线网络协议、IoTeX的去中心化物联网、IO NET的去中心化…...
《Vue进阶教程》第十六课:深入完善响应式系统之单例模式
往期内容: 《Vue进阶教程》第五课:ref()函数详解(重点) 《Vue进阶教程》第六课:computed()函数详解(上) 《Vue进阶教程》第七课:computed()函数详解(下) 《Vue进阶教程》第八课:watch()函数的基本使用 《Vue进阶教…...
C++ —— const修饰指针
C —— const修饰指针 常量指针(实际开发中用的很多)指针常量(了解即可)常指针常量(了解即可) 常量指针(实际开发中用的很多) 语法:const 数据类型 *变量名; 不能通过解…...
【学习笔记】数据结构(八)
动态存储管理 文章目录 动态存储管理8.1 概述8.2 可利用空间表及分配方法8.3 边界标识法8.3.1 可利用空间表的结构8.3.2 分配算法8.3.3 回收算法 8.4 伙伴系统8.4.1 可利用空间表的结构8.4.2 分配算法8.4.3 回收算法 8.5 无用单元收集 - 垃圾回收机制8.6 存储紧缩 - 内存碎片化…...
maven-resources-production:ratel-fast: java.lang.IndexOutOfBoundsException
Maven生产环境中遇到java.lang.IndexOutOfBoundsException的问题,尝试了重启电脑、重启IDEA等常规方法无效,最终通过直接重建工程解决了问题。 Rebuild Project 再启动OK...
建投数据与腾讯云数据库TDSQL完成产品兼容性互认证
近日,经与腾讯云联合测试,建投数据自主研发的人力资源信息管理系统V3.0、招聘管理系统V3.0、绩效管理系统V2.0、培训管理系统V3.0通过腾讯云数据库TDSQL的技术认证,符合腾讯企业标准的要求,产品兼容性良好,性能卓越。 …...
后端-添加购物车和查看购物车
...
【HarmonyOS NEXT】Web 组件的基础用法以及 H5 侧与原生侧的双向数据通讯
关键词:鸿蒙、ArkTs、Web组件、通讯、数据 官方文档Web组件用法介绍:文档中心 Web 组件加载沙箱中页面可参考我的另一篇文章:【HarmonyOS NEXT】 如何将rawfile中文件复制到沙箱中_鸿蒙rawfile 复制到沙箱-CSDN博客 目录 如何在鸿蒙应用中加…...
7-2 排序
输入一批未排序的数据,数量不超过30个,请使用选择法或者冒泡法对其排序,并按照规定的要求输出。 输入格式: 先输入待排序的整形数的个数;然后输入所有的待排序的数据。 输出格式: 在一行中按照由大到小的顺序输出排序好的数据…...
Java通过反射破坏单例模式
有个第三方工具类,不支持多例模式。但是又不能直接改第三方工具类的代码,因此可以通过反射破坏第三方工具类的单例。 第三方工具类反编译如下 可以看到构造函数进行了私有化,不允许外部new,只能通过newInstance进行实例化。并且…...
FFmpeg第一话:FFmpeg 简介与环境搭建
FFmpeg 探索之旅 一、FFmpeg 简介与环境搭建 二、FFmpeg 解码详解 第一话:FFmpeg 简介与环境搭建 FFmpeg 探索之旅一、前言二、FFmpeg 是什么?三、简单介绍其历史背景四、为什么用 C学习 FFmpeg?(一)高性能优势&#…...
C++并发编程: std::atomic对指针进行操作
std::atomic 对指针进行运算的用途 std::atomic 提供了一种在多线程环境中安全地操作指针的方法。这对于实现线程安全的指针管理、动态内存分配、链表操作等场景非常有用。通过使用std::atomic对指针进行运算,可以确保指针操作的原子性和多线程安全性。 常见用途 …...
工业大数据分析算法实战-day08
文章目录 day08模型评价聚类算法基于距离的聚类基于层次的聚类基于密度的聚类基于分布的聚类聚类结果的评价 day08 今天是第8天,昨日阐述了概率图模型和集成学习的分类,主要讲解了有向图和无向图,生成式模型和判断式模型,以及集成…...
在 C# 中实现的目录基础操作
前言 在开发应用程序过程中,对操作系统上的文件夹存储文件和子文件夹操作是常见的需求。.NET中的Directory类提供了处理文件目录的功能。本文介绍如何读取文件夹的属性、获取文件夹的大小及文件个数、创建文件夹、遍历文件夹中的所有文件、移动文件夹和删除文件夹等…...
Python 标识符是啥?
Python 的标识符就是我们写代码时用来给变量、函数、类等取名字的东西。 你写的 my_variable 是个标识符, 定义的 add_numbers 函数名也是个标识符, 甚至你写的 Cat 类名,也是标识符。 一句话总结:标识符就是代码里给“东西”起…...
WEB开发: 全栈工程师起步 - Python Flask +SQLite的管理系统实现
一、前言 罗马不是一天建成的。 每个全栈工程师都是从HELLO WORLD 起步的。 之前我们分别用NODE.JS 、ASP.NET Core 这两个框架实现过基于WebServer的全栈工程师入门教程。 今天我们用更简单的来实现: Python。 我们将用Python来实现一个学生管理应用࿰…...
将 Matplotlib 图形转换为 PIL 图像并返回
将 Matplotlib 图形转换为 PIL 图像并返回 前言完整代码Matplotlib 中 fig 和 ax 的关系示例: 问题分析常见错误及解决方案总结 前言 Matplotlib 是 Python 里最流行的图表展示库,PIL (Python Imaging Library)则是一个强大的图像处理库。在开发过程中&…...
F5中获取客户端ip地址(client ip)
当F5设备对其原始设置上的所有IP地址使用NAT时,连接到poo成员(nodes、backend servers)的出站连接将是NAT IP地址。 pool 成员(nodes、backend servers)将无法看到真实的客户端 ip地址,因为看到的是F5上的…...
点焊机器人维修-ABB-KUKA-FANUC-YASKAWA
在正式启用点焊机器人之前,一项至关重要的预备步骤便是进行焊枪的全面设置操作。以FANUC机器人为例,其焊枪的设置流程涵盖了多个关键环节,如焊枪运动方向的精确规划、焊枪规格的选择以及零点标定的细致执行等。这些设置均须严格依据实际所采用…...
springboot448教学辅助系统(论文+源码)_kaic
摘 要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱,出错率高,信息安全性差&#x…...
网络地址转换(NAT)和端口映射
1. 网络地址转换(NAT) 1.1 NAT的应用场景 (1)应用场景:允许将私有IP地址映射到公网地址,以减缓IP地址空间的消耗 ①需要连接Internet,但主机没有公网IP地址 ②更换了一个新的ISP,需要重新组织网络时&…...
iClent3D for Cesium 实现无人机巡检飞行效果
作者:gaogy 1、背景 随着地理信息技术的发展,三维地球技术逐渐成为了许多领域中的核心工具,尤其是在城市规划、环境监测、航空航天以及军事领域。三维地图和场景的应用正在帮助人们更加直观地理解空间数据,提供更高效的决策支持。…...