PyTorch-Dataset\DataLoader数据加载


1. 引言

在深度学习项目中,数据加载是训练流程的第一步,也是至关重要的一环。PyTorch 提供了强大而灵活的数据加载机制,帮助开发者高效地管理和预处理数据。本文将带你从零开始,深入理解 PyTorch 中的数据加载原理,并通过实战代码掌握 Dataset 与 DataLoader 的核心用法。

2. PyTorch 数据加载核心概念

PyTorch 中加载数据主要依赖两个核心组件:Dataset 和 DataLoader。

  • Dataset:提供一种方式去获取每个数据及其对应的 label,同时告诉我们总共有多少个数据。它负责定义数据的索引方式与读取逻辑。
  • DataLoader:为后面的网络提供不同的数据形式,它将数据一批一批地进行打包,支持 shuffle、并行加载等特性,方便模型训练时按批次取用。

简单来说,Dataset 解决「数据怎么读」的问题,DataLoader 解决「数据怎么给」的问题。

3. 常用数据集的两种组织形式

在实际项目中,数据集通常以以下两种形式组织:

3.1 文件夹名称作为 label

这是最常见的一种形式,文件夹的名称就是数据的标签(label)。例如:

复制代码
Data/FirstTypeData/train/
├── ants/    # 蚂蚁图片,label 为 "ants"
└── bees/    # 蜜蜂图片,label 为 "bees"

每个子文件夹内的图片都属于该类别,读取时只需遍历文件夹即可。

3.2 文本文件记录 label

第二种形式中,label 以文本格式存储。文本文件名与图片名称对应,文本内容即为该图片的 label。例如:

复制代码
Data/SecondTypeData/
├── images/
│   ├── 001.jpg
│   └── 002.jpg
└── labels/
    ├── 001.txt   # 内容为 "cat"
    └── 002.txt   # 内容为 "dog"

这种形式适合 label 信息较为复杂或需要额外描述的场景。

4. 认识 Dataset 抽象类

在动手写自定义数据集之前,先来认识 PyTorch 内置的 Dataset 抽象类。通过 help() 可以查看其完整定义:

python 复制代码
from torch.utils.data import Dataset

help(Dataset)

从输出可以看到,Dataset 是一个抽象类,所有表示「键到数据样本映射」的数据集都应继承它。子类必须重写 __getitem__ 方法,用于根据索引获取对应的数据样本;同时可以重写 __len__ 方法,返回数据集的大小,供 Sampler 和 DataLoader 使用。

5. 路径直接加载数据

在正式封装数据集之前,先来看如何直接通过路径加载一张图片。这里使用 PIL 库:

python 复制代码
from PIL import Image

img_path = "Data/FirstTypeData/train/ants/0013035.jpg"
img = Image.open(img_path)
img.show()

这段代码通过图片路径直接打开并显示图片,是理解后续 Dataset 封装逻辑的基础。

6. 自定义 Dataset 加载数据

接下来,我们通过继承 Dataset 类,实现一个完整的自定义数据集。以下代码以「文件夹名称作为 label」的第一种数据形式为例:

python 复制代码
from torch.utils.data import Dataset
from PIL import Image
import os


class MyData(Dataset):
    def __init__(self, root_dir, label_dir):
        # 该魔术方法在创建实例对象时自动调用
        self.root_dir = root_dir          # 根目录
        self.label_dir = label_dir        # 标签目录(即类别名)
        self.path = os.path.join(self.root_dir, self.label_dir)  # 拼接完整路径
        self.img_path = os.listdir(self.path)  # 获取该路径下所有图片文件名

    def __getitem__(self, idx):
        img_name = self.img_path[idx]
        img_item_path = os.path.join(self.root_dir, self.label_dir, img_name)
        img = Image.open(img_item_path)
        label = self.label_dir
        return img, label

    def __len__(self):
        return len(self.img_path)

6.1 代码逐行解析

  • __init__:初始化方法,接收根目录和标签目录,拼接出图片所在路径,并列出该路径下所有图片文件名。
  • __getitem__:根据索引 idx 返回对应的图片和标签。这是 Dataset 必须实现的核心方法。
  • __len__:返回数据集中的样本总数。

6.2 实例化并使用数据集

python 复制代码
root_dir = "Data/FirstTypeData/train"
ants_label_dir = "ants"
bees_label_dir = "bees"

ants_dataset = MyData(root_dir, ants_label_dir)
bees_dataset = MyData(root_dir, bees_label_dir)

print(len(ants_dataset))   # 输出:124
print(len(bees_dataset))   # 输出:121

# 两个数据集可以直接相加合并
train_dataset = ants_dataset + bees_dataset
print(len(train_dataset))  # 输出:245

# 通过索引获取数据
img, label = train_dataset[200]
print("label:", label)    # 输出:label: bees
img.show()

运行结果:

text 复制代码
124
121
245
label: bees

可以看到,两个 Dataset 可以直接通过 + 运算符合并成一个更大的数据集,这是 PyTorch 提供的便捷特性。

7. 总结

本文从 PyTorch 数据加载的核心概念出发,详细介绍了 Dataset 与 DataLoader 的分工,梳理了两种常见的数据集组织形式,并通过完整的代码示例演示了如何自定义 Dataset 类来加载图片数据。掌握这些基础,你就为后续使用 DataLoader 进行批量训练打下了坚实的基础。

在接下来的学习中,可以进一步探索 DataLoader 的 batch_size、shuffle、num_workers 等参数,以及如何对图片进行 transform 预处理,让数据加载更加高效和规范。

相关推荐
语音之家1 小时前
NeurIPS 2026|AnyEdit:免人声分离,嘈杂音频也能局部编辑
人工智能·音视频·消融实验·声源分离
卷无止境1 小时前
Python 3.14 自由线程:拆掉 GIL 之后,我们到底得到了什么
后端·python
染指11101 小时前
147.Agent-LangGraph归并函数
开发语言·人工智能·python·langchain·agents
思绪漂移1 小时前
人机交互(人和AI)中的流程设计原则之一
人工智能·人机交互
智码看视界1 小时前
深度学习:环境搭建PyTorch vs TensorFlow 选型
pytorch·深度学习·tensorflow·gpu·环境搭建·cuda·框架选型
磁场转动100万匹1 小时前
PyTorch 版 YOLOv3 源码逐段详解:从配置文件到训练、评估、检测(定制自己的数据集)
人工智能·深度学习·yolo
小白学大数据1 小时前
逆向分析短视频平台 a_bogus 参数:从 JavaScript 混淆到 Python 复现
javascript·python·音视频
lisw051 小时前
“科学前沿极限突破计划”述评!
大数据·人工智能·学习
戴西软件1 小时前
企业如何搭建自己的AI智能体?戴西智能体管理与戴西SKILL管理实战解析
运维·jvm·人工智能·自动化·rpa