加载自己的图像数据集

文章目录

  • 1 加载图像数据集
  • 2 图像预处理
  • 3 再次加载数据集
  • 4 这里还有一个问题,我们没有验证集
  • 5 构建DataLoader
  • 6 检查是否正确导入数据集

原文链接:《加载自己的图像数据集》

​ 数据集下载链接

1 加载图像数据集

目录结构:

image-20230426200033333

针对这种非常典型的数据集组织方式
我们可以用torchvision.datasets.ImageFolder来加载数据集

import os
import torchvision

data_path = '.\\archive'

train_dataset = torchvision.datasets.ImageFolder(os.path.join(data_path, 'train'))

注意!这并不是把训练集中所有的图像都加载到了内存,那样太耗费内存了,仅仅是把训练集中的图像在磁盘中的存储路径加载了。

train_dataset有几个重要的属性:

# 这个是一个元组列表
# 元组的第一个元素是图像在磁盘中的路径,第二个元素是图像所属的数字标签
# 类似这样('.\\archive\\train\\dandelion\\2503034372_db7867de51_m.jpg', 1)
train_dataset.imgs

# 就是我们要预测的图像所属的数字标签列表
# 顺序和上面的元组列表顺序一样
train_dataset.targets

# 类别的中文名称
# 在这里就是那5个文件夹的名称列表
train_dataset.classes
# ['daisy', 'dandelion', 'roses', 'sunflowers', 'tulips']

# 这是一个字典
# 键为train_dataset.classes
# 值为train_dataset.targets
train_dataset.class_to_idx
# {'daisy': 0, 'dandelion': 1, 'roses': 2, 'sunflowers': 3, 'tulips': 4}

# 我们可以通过len(train_dataset)查看训练集中一共有多少样本
len(train_dataset) # 3670

我们可以查看一下第一张图像:

from PIL import Image

# 读取图像, train_dataset.imgs[0][0]是第一张图像的路径
img = Image.open(train_dataset.imgs[0][0])
img

output_5_0

2 图像预处理

前面已经看到这些图像现在都是尺寸各异,那么在正式使用这些图像之前,我们首先需要将这些图像的尺寸统一,然后还有一些其他的预处理。常见的预处理顺序是:

  1. 调整图像尺寸为模型规定的尺寸,比如3x224x224。

  2. 如果是训练集,那还要做一些数据增强操作,比如随机水平翻转图像。

  3. 将图像转成张量。自动归一化像素值在0到1之间,这样有助于高效训练CNN。

当然实际的预处理操作可能比这个多,这只是举个例子。

这些操作可以放到管道里依次执行:

import torchvision.transforms as transforms

transform = transforms.Compose([
    transforms.RandomResizedCrop(224),  # 随机缩放裁剪出224x224的区域
    transforms.RandomHorizontalFlip(),  # 在水平方向上随机翻转图像,50%的概率
    transforms.ToTensor()  # 转成张量,自动归一化到0~1
])

3 再次加载数据集

那么现在加载数据集的正确方式就是:

import os
import torchvision
import torchvision.transforms as transforms

# 如果遇到损坏的图像则跳过
from PIL import ImageFile

ImageFile.LOAD_TRUNCATED_IMAGES = True

data_path = '.\\archive'

train_transform = transforms.Compose([
    transforms.RandomResizedCrop(224),  # 随机缩放裁剪出224x224的区域
    transforms.RandomHorizontalFlip(),  # 在水平方向上随机翻转图像,50%的概率
    transforms.ToTensor()  # 转成张量,自动归一化到0~1
])

# 测试集的transform仅仅是缩放图像到合适尺寸并在转成张量
test_transform = transforms.Compose([
    transforms.Resize(256),  # 缩放到256x256的大小,因为后面要裁剪成224x224
    transforms.CenterCrop(224),  # 从中心裁剪成224x224的大小
    transforms.ToTensor()
])

train_dataset = torchvision.datasets.ImageFolder(
    os.path.join(data_path, 'train'), transform=transform)

test_dataset = torchvision.datasets.ImageFolder(
    os.path.join(data_path, 'test'), transform=transform)

注意!训练集和测试集用了不同的transforms。因为在训练模型时我们需要用到tranforms来帮助我们实现数据增强(Data Augmentation)来减小模型过拟合的可能性。

4 这里还有一个问题,我们没有验证集

利用torch.utils.data.random_split可以帮助我们划分数据集,而且是保持数据集中每个类别的数据量比例不变。

import torch

# 从train_dataset中抽取80%作为训练集
num_train = int(0.8 * len(train_dataset))
# 余下20%作为验证集
num_val = int(0.2 * len(train_dataset))

# torch.manual_seed(0) 为了方便复现设置的随机抽样生成器
train, val = torch.utils.data.random_split(
    train_dataset, [num_train, num_val], torch.manual_seed(0))

5 构建DataLoader

有了数据集之后我们还要批量的将数据集真正加载到内存/显存:

from torch.utils.data import DataLoader

train_dl = DataLoader(train, batch_size=128, shuffle=True)
val_dl = DataLoader(val, batch_size=128, shuffle=False)
test_dl = DataLoader(test_dataset, batch_size=128, shuffle=True)

batch_size参数表示一次性加载多少张图像(样本)进入内存。

shuffle表示是否对数据集中的图像(样本)进行混洗。

6 检查是否正确导入数据集

别忘了随机检查几份样本观察一下正确导入了数据集哦,对于图像数据集,那么就是直接画出来看:

import matplotlib.pyplot as plt

imgs, labels = next(iter(train_dl))  # 从train_dl中取出一个批次的数据, iter()是生成器, next()是迭代器
figure = plt.figure(figsize=(10, 8))
cols, rows = 3, 3
for i in range(1, cols * rows + 1):
    img, label = imgs[i], labels[i]  # imgs[i]是第i张图像, labels[i]是第i张图像的标签
    figure.add_subplot(rows, cols, i)
    plt.title(train_dataset.classes[label])
    plt.axis("off")
    # img.permute(1, 2, 0)是将张量的维度换位, 使得第0维度在最后, 以便于matplotlib显示,
    # 因为matplotlib显示的是RGB图像, 而pytorch的图像是CHW格式, 所以需要将CHW转换为HWC
    plt.imshow(img.permute(1, 2, 0))
plt.show()

output_17_0

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

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

相关文章

while语句和until语句顺便带点小实验

while语句和until语句 一、while用法二、Until循环语句三、趣味小实验猜价格的游戏(价格是随机数)写一个计算器脚本闲来无事去购物 一、while用法 for循环语句非常适用于列表对象无规律,且列表来源以固定(如某个列表文件&#xf…

nginx配置sh脚本远程执行一键安装

背景 本地多机重复操作某些shell指令,分步执行,很耗费时间, 需要远程一键部署,傻瓜化运维,更为通用安装。 即参考docker通用安装 sudo curl https://get.docker.com | sh - # sudo python3 -m pip install docker-co…

Design_transformer

磁性元件设计 思路 滤波电感设计 磁芯不要饱和(开气隙) 考虑铜损大于铁损 谐振电感设计 磁芯不要饱和(开气隙) 考虑铁损大于铜损 变压器设计 磁芯不要饱和(开气隙) 励磁电流产生磁场 开气隙 增加了…

FreeRTOS系统学习-内核篇.01-数据结构---列表与列表项定义详解-链表节点插入实验

# 内核篇.01 列表与列表项 为什么要学列表?链表单向链表双向链表 FreeRTOS 中链表的实现节点节点初始化尾节点根节点链表根节点初始化将节点插入到链表的尾部将节点按照升序排列插入到链表将节点从链表删除节点带参宏小函数 链表节点插入实验实验现象 为什么要学列表…

内存优化-比glibc更快的tcmalloc

TCMalloc 是 Google 开发的内存分配器,在不少项目中都有使用,例如在 Golang 中就使用了类似的算法进行内存分配。它具有现代化内存分配器的基本特征:对抗内存碎片、在多核处理器能够 scale。据称,它的内存分配速度是 glibc2.3 中实…

vue3表单输入绑定

初识表单输入绑定 vue3可以帮助我们将vue定义的变量绑定到html表单元素上&#xff0c;并且监听到html表单元素修改值时&#xff0c;会将对应的vue定义的变量修改。 <!-- 将vue3定义的text绑定给inut元素, 当input元素发生input输入事件时, 将修改vue3定义的text --> <…

WeakMap 与 WeakSet

WeakSet WeakSet 结构与 Set 类似&#xff0c;也是不重复的值的集合。 成员都是数组和类似数组的对象&#xff0c;WeakSet 的成员只能是对象&#xff0c;而不能是其他类型的值。 若调用 add() 方法时传入了非数组和类似数组的对象的参数&#xff0c;就会抛出错误。 const b …

SpringBoot + Druid DataSource 实现监控 MySQL 性能

1 添加依赖 <properties><java.version>1.8</java.version><alibabaDruidStarter.version>1.2.11</alibabaDruidStarter.version> </properties><dependency><groupId>com.alibaba</groupId><artifactId>druid-s…

MYSQL进阶02

MYSQL进阶02 数据类型char与varchartext与blob浮点数与定点数日期类型的选择 数据类型 char与varchar char和varchar类型类似&#xff0c;都用来存储字符串&#xff0c;但是他们保存和检索的方式不同。char属于固定长度的字符类型&#xff0c;而varchar属于可变长度的字符类型…

【Java校招面试】基础知识(四)——JVM

目录 前言一、基础概念二、反射三、类加载器ClassLoader四、JVM内存模型后记 前言 本篇主要介绍Java虚拟机——JVM的相关内容。 “基础知识”是本专栏的第一个部分&#xff0c;本篇博文是第四篇博文&#xff0c;如有需要&#xff0c;可&#xff1a; 点击这里&#xff0c;返回…

营收、利润增速第一!海尔智家为何领跑?

“企业只有保持领先的能力&#xff0c;才有可能取得经济成果。” 管理学大师德鲁克曾如此强调。所谓“领先”&#xff0c;就是独一无二的、有价值的东西。利润&#xff0c;是企业在某个领域取得领先优势后&#xff0c;必然获得的回报。 这种“领先优势”&#xff0c;在各行业…

Linux基础IO【重定向及缓冲区理解】

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; Linux学习之旅 &#x1f383;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 文章目录 &#x1f307;前言&#x1f3d9;️正文1、文件描述符1.1、先描述&#xff0c;再组织1.2、files_struct1.3、分配规则…

跨平台Office文档预览原生插件,非腾讯X5,支持离线,稳定高可用

引言 2023年4月13日零时起&#xff0c;腾讯浏览服务内核文档能力正式下线&#xff0c;要实现真正离线文档预览&#xff0c;于是有了这边文章。 前面写了多篇关于<跨平台文件在线预览解决方案>&#xff0c;不管使用pdf.js、LibreOffice&#xff0c;还是永中DCS&#xff…

单列文本数据快速导入表格

文本数据导入Excel似乎是个老生常谈&#xff0c;方法也有很多&#xff0c;例如 使用文本编辑器打开文本文件&#xff0c;拷贝粘贴到Excel然后分类Power Query中的【从文本/CSV】如下图所示。 但是这个需求略有不同&#xff0c;文本数据为单列&#xff0c;每7行数据为一组&am…

MYSQL-数据库管理(下)

查看数据库信息 show database 查看数据库中的表信息 use 数据库名 #切换到书库中 show tables show tables in mysql 显示数据表的结构&#xff08;字段&#xff09; describe user; Field:字段名称 type:数据类型 Null :是否允许为空 Key :主键 Type:数据类型 Null :是否…

缓存空间优化实践

导读 缓存 Redis&#xff0c;是我们最常用的服务&#xff0c;其适用场景广泛&#xff0c;被大量应用到各业务场景中。也正因如此&#xff0c;缓存成为了重要的硬件成本来源&#xff0c;我们有必要从空间上做一些优化&#xff0c;降低成本的同时也会提高性能。 下面以我们的案…

【Git】Gitee免密push(TencentCloudLinux)

前提&#xff1a; 我用的是腾讯云的Centos(Linux)服务器 我创建好了仓库 我配置过git 可以正常用密码push 以上自行解决 我们直接配置公钥解决免密push 1.在服务器上创建公钥 在用户根目录创建 公钥 邮箱写自己的 随意写 我写的是gitee绑定的邮箱 ssh-keygen -t ed25519 -C…

数据结构(六)—— 二叉树(2)遍历

文章目录 递归三要素一、深度优先遍历&#xff08;前中后序&#xff09;1.1 递归遍历1.1.1 前序&#xff08;中左右&#xff09;1.1.2 中序&#xff08;左中右&#xff09;1.1.3 后序&#xff08;左右中&#xff09; 1.2 迭代遍历1.2.1 前序1.2.2 后序1.2.3 中序 二、广度优先遍…

Renesas瑞萨A4M2和STM32 CAN通信

刚好拿到一块瑞萨开发板&#xff0c;捣鼓玩下CAN&#xff0c;顺便试下固件升级。 A4M2 工程创建 详细可以参考&#xff0c;我之前写的文章 Renesa 瑞萨 A4M2 移植文件系统FAT32 CAN0 配置信息&#xff0c;使能FIFO&#xff0c;接收标准帧 ID为0x50&#xff0c;数据帧。 代…

密码学【java】初探究加密方式之对称加密

文章目录 一 常见加密方式二 对称加密2.1 Cipher类简介2.2 Base算法2.3 补充&#xff1a;Byte&bit2.4 DES加密演示2.5 DES解密2.6 补充&#xff1a;对于IDEA控制台乱码的解决方法2.7 AES加密解密2.8 补充&#xff1a; toString()与new String ()用法区别2.9 加密模式2.9.1 …