You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

torch.utils.data.DataLoader迭代机制解析:为何遍历一次后times值为938而非预期的64?

关于PyTorch DataLoader迭代机制的疑问解答

首先,咱们先解决你最困惑的问题:为什么times的值是938而不是64?

核心误解:batch_size vs 批次数量

你设置的batch_size=64是每个批次包含的样本数量,而不是遍历trainloader的循环次数。for image, label in trainloader这个循环会遍历所有批次,每一次循环对应一个batch的样本处理。times每次循环加1,所以它的最终值等于trainloader的总批次数量。

举个例子,如果你的trainset总共有60000个样本(比如经典的MNIST数据集),总批次数量就是ceil(60000 / 64) = 938——这正好和你看到的结果一致!因为60000除以64等于937.5,最后一批会包含剩下的32个样本(除非你设置drop_last=True,这时候会丢弃最后一批不足64的样本,批次数量就变成937)。

torch.utils.data.DataLoader的迭代运行机制

DataLoader的核心作用是把原始的Dataset包装成一个可迭代的批次生成器,它的迭代逻辑可以拆解成这几个关键步骤:

  • 采样器(Sampler)生成样本索引序列
    当你设置shuffle=True时,DataLoader会使用RandomSampler,在每个epoch开始时随机打乱所有样本的索引顺序;如果shuffle=False,则用SequentialSampler按顺序生成索引。这个步骤决定了每个epoch中样本的读取顺序。

  • 批次采样器(BatchSampler)拆分索引为批次
    BatchSampler会把Sampler生成的索引序列,按照batch_size分成一个个索引组。比如总共有60000个索引,就会分成938组,前937组每组64个索引,最后一组32个索引。如果你设置了drop_last=True,BatchSampler会丢弃最后一组不足batch_size的索引,只保留完整的批次。

  • 迭代时加载并打包批次数据
    当你遍历trainloader时,每次迭代会取出一个索引组,然后从Dataset中加载对应的样本和标签。默认的collate_fn会把这些零散的样本打包成形状为(batch_size, ...)的Tensor,标签也会打包成对应的Tensor,最后返回给你。整个循环会跑完所有批次,直到所有索引组都被处理完毕。

对你的代码的补充说明

你的训练逻辑里,外层的for i in range(batches)是遍历epoch(训练轮数),每一轮都会完整遍历trainloader的所有批次。所以第一个epoch结束后,times就是938;如果batches=2,那times就会变成1876,以此类推。

另外提个小细节:你的accuracy计算是累加每个batch的准确率,最后除以批次数量得到整个epoch的平均准确率,这个逻辑是对的。如果想更清晰,可以把times的初始化放到外层循环里,这样每一轮epoch都能单独统计该轮的batch次数。

内容的提问来源于stack exchange,提问作者Alessandro Mondin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 16:58:13