2025-05-21 Python&深度学习5——数据读取

[复制链接]
发表于 2025-5-24 21:46:30 | 显示全部楼层 |阅读模式
本文环境:
  

  • Pycharm 2025.1
  • Python 3.12.9
  • Pytorch 2.6.0+cu124
  1 数据准备

​ 数据集放在 dataset 路径下,其中 train 文件夹存放训练数据,包括 ants 和 bees,val 文件夹存放测试数据,包括 ants 和 bees。
​ 训练数据为多少个 .jpg 图片。


  • 数据集下载链接:https://pan.baidu.com/s/1jZoTmoFzaTLWh4lKBHVbEA;密码: 5suq。
  • 参考教程视频链接:P7. TensorBoard的利用(一)_哔哩哔哩_bilibili。
2 Dataset

​ Dataset 是抽象类,界说数据泉源及单样本读取逻辑,所有自界说的 Dataset 均需要继承它。
​ 必须实现的方法:


  • __getitem__(self, index):根据索引返回(样本, 标签)。
  • __len__(self):返回数据集巨细。
2.1 自界说 Dataset

  1. import os
  2. from PIL import Image
  3. from torch.utils.data import Dataset
  4. class MyData(Dataset):
  5.     def __init__(self, root_dir, label_dir):
  6.         # 初始化函数,传入根目录和标签目录
  7.         self.root_dir = root_dir  # 数据集根目录
  8.         self.label_dir = label_dir  # 标签目录(也是类别名)
  9.         # 拼接完整路径
  10.         self.path = os.path.join(self.root_dir, self.label_dir)
  11.         # 获取该路径下所有图片文件名
  12.         self.img_path = os.listdir(self.path)
  13.     def __getitem__(self, index):
  14.         # 根据索引获取图片名
  15.         img_name = self.img_path[index]
  16.         # 拼接图片完整路径
  17.         img_item_path = os.path.join(self.path, img_name)
  18.         # 使用PIL打开图片
  19.         img = Image.open(img_item_path)
  20.         # 标签就是目录名(如"ants"或"bees")
  21.         label = self.label_dir
  22.         return img, label  # 返回图片和标签
  23.     def __len__(self):
  24.         # 返回数据集大小(图片数量)
  25.         return len(self.img_path)
复制代码

  • __init__()


  • 吸收两个参数:root_dir(根目次)和label_dir(标签目次)。
  • 利用os.path.join拼接完整路径。
  • os.listdir获取该目次下所有文件名列表。

  • __getitem__()

    • 根据索引获取对应图片。
    • 利用 PIL.Image 打开图片。
    • 标签直接利用目次名(简单示例中)。
    • 返回(图片, 标签)元组。

  • __len__()

    • 返回数据集巨细(图片数量)。
    • 用于 DataLoader 确定迭代次数。

2.2 利用示例

  1. # 定义路径
  2. root_dir = "dataset/train"  # 训练集根目录
  3. ants_label_dir = "ants"    # 蚂蚁图片目录
  4. bees_label_dir = "bees"    # 蜜蜂图片目录
  5. # 创建数据集实例
  6. ants_dataset = MyData(root_dir, ants_label_dir)
  7. bees_dataset = MyData(root_dir, bees_label_dir)
  8. # 合并数据集(实际应该使用ConcatDataset)
  9. train_dataset = ants_dataset + bees_dataset  # 简单合并
复制代码
​ 示例中直接利用+合并数据集不是很规范,PyTorch 提供ConcatDataset类来正确合并多个 Dataset:
  1. from torch.utils.data import ConcatDataset
  2. train_dataset = ConcatDataset([ants_dataset, bees_dataset])
复制代码
3 TensorBoard

​ TensorBoard 是 TensorFlow 提供的可视化工具,PyTorch 通过torch.utils.tensorboard模块也支持利用 TensorBoard。它可以帮助我们:


  • 监控监控训练过程中的指标厘革(如损失、正确率)。
  • 可视化模子结构。
  • 查看图像、音频等数据。
  • 分析参数分布和直方图。
3.1 安装

​ 利用以下下令进行安装:
  1. pip install tensorboard
复制代码

​ 基本利用流程如下:

  • 创建SummaryWriter实例。
  • 利用各种add_*方法记录数据。
  • 关闭SummaryWriter。
  • 启动 TensorBoard 服务查看结果。
3.2 标量可视化(Scalars)

add_scalar(tag, scalar_value, global_step)


  • tag: 数据标识(图表标题)。
  • scalar_value: 要记录的标量值。
  • global_step: 训练步数/迭代次数。
  1. from torch.utils.tensorboard import SummaryWriter
  2. writer = SummaryWriter("logs")  # 日志日志保存到logs目录
  3. for i in range(100):
  4.     writer.add_scalar("y=2x", 2*i, i)  # 记录y=2x函数值
  5.    
  6. writer.close()
复制代码
​ 上述代码运行后,在当前目次下会生成 logs 目次,内里存放 TensorBoard 的可视化数据。
​ 进入 Pycharm 终端,在下令行运行如下下令:
  1. tensorboard --logdir=Pytorch教程/logs --port=6006
复制代码


  • logdir:可视化数据的存储路径在哪里。
  • port:从哪个端口打开可视化网页。
​ 在浏览器访问http://localhost:6006即可查看可视化结果。
   注意
  ​ 请确保从 cmd 中输入下令,而不是 Powershell。
  ​ 若出现如下报错,阐明利用 Powershell 打开而不是 cmd。
  
  办理方案
  ​ 打开 Pycharm 的设置选项,进入“终端”页面,将默认页签更改为 cmd.exe,重新在 Pycharm 中打开终端即可。
  
  3.3 图像可视化(Images)

add_image(tag, img_tensor, global_step, dataformats)


  • tag: 数据标识(图表标题)。
  • img_tensor: 图像数据(numpy 数组或 torch tensor)。
  • global_step: 训练步数/迭代次数。
  • dataformats: 指定命据格式,如 ‘HWC’(高度、宽度、通道)。
  1. from PIL import Image
  2. import numpy as np
  3. img_PIL = Image.open("image.jpg")
  4. img_array = np.array(img_PIL)  # 转换为numpy数组
  5. writer.add_image("train", img_array, 1, dataformats='HWC')
复制代码
​ 上述代码运行后,在可视化网页中点击革新,即可表现图像。
3.4 其他常勤奋能



  • add_graph(): 可视化模子结构。
  • add_histogram(): 记录参数分布。
  • add_text(): 记录文本信息。
  • add_embedding(): 可视化高维数据降维结果。
4 transform

​ torchvision.transforms 是 PyTorch 中用于图像预处置惩罚的强大工具包,提供丰富的图像转换操作。主要功能包括:


  • 图像格式转换(如 PIL Image ↔ Tensor)。
  • 图像尺寸调整(缩放、裁剪)。
  • 数据加强(翻转、旋转、颜色变换)。
  • 数据标准化。
4.1 ToTensor()



  • 将 PIL/Numpy 图像转为 PyTorch Tensor。
  • 将像素值从 [0, 255] 缩放到 [0.0, 1.0]。
  • 调整维度次序为 (C, H, W)。
  1. from PIL import Image
  2. from torch.utils.tensorboard import SummaryWriter
  3. from torchvision import transforms
  4. writer = SummaryWriter("logs")
  5. img = Image.open("image/pytorch.png")
  6. print(img)
  7. # ToTensor
  8. tensor_trans = transforms.ToTensor()
  9. tensor_img = tensor_trans(img)
  10. writer.add_image("Tensor_img", tensor_img)
  11. print(tensor_img)  # 输出形状为(C, H, W)的tensor,值范围[0,1]
  12. writer.close()
复制代码
4.2 Normalize()

​ 逐 Channel 对图像进行标准化。


  • mean:各通道的均值。
  • std:各通道的标准差。
  • inplace:是否原地操作。
   

  • 利用公式:output = (input - mean) / std。
  • 此处将 [0, 1] 范围的数据转换到 [-1, 1] 范围。
  • 注意:必须先转换为 Tensor 才能利用 Normalize。
  1. from PIL import Image
  2. from torch.utils.tensorboard import SummaryWriter
  3. from torchvision import transforms
  4. writer = SummaryWriter("logs")
  5. img = Image.open("image/pytorch.png")
  6. print(img)
  7. # ToTensor
  8. tensor_trans = transforms.ToTensor()
  9. tensor_img = tensor_trans(img)
  10. # Normalize
  11. normalize = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
  12. normalize_img = normalize(tensor_img)
  13. writer.add_image("Normalize_img", normalize_img)
  14. print(normalize_img)
  15. writer.close()
复制代码
4.3 Resize()



  • 将图像调整为指定尺寸 (512x512)。
  1. from PIL import Image
  2. from torch.utils.tensorboard import SummaryWriter
  3. from torchvision import transforms
  4. writer = SummaryWriter("logs")
  5. img = Image.open("image/pytorch.png")
  6. print(img)
  7. # ToTensor
  8. tensor_trans = transforms.ToTensor()
  9. tensor_img = tensor_trans(img)
  10. # Resize
  11. resize = transforms.Resize((512, 512))
  12. resize_img = resize(tensor_img)
  13. writer.add_image("Resize_img", resize_img)
  14. print(tensor_img)
  15. writer.close()
复制代码
4.4 Compose()



  • 将多个转换步调按次序组合。
  • 执行次序:先 Resize 再 ToTensor。
  1. from PIL import Image
  2. from torch.utils.tensorboard import SummaryWriter
  3. from torchvision import transforms
  4. writer = SummaryWriter("logs")
  5. img = Image.open("image/pytorch.png")
  6. print(img)
  7. # Compose
  8. compose = transforms.Compose([
  9.     transforms.Resize((512, 512)),
  10.     transforms.ToTensor()
  11. ])
  12. compose_img = compose(img)
  13. writer.add_image("Compose_img", compose_img)
  14. print(compose_img)
  15. writer.close()
复制代码
4.5 Crop

RandomCrop()

​ 从图片中随机裁剪出尺寸为 size 的图片。


  • size:所需裁剪图片尺寸。
  • padding:设置填充巨细。

    • 当为a时,上下左右均填充 a 个像素。
    • 当为 (a, b) 时,上下填充 b 个像素,左右填充 a 个像素。
    • 当为 (a, b, c, d) 时,左,上,右,下分别填充 a, b, c, d。

  • pad_if_needed:若图像小于设定 size,则填充。
  1. from PIL import Image
  2. from torch.utils.tensorboard import SummaryWriter
  3. from torchvision import transforms
  4. writer = SummaryWriter("logs")
  5. img = Image.open("image/pytorch.png")
  6. print(img)
  7. # ToTensor
  8. tensor_trans = transforms.ToTensor()
  9. tensor_img = tensor_trans(img)
  10. # RandomCrop
  11. random_crop = transforms.RandomCrop((512, 512))
  12. random_crop_img = random_crop(tensor_img)
  13. writer.add_image("RandomCrop_img", random_crop_img)
  14. print(random_crop_img)
  15. writer.close()
复制代码
CenterCrop()

​ 从图像中心裁剪图片。
• size:所需裁剪图片尺寸。
RandomResizedCrop()

​ 随机巨细、长宽比裁剪图片。


  • size:所需裁剪图片尺寸。
  • scale:随机裁剪面积比例,默认 (0.08, 1)。
  • ratio:随机长宽比,默认(3/4, 4/3)。
  • interpolation:插值方法。

    • PIL.Image.NEAREST。
    • PIL.Image.BILINEAR。
    • PIL.Image.BICUBIC。

FiveCrop() / TenCrop()

​ FiveCrop 在图像的上下左右以及中心裁剪出尺寸为 size 的 5 张图片;
​ TenCrop 对这 5 张图片进行水平大概垂直镜像得到 10 张图片.


  • size:所需裁剪图片尺寸。
  • vertical_flip:是否垂直翻转。
4.6 RandomHorizontalFlip() / RandomVerticalFlip()

​ 依概率水平(左右)或垂直(上下)翻转图片。


  • p:翻转概率。
  1. from PIL import Image
  2. from torch.utils.tensorboard import SummaryWriter
  3. from torchvision import transforms
  4. writer = SummaryWriter("logs")
  5. img = Image.open("image/pytorch.png")
  6. print(img)
  7. # ToTensor
  8. tensor_trans = transforms.ToTensor()
  9. tensor_img = tensor_trans(img)
  10. # RandomHorizontalFlip
  11. random_flip = transforms.RandomHorizontalFlip(1)
  12. random_flip_img = random_flip(tensor_img)
  13. writer.add_image("RandomFlip_img", random_flip_img)
  14. print(random_flip_img)
  15. writer.close()
复制代码
4.7 Random

RandomChoice()

​ 从一系列 transforms 方法中随机挑选一个。
  1. transforms.RandomChoice([transforms1, transforms2, transforms3])
复制代码
RandomApply()

​ 依据概率执行一组 transforms 操作。
  1. transforms.RandomApply([transforms1, transforms2, transforms3], p=0.5)
复制代码
RandomOrder()

​ 对一组 transforms 操作打乱次序。
  1. transforms.RandomOrder([transforms1, transforms2, transforms3])
复制代码
4.8 自界说 transforms

​ 自界说 transforms 要素:

  • __init__():初始化方法。
  • __call__:执行方法。
  1. class YourTransforms(object):
  2.    
  3.     def __init__(self, ...):
  4.         ...
  5.     def __call__(self, img):
  6.         ...
  7.         return img
复制代码
以 RandomChoice为例:
注意


  • 仅吸收一个参数,返回一个参数。
  • 注意上下游的输出与输入。
4.9 其他



  • Pad():对图片边缘进行填充。
  • ColorJitter():调整亮度、对比度、饱和度和色相。
  • Grayscale() / RandomGrayscale():依概率将图片转换为灰度图。
  • RandomAffine():对图像进行仿射变换。
    仿射变换是二维的线性变换,由五种基本原子变换构成,分别是旋转、平移、缩放、错切和翻转。
  • RandomErasing():对图像进行随机遮挡。
  • Lambda():用户自界说 Lambda 方法。
5 torchvision 中的数据集

​ 官方文档:Datasets — Torchvision 0.22 documentation。
5.1 CIFAR10 数据集

​ 以 CIFAR10 为例:CIFAR10 — Torchvision 0.22 documentation。打开文档链接,以下是 CIFAR10 的创建方法。
​ 进入主页,可观看数据集详细先容。


  • 包含 60,000 张 32×32 像素的 RGB 彩色图像,分为 10 个种别(飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船、卡车),每类 6,000 张。

    • 训练集
      50,000 张图像,分为 5 个批次(data_batch_1 至 data_batch_5),每批 10,000 张。每个种别在训练会合共 5,000 张图像,但单个批次内种别分布大概不均匀。
    • 测试集
      10,000 张图像(test_batch),每个种别均匀包含 1,000 张随机选择的图像,且与训练集无重叠。

  • 种别间完全互斥,比方“汽车”与“卡车”不重叠(汽车含轿车 / SUV,卡车仅含大型货车)。
5.2 数据加载



  • torchvision.datasets.CIFAR10
    PyTorch 内置的 CIFAR-10 数据集加载接口。

    • root='./dataset':数据集存储路径(若不存在会主动创建)。
    • train=True/False:分别加载训练集(50,000 张)或测试集(10,000 张)。
    • transform=None:吸收 PIL 图像并返回转换后的版本的函数/转换。
    • target_transform=None:吸收目标并对其进行转换的函数/转换。
    • download=True:主动下载数据集(若本地不存在)。

  1. import torchvision
  2. # 定义数据集的转换方式
  3. dataset_transform = torchvision.transforms.Compose([
  4.     torchvision.transforms.ToTensor(),
  5. ])
  6. # 加载训练集
  7. train_set = torchvision.datasets.CIFAR10(
  8.     root='./dataset',  # 数据集的根目录
  9.     train=True,  # 是否为训练集
  10.     transform=dataset_transform,  # 数据集的转换方式
  11.     download=True  # 是否下载数据集
  12. )
  13. # 加载测试集
  14. test_set = torchvision.datasets.CIFAR10(
  15.     root='./dataset',  # 数据集的根目录
  16.     train=False,  # 是否为训练集
  17.     transform=dataset_transform,  # 数据集的转换方式
  18.     download=True  # 是否下载数据集
  19. )
复制代码
5.3 数据格式



  • 未启用transform时
    test_set[0]返回 PIL.Image 对象和标签(整数)。
    1. # 打印测试集的第一个样本
    2. print(test_set[0])
    3. # 获取测试集的第一个样本的图像和标签
    4. img, target = test_set[0]
    5. # 打印图像
    6. print(img)
    7. # 打印标签
    8. print(target)
    复制代码

  • 启用transform=ToTensor()后
    图像转为 Tensor 格式(外形为 [3, 32, 32],值域 [0, 1])。
    1. # 获取测试集的第一个样本的图像和标签
    2. img, target = test_set[0]
    3. # 打印图像
    4. print(img.shape)
    5. # 打印标签
    6. print(target)
    复制代码

  • test_set.classes:直接输出 10 个种别的名称列表。
    1. # 打印测试集的类别
    2. print(test_set.classes)
    复制代码

5.4 可视化

  1. # 创建一个SummaryWriter对象,用于记录训练过程中的数据
  2. writer = SummaryWriter("logs")
  3. # 遍历测试集
  4. for i in range(10):
  5.     # 获取测试集中的第i个样本
  6.     img, target = test_set[i]
  7.     # 将第i个样本的图像添加到SummaryWriter中
  8.     writer.add_image("test_set", img, i)
  9.    
  10. writer.close()
复制代码
6 DataLoader

功能:构建可迭代的数据装载器。
​ 常用参数:


  • dataset:Dataset 类,决定命据从哪读取及怎样读取。
  • batch_size:批巨细。
  • shuffle:每个 Epoch 是否乱序。
  • num_workers:是否多历程读取数据,0 表现利用主线程读取。
  • drop_last:当样本数不能被 batch_size 整除时,是否舍弃末了一批数据。
   

  • Epoch:所有训练样本都已输入到模子中,称为一个 Epoch。
  • Iteration:一批样本输入到模子中,称之为一个 Iteration。
  • Batchsize:批巨细,决定一个 Epoch 有多少个 Iteration。
  样本总数:80,Batchsize:8
  

  • 1 Epoch 10 Iteration
  样本总数:87,Batchsize:8
  

  • drop_last = True:1 Epoch = 10 Iteration
  • drop_last = False:1 Epoch = 11 Iteration
  ​ 其他参数


  • sampler:自界说采样战略(如按权重采样,与 shuffle 互斥)。
  • batch_sampler:直接生成批次索引(与 batch_size/shuffle/sampler 互斥)。
  • collate_fn:自界说批次合并逻辑(处置惩罚非规则数据,如变长序列)。
  • pin_memory:是否将数据复制到 CUDA 固定内存(加速 GPU 数据传输)。
  • timeout:从 worker 收集数据的超时时间(秒,0=无超时)。
  • worker_init_fn:每个 worker 的初始化函数(常用于设置随机种子)。
  • multiprocessing_context:多历程上下文(如 'spawn'/'fork',影响历程启动方式)。
  • generator:控制随机采样的随机数生成器(RNG)。
  • prefetch_factor:每个 worker 预加载的批次数量(默认 2,仅 num_workers>0 生效)。
  • persistent_workers:是否保持 worker 历程存活(制止重复初始化开销)。
  • pin_memory_device:指定固定内存的装备(如 'cuda:0')。
  • in_order:是否强制按 FIFO 次序返回批次(num_workers>0 时生效)。
6.1 读取数据

​ 以 CIFAR10 测试集为例,共包含 10000 个样本。
  1. import torchvision
  2. from torch.utils.data import DataLoader
  3. # 加载CIFAR10测试数据集
  4. test_data = torchvision.datasets.CIFAR10(
  5.     root='./dataset',  # 数据集的根目录
  6.     train=False,  # 是否为训练集
  7.     transform=torchvision.transforms.ToTensor(),  # 数据预处理
  8. )
复制代码
​ 设置batch_size=4,即每次读取 4 个样本,而且drop_last=False。
  1. # 创建数据加载器
  2. test_loader = DataLoader(
  3.     dataset=test_data,  # 数据集
  4.     batch_size=4,  # 每个batch的大小
  5.     shuffle=True,  # 是否打乱数据
  6.     num_workers=0,  # 加载数据的线程数
  7.     drop_last=False  # 是否丢弃最后一个batch
  8. )
复制代码
​ 遍历 test_loader 以得到每批次的数据,
  1. i = 0
  2. # 遍历test_loader中的数据
  3. for data in test_loader:
  4.     i += 1
  5.     imgs, targets = data  # 获取每批次的数据与标签
  6.     print(i, "  ", imgs.shape)
  7.     print(targets)
复制代码


  • 数据集一共 10000 个样本,每批次取出 4 个,因此序号为 10000 / 4 = 2500。
  • 每个批次的张量外形为 torch.Size([4, 3, 32, 32]),是 4 个 torch.Size([3, 32, 32]) 的组合。
  • targets 为包含 4 个元素的列表,每个元素表现对应位置的数据标签。
6.2 可视化

​ 设置batch_size=64,而且drop_last=False。
  1. import torchvision
  2. from torch.utils.data import DataLoader
  3. from torch.utils.tensorboard import SummaryWriter
  4. # 加载CIFAR10测试数据集
  5. test_data = torchvision.datasets.CIFAR10(
  6.     root='./dataset',  # 数据集的根目录
  7.     train=False,  # 是否为训练集
  8.     transform=torchvision.transforms.ToTensor(),  # 数据预处理
  9. )
  10. # 创建数据加载器
  11. test_loader = DataLoader(
  12.     dataset=test_data,  # 数据集
  13.     batch_size=64,  # 每个batch的大小
  14.     shuffle=True,  # 是否打乱数据
  15.     num_workers=0,  # 加载数据的线程数
  16.     drop_last=False  # 是否丢弃最后一个batch
  17. )
复制代码
​ 利用 tensorboard 可视化每个批次。
  1. writer = SummaryWriter('logs')
  2. step = 0
  3. # 遍历test_loader中的数据
  4. for data in test_loader:
  5.     # 获取每批次的数据与标签
  6.     imgs, targets = data
  7.     # 将imgs写入tensorboard
  8.     writer.add_images('test_data', imgs, step)
  9.     step += 1
  10. writer.close()
复制代码
​ 拖动滑动条,可看见第 32 step 的批次图像如下。
​ 将滑动条拖动到最右侧,发现该批次只剩余 16 张图像,因为 10000 % 64 = 16。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

© 2001-2025 Discuz! Team. Powered by Discuz! X3.5

GMT+8, 2025-7-10 02:42 , Processed in 0.094684 second(s), 31 queries 手机版|qidao123.com技术社区-IT企服评测▪应用市场 ( 浙ICP备20004199 )|网站地图

快速回复 返回顶部 返回列表