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
相关产品推荐
相关产品推荐

