Python打卡第39天

📅 发布时间:2026/10/15 14:04:02
Python打卡第39天
浙大疏锦行Dataset 与 DataLoader 详解本文为 PyTorch 入门学习笔记讲解 Dataset、DataLoader 核心概念搭配 MNIST 手写数字数据集案例理解分批训练思想。一、为什么需要 Dataset DataLoader当数据集规模很大显存一次性装不下全部数据不能一次性把所有图片送入网络训练。 解决方案分批训练。 PyTorch 提供两个核心组件配合完成数据加载Dataset定义单个样本怎么读取、去哪里找、怎么做预处理厨师负责处理每一份原材料DataLoader在 Dataset 基础上自动打包成 batch 批次、支持打乱、多线程加载服务员把做好的菜按份打包送上MNIST 数据集介绍 60000 张训练图片 10000 张测试图片单张尺寸28×28灰度图一共 10 个类别数字 0~9。 数据维度很小既可以用 MLP 多层感知机训练也可以用 CNN 卷积网络训练。二、torchvision 库简介torchvision是 PyTorch 配套的计算机视觉工具库专门处理图像相关任务torchvision ├── datasets # 内置经典视觉数据集MNIST、CIFAR等 ├── transforms # 图像预处理管道裁剪、翻转、归一化等 ├── models # 预训练模型ResNet、YOLO等 ├── utils # 视觉工具函数目标检测后处理 └── io # 图像/视频读写三、完整 MNIST 数据集加载代码1. 导入依赖import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader, Dataset from torchvision import datasets, transforms import matplotlib.pyplot as plt # 设置随机种子保证实验结果可复现 torch.manual_seed(42)2. 图像预处理流水线 Composetransforms.Compose相当于预处理管道按顺序执行操作transform transforms.Compose([ transforms.ToTensor(), # PIL图片转张量像素值从0~255缩放到0~1 transforms.Normalize((0.1307,), (0.3081,)) # Z-score标准化减均值除以标准差 ])MNIST 的均值 0.1307、标准差 0.3081 是整个训练集统计出来的固定值直接复用。 PyTorch 设计思路数据加载阶段就完成预处理不是拿到 batch 之后再处理。3. 加载内置 MNIST 数据集# 训练集自动下载 train_dataset datasets.MNIST( root./data, trainTrue, downloadTrue, transformtransform ) # 测试集 test_dataset datasets.MNIST( root./data, trainFalse, transformtransform )4. 从 Dataset 取单张样本查看# 随机挑选一张图片索引 sample_idx torch.randint(0, len(train_dataset), size(1,)).item() # 索引取值自动调用__getitem__返回(图像张量, 标签) image, label train_dataset[sample_idx]原理datasets.MNIST继承Dataset抽象基类train_dataset[索引]语法会自动调用魔术方法__getitem__(idx)。四、Dataset 抽象基类核心原理所有自定义数据集必须继承 Dataset并且强制实现两个魔术方法__len__()len(数据集)时自动调用返回样本总数量__getitem__(idx)数据集[idx]索引取值时自动调用根据索引返回单条样本(img, target)魔术方法不需要手动直接调用Python 在对应语法时自动执行。魔术方法极简演示class MyList: def __init__(self): self.data [10, 20, 30, 40, 50] # 索引取值自动调用 def __getitem__(self, idx): return self.data[idx] # len()函数自动调用 def __len__(self): return len(self.data) my_list_obj MyList() print(my_list_obj[2]) # 自动调用__getitem__输出30 print(len(my_list_obj)) # 自动调用__len__输出4手写简化版 MNIST Dataset理解底层class MNIST(Dataset): def __init__(self, root, trainTrue, transformNone): # 加载全部图片路径列表、标签列表 self.data, self.targets fetch_mnist_data(root, train) self.transform transform def __len__(self): # 返回样本总数len(dataset)触发 return len(self.data) def __getitem__(self, idx): # dataset[idx]自动执行取单条路径标签 img, target self.data[idx], self.targets[idx] # 执行图像预处理 if self.transform is not None: img self.transform(img) # 返回处理好的图片张量 真实标签 return img, target五、可视化图像反归一化送入模型的张量经过标准化数值不是 0~255直接画图会颜色异常可视化时需要反标准化还原。def imshow(img, label): # 反标准化 x x_norm * std mean img img * 0.3081 0.1307 img torch.clamp(img, 0, 1) # 截断防止数值越界 npimg img.numpy() plt.imshow(npimg[0], cmapgray) plt.title(fLabel: {label}) plt.show() # 调用示例 imshow(image, label)小提示如果张量来自模型输出、带有梯度转 numpy 需要写成img.detach().numpy()切断计算图梯度避免报错。六、DataLoader 批次加载器Dataset 只负责单个样本DataLoader 负责打包成 batch。train_loader DataLoader( train_dataset, batch_size64, # 一个批次64张图片推荐2的幂次适配GPU计算 shuffleTrue # 训练集打乱样本顺序防止模型记住样本顺序 ) test_loader DataLoader( test_dataset, batch_size1000, shuffleFalse # 测试集不需要打乱 )核心功能自动按batch_size打包图片 标签shuffleTrue每一轮 epoch 开始打乱数据支持num_workers多进程并行读取图片加快 IO 速度。迭代器小知识 DataLoader 是可迭代对象可以用iter(train_loader)转为迭代器配合next()取出单个 batch常用于调试查看一批数据。七、Dataset vs DataLoader 对比表表格维度DatasetDataLoader核心职责定义数据内容、单个样本读取逻辑定义批量加载策略组装 batch核心方法__getitem__获取单样本__len__获取样本总数无自定义魔术方法依靠参数控制加载预处理位置在__getitem__内部执行 transform 预处理不做预处理接收 Dataset 处理好的样本并行能力单样本处理无并行支持多进程加载num_workers常用参数root 路径、transform 预处理batch_size、shuffle、num_workers八、核心总结Dataset管单个样本规定去哪里找图、怎么读图、怎么做预处理必须实现__len__、__getitem__两个魔术方法。DataLoader管批量打包在 Dataset 之上自动组成 batch、打乱、多线程加载解决显存放不下大数据的问题。数据流程Dataset 读取单张图片 → transform 预处理 → DataLoader 打包成 batch → 送入网络前向传播计算 loss 反向传播。可视化图像需要反归一化把标准化后的张量还原到 0~1 区间才能正常绘图。