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

PyTorch中DataLoader不同配置下洗牌顺序差异原因咨询

PyTorch DataLoader 不同洗牌结果的原因解析

我们先明确测试用的数据集:

datasets = [0,1,2,3,4]

下面分三个场景逐一分析:

场景I

代码:

torch.manual_seed(1)

G = torch.Generator()
G.manual_seed(1)

ran_sampler = RandomSampler(data_source=datasets,generator=G)
dataloader = DataLoader(dataset=datasets,sampler=ran_sampler)

洗牌结果:0,4,2,3,1

原因:
这里RandomSampler明确绑定了我们创建的生成器G,而DataLoader没有传入generator参数。由于自定义采样器(指定sampler参数)会完全接管采样逻辑,DataLoader不会介入采样的随机过程,洗牌顺序完全由绑定了种子1的生成器G决定,最终得到上述结果。

场景II

代码:

torch.manual_seed(1)

G = torch.Generator()
G.manual_seed(1)

ran_sampler = RandomSampler(data_source=datasets)
dataloader = DataLoader(dataset=datasets, sampler=ran_sampler, generator=G)

洗牌结果:1,3,4,0,2

原因:

  • RandomSampler未指定generator参数时,会自动初始化一个独立的默认生成器,这个生成器和我们创建的G、全局生成器都不是同一个实例。
  • 虽然DataLoader传入了generator=G,但当自定义采样器被指定时,DataLoader的generator参数会被忽略——采样逻辑完全由RandomSampler自己的生成器控制。
  • 这个默认生成器的种子受全局torch.manual_seed(1)间接影响,但生成的随机序列和绑定了种子1的G不同,因此得到了和场景I不一样的洗牌结果。

场景III

代码:

torch.manual_seed(1)

G = torch.Generator()
G.manual_seed(1)

ran_sampler = RandomSampler(data_source=datasets, generator=G)
dataloader = DataLoader(dataset=datasets, sampler=ran_sampler, generator=G)

洗牌结果:4,1,3,0,2

原因:
这里RandomSampler和DataLoader共用了同一个生成器G。虽然自定义采样器会接管采样,但DataLoader在内部处理流程中,会额外调用这个共享的生成器G生成随机数,导致G的内部状态被提前消耗。当RandomSampler再使用G生成采样序列时,G的状态已经和场景I中未被额外调用的状态不同,最终生成的洗牌顺序也就不一样了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:20:45