《PyTorch 深度修炼》Dataset 和 DataLoader:数据如何喂给模型

作者:闵孚龙日期:2026/6/17

一、模型吃的不是文件,是 Batch Tensor

很多人刚学 PyTorch,会把数据加载理解成“读文件”。这个理解太浅。

训练模型时,真正进入模型的不是图片路径,不是 JSON,不是数据库记录,而是整理好的 Batch Tensor。

Dataset 负责回答一个问题:一个样本怎么取。DataLoader 负责回答另一个问题:怎样高效、稳定、成批地把样本送到训练循环。

所以 DataLoader 不是一个普通 for 循环。它是一条数据流水线。它管顺序、管批次、管拼接、管多进程、管预取、管内存搬运。

二、Dataset:不是数据本身,而是“取样规则”

Dataset 不是把所有数据都塞进内存。更准确地说,Dataset 是一套取样规则。

你告诉它:给我一个索引,我能拿到一个样本;或者你告诉它:我能持续吐出一条条样本流。

PyTorch 官方把 Dataset 分成两类:Map-style Dataset 和 Iterable-style Dataset。前者像一本有页码的书,后者像一条正在流动的河。

三、Map-style:最常见,也最适合入门

Map-style Dataset 的核心是两个协议:__getitem__ 和 __len__。

__getitem__ 负责按 key 或 index 取一个样本。__len__ 负责告诉外部数据集有多大。

图片分类、离线文本分类、CSV 样本、已经落盘的训练集,大多数都适合 Map-style。

它的好处是顺序可控。DataLoader 可以基于它自动构造 SequentialSampler 或 RandomSampler,也可以接受自定义 sampler。

四、Iterable-style:适合流式数据,但多进程容易踩坑

Iterable-style Dataset 的核心是 __iter__。它不强调“第几个样本”,而强调“持续吐出样本”。

它适合数据库游标、日志流、消息队列、远程数据流、实时生成数据。

但它有一个大坑:多进程时,每个 worker 都会拿到 dataset 的副本。如果你不切分,每个 worker 可能都读同一批数据,训练样本会重复。

因此,IterableDataset 往往要结合 get_worker_info 或 worker_init_fn,在每个 worker 中配置不同的数据范围。

五、DataLoader:真正的数据调度器

DataLoader 的职责不是“保存数据”。它的职责是把 Dataset、Sampler、BatchSampler、Fetcher、collate_fn、worker 进程串起来。

一旦你写出 for batch in dataloader,背后其实发生了一长串动作:创建迭代器,生成样本索引,读取样本,拼成 batch,必要时放进 pinned memory,再返回训练循环。

理解这一层,你才能真正排查训练慢、样本重复、shape 不对、卡死、内存暴涨这些问题。

六、Sampler:数据顺序不该写死在 Dataset 里

Dataset 只管怎么取样本。样本按什么顺序取,应该交给 Sampler。

训练时,我们希望样本顺序随机,所以常用 shuffle=True 或 RandomSampler。验证和测试时,我们希望结果稳定,所以一般不打乱。

如果要做类别均衡、难例采样、分布式切分、自定义权重采样,Sampler 就会变成关键组件。

BatchSampler 则更进一步。它不只是吐出一个 index,而是一次吐出一组 index,告诉 DataLoader 哪些样本属于同一个 mini-batch。

七、collate_fn:样本如何拼成 Batch

Dataset 每次返回的是一个样本。模型训练需要的是一个 batch。中间这一步,就靠 collate_fn。

默认 collate_fn 会把一组 Tensor 沿第 0 维堆叠起来,也会递归处理 tuple、list、dict 等结构。

固定尺寸图片任务通常不用改。变长文本、目标检测、多模态样本、复杂对象,几乎都要自定义 collate_fn。

如果你遇到 batch 的 shape 和预期不一致,先别怀疑模型。先看 Dataset 返回结构和 collate_fn。

八、num_workers:不是越大越好

num_workers=0 时,数据读取发生在主进程里。优点是报错清楚,调试方便;缺点是读数据可能阻塞训练。

num_workers>0 时,DataLoader 会启动多个 worker 进程。它们提前读取、解码、Transform、collate,再把 batch 送回主进程。

这能提高吞吐,但不是无脑越大越好。worker 过多会带来进程开销、内存复制、共享内存压力、磁盘 IO 争用、序列化成本。

真实工程里,推荐从 num_workers=0 开始确认逻辑正确,再按 2、4、8 逐步压测。观察 GPU 利用率、CPU 利用率、磁盘 IO 和主机内存。

多进程 DataLoader 的调度结构

九、pin_memory:数据搬到 GPU 前的加速点

GPU 训练的瓶颈不只有模型计算。CPU 到 GPU 的数据拷贝也可能拖慢训练。

pin_memory=True 会让 DataLoader 尝试把返回的 Tensor 放进页锁定内存。这样 Host 到 GPU 的拷贝通常更快。

但它不是魔法。如果数据本身很小、训练在 CPU、或者瓶颈不在拷贝,收益就不明显。

另外,默认 pin_memory 逻辑主要识别 Tensor,以及包含 Tensor 的 map/iterable。如果 collate_fn 返回自定义 batch 类型,就要给这个类型实现 pin_memory 方法。

十、源码级讲解:一条 Batch 是怎么出来的

现在从源码视角看 DataLoader。先看 DataLoader.__iter__。它不会直接读取数据,而是创建一个 iterator。

DataLoader._get_iterator 会根据 num_workers 选择不同执行路径:num_workers=0 走 _SingleProcessDataLoaderIter;num_workers>0 走 _MultiProcessingDataLoaderIter。

iterator 内部会维护 sampler_iter。Sampler 负责吐出 index,BatchSampler 负责吐出 index 列表。Fetcher 拿到这些 index 后,才真正调用 Dataset。

如果是 Map-style,Fetcher 通过 dataset[i] 取样本。如果是 Iterable-style,Fetcher 从 iter(dataset) 中取下一个样本。

样本拿到后,collate_fn 会把样本列表组织成 batch。多进程模式下,worker 还会通过队列把结果送回主进程,并用 ExceptionWrapper 包装异常。

十一、几个源码关键点

第一,Dataset 是抽象协议。它不强制你一次性加载所有数据,只要求你定义样本怎么被取出。

第二,DataLoader 初始化时会检查参数合法性。例如 prefetch_factor 只能在多进程场景使用;persistent_workers 必须要求 num_workers>0。

第三,DataLoader 初始化后,batch_size、sampler、batch_sampler、drop_last、dataset、persistent_workers 等关键属性不应该再随便修改。源码里通过 __setattr__ 做了限制。

第四,collate 逻辑是递归的。Tensor 会被 stack,字典会按 key 递归合并,列表和 tuple 也会继续拆开处理。复杂对象如果不符合默认规则,就要自定义。

第五,多进程 worker 里的 dataset 是副本。get_worker_info 返回当前 worker 的 id、num_workers、seed 和 dataset 副本。这就是做流式数据切分的入口。

十二、参数速查:不是背 API,而是看瓶颈

十三、常见问题:先把数据链路查清楚

训练报错,不一定是模型错。训练很慢,也不一定是模型慢。

DataLoader 的问题常常隐藏得很深:它可能让 GPU 空转,可能让样本重复,可能让 batch shape 错乱,也可能在多进程里卡住。

最稳的排查路径是:先把 num_workers 改成 0,确认 Dataset 和 collate_fn 没问题;再逐步打开多进程;最后再考虑 pin_memory、prefetch_factor、persistent_workers。

十四、总结

• Dataset 解决“一个样本怎么取”。

• DataLoader 解决“样本如何成批、高效、稳定地送进模型”。

• Sampler 管顺序,BatchSampler 管批次,collate_fn 管拼接。

• num_workers 能提升吞吐,但也会带来进程、内存和 IO 成本。

• IterableDataset 多进程要特别注意分片,否则容易重复读数据。

• pin_memory 是 GPU 训练的数据搬运优化点,但自定义 batch 需要自己适配。

• 源码主线是 DataLoader -> Iterator -> Sampler -> Fetcher -> Dataset -> collate_fn -> Batch。

下一章:Transforms。数据增强不是锦上添花,而是训练稳定性和泛化能力的关键。

内容来源:《PyTorch 深度修炼》Dataset 和 DataLoader:数据如何喂给模型:功能变化与行业影响解析_热闻岛


《PyTorch 深度修炼》Dataset 和 DataLoader:数据如何喂给模型》 是转载文章,点击查看原文


相关推荐


Java Spring Data JPA 实战指南:Repository 查询、分页与实体映射
唐青枫2026/6/10

简介 Spring Data JPA 是 Spring Data 家族里专门用来简化 JPA 开发的模块。 它不是一个新的 ORM 规范。 更准确地说: JPA 是规范 Hibernate 是常见实现 Spring Data JPA 是 Spring 对 JPA Repository 的封装 在 Spring Boot 项目里,常见调用链大致是: Controller | v Service | v Repository | v Spring Data JPA |


阿里云ECS部署YOLO教程
MR_Colorful2026/6/2

1、阿里云注册 在官网注册账号:阿里云登录 - 欢迎登录阿里云,安全稳定的云计算服务平台 2、ECS配置选择 3、在阿里云 Workbench里为Ubuntu 18/20/22/24安装XFCE桌面(不推荐在这个里面使用,不好用!) stesteps1、通过VNC连接实例 step2、更新软件包列表和已安装的包 sudo apt update && sudo apt upgrade -y step3、安装XFCE桌面环境 sudo apt install -y xfce4 xfc


HarmonyOS 鸿蒙PC平台三方库移植:使用 vcpkg 移植 libzen(ZenLib)
展菲2026/5/25

网罗开发 (小红书、快手、视频号同名)   大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等方向。在移动端开发、鸿蒙开发、物联网、嵌入式、云原生、开源等领域有深厚造诣。 图书作者:《ESP32-C3 物联网工程开发实战》 图书作者:《SwiftUI 入门,进阶与实战》 超级个体:COC上海社区主理人 特约讲师:大学讲师,谷歌亚马逊分享嘉宾 科技


决定命运的,从来不是市场,而是你看待市场的方式
怕浪猫2026/5/4

真正拉开差距的,从来不是信息,而是认知。 在金融市场中,绝大多数人输掉的,不是技术,而是思维方式。 真正站在顶层的投资者,往往遵循一些看似简单、却极难长期执行的原则。这些原则,构成了投资世界的底层逻辑。 以下 9 种投资思维,不仅被反复验证,更塑造了历史上最成功的一批投资者。 一、长期主义:真正的财富,是"熬"出来的 "如果你不打算持有一只股票10年,那就不要持有10分钟。" —— Warren Buffett 真实故事:可口可乐的"慢性暴利" 1988年,巴菲特开始大量买入 Coca-


S10-蓝桥杯 17822 乐乐的积木塔
郑恩赐2026/4/25

S10-蓝桥杯 17822 乐乐的积木塔 摘要:本文详细解析蓝桥杯17822题"乐乐的积木塔",重点剖析题目中"连续递减积木塔"等绕口表述的真实含义,分享个人从困惑到理解的解题历程,并提供简洁的Python题解。 1. 题目描述 📋 1.1 问题描述 在乐乐的玩具箱中,有一系列的积木,每个积木上都标记有一个高度值。乐乐想要找出每个积木能够成为最高的连续递减积木塔的一部分的最大高度。对于每个积木,求出包含该积木的最长递减积木序列的长度。 1.2 输入格式 第一行包含一个整数 NNN。 第二行


GitHub 热榜项目 - 日榜(2026-04-14)
CoderJia_2026/4/16

GitHub 热榜项目 - 日榜(2026-04-14) 生成于:2026-04-14 统计摘要 共发现热门项目: 16 个 榜单类型:日榜 Token赞助:siliconflow 本期热点趋势总结 本期热榜彰显了 AI Agent 深度渗透垂直场景的技术趋势。Claude 生态及其相关的代码辅助开发工具(如 Claude Code 高级优化技巧、记忆插件及自动开发框架)成为绝对核心,反映出开发者对提高 LLM 编码确定性和确定化工作流的强烈需求。同时,金融领域的 Found


《从同步到消息驱动:现代后端交互模式的深度解析与工程实践》
铭渊老黄2026/4/8

《从同步到消息驱动:现代后端交互模式的深度解析与工程实践》 ——以百万行报表导出为例,谈用户体验、可观测性、失败处理与成本权衡 在过去十多年里,我见证了 Python 从“小巧优雅的脚本语言”成长为支撑全球互联网、数据科学、AI 产业的核心力量。无论是 Web 服务、自动化任务、数据处理,还是如今的 LLM 应用,Python 都以其灵活、可读、生态丰富的特性成为开发者的首选。 而在所有后端系统中,一个绕不开的问题是: “系统应该如何与用户交互?” 是同步返回?异步任务?还是彻底消息驱动? 这篇


腾讯这只小程序Agent🦀,帮我找到了最强日程、文件、知识管理姿势
AI袋鼠帝2026/3/31

大家好,我是袋鼠帝。 这两天,我发现微信里悄悄接入了一个全新的Agent入口:WorkBuddy 微信小程序。 通过这个小程序,你不仅能在云端直接召唤龙虾,甚至还能把你办公桌上那台电脑里的本地WorkBuddy,直接拉进微信里干活! 简单来说,就是你可以通过workbuddy小程序,操控你本地电脑上的workbuddy,进而控制你的电脑干活~ 更重要的是,进一步打通了微信的生态,用起来更舒服了。 经常看我文章的朋友对 WorkBuddy 应该不陌生。之前我写过一篇关于它的测评,我也是没想到,阅


GPU 编号进阶:CUDA\_VISIBLE\_DEVICES、多进程与容器化陷阱
吴佳浩2026/3/22

GPU 编号进阶:CUDA_VISIBLE_DEVICES、多进程与容器化陷阱 本篇是系列第二篇。第一篇介绍了 CUDA_DEVICE_ORDER 的基本概念与修复方法。本篇在此基础上,深入讲解 CUDA_VISIBLE_DEVICES 与 CUDA_DEVICE_ORDER 的叠加效应,分析多进程训练框架(torch.distributed、DeepSpeed)中的潜在陷阱,并介绍 Docker 和 Kubernetes 环境下的特殊处理方式,最后给出混合 GPU 环境下的正确架构设计思路。


PostgreSQL 入门学习教程,从入门到精通,PostgreSQL 16 服务器配置与数据库监控终极指南 —语法、案例与实战(18)
知识分享小能手2026/3/14

PostgreSQL 16 服务器配置与数据库监控终极指南 —语法、案例与实战 ✅ 一、服务器配置概述 PostgreSQL 16 的服务器配置主要通过 配置文件 和 SQL 命令 控制,涵盖连接、资源、日志、查询优化、统计收集等核心模块。 📁 主要配置文件: postgresql.conf:主配置文件(全局参数)pg_hba.conf:客户端认证配置(Host-Based Authentication)pg_ident.conf:用户映射配置(可选) ⚙️ 配置方式优先级: 会话级设

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 聚合阅读