Pytorch DataLoader迭代顺序是否稳定?
Pytorch数据加载器的迭代顺序是否保证相同(在温和条件下) 例如:Pytorch DataLoader迭代顺序是否稳定?,pytorch,iterable,deterministic,dataloader,Pytorch,Iterable,Deterministic,Dataloader,Pytorch数据加载器的迭代顺序是否保证相同(在温和条件下) 例如: dataloader = DataLoader(my_dataset, batch_size=4, shuffle=True, num_workers=4) print("run 1") for batch in dataloader: print(batch["index"]) print("run 2") for batch in dataloader: prin
dataloader = DataLoader(my_dataset, batch_size=4,
shuffle=True, num_workers=4)
print("run 1")
for batch in dataloader:
print(batch["index"])
print("run 2")
for batch in dataloader:
print(batch["index"])
到目前为止,我已经尝试过测试它,但它似乎没有被修复,两次运行的顺序相同。有没有办法让订单也一样?谢谢
编辑:我也试过这样做
unlabeled_sampler = data.sampler.SubsetRandomSampler(unlabeled_indices)
unlabeled_dataloader = data.DataLoader(train_dataset,
sampler=unlabeled_sampler, batch_size=args.batch_size, drop_last=False)
然后在数据加载器中迭代两次,但结果是相同的非确定性 简短的回答是否定的,当
shuffle=True
数据加载程序的迭代顺序在迭代之间不稳定时。每次在加载程序上迭代时,内部RandomSampler
都会创建一个新的随机顺序
获得稳定的无序DataLoader
的一种方法是使用一组无序索引创建一个子集
数据集
shuffled_dataset = torch.utils.data.Subset(my_dataset, torch.randperm(len(my_dataset)).tolist())
dataloader = DataLoader(shuffled_dataset, batch_size=4, num_workers=4, shuffled=False)
简短的回答是否定的,当
shuffle=True
数据加载程序的迭代顺序在迭代之间不稳定时。每次在加载程序上迭代时,内部RandomSampler
都会创建一个新的随机顺序
获得稳定的无序DataLoader
的一种方法是使用一组无序索引创建一个子集
数据集
shuffled_dataset = torch.utils.data.Subset(my_dataset, torch.randperm(len(my_dataset)).tolist())
dataloader = DataLoader(shuffled_dataset, batch_size=4, num_workers=4, shuffled=False)
事实上,我在回答jodag的评论时也这么认为:
torch.manual_seed("0")
for i,elt in enumerate(unlabeled_dataloader):
order.append(elt[2].item())
print(elt)
if i > 10:
break
torch.manual_seed("0")
print("new dataloader")
for i,elt in enumerate( unlabeled_dataloader):
print(elt)
if i > 10:
break
exit(1)
以及输出:
[tensor([[-0.3583, -0.6944]]), tensor([3]), tensor([1610])]
[tensor([[-0.6623, -0.3790]]), tensor([3]), tensor([1958])]
[tensor([[-0.5046, -0.6399]]), tensor([3]), tensor([1814])]
[tensor([[-0.5349, 0.2365]]), tensor([2]), tensor([1086])]
[tensor([[-0.1310, 0.1158]]), tensor([0]), tensor([321])]
[tensor([[-0.2085, 0.0727]]), tensor([0]), tensor([422])]
[tensor([[ 0.1263, -0.1597]]), tensor([0]), tensor([142])]
[tensor([[-0.1387, 0.3769]]), tensor([1]), tensor([894])]
[tensor([[-0.0500, 0.8009]]), tensor([3]), tensor([1924])]
[tensor([[-0.6907, 0.6448]]), tensor([4]), tensor([2016])]
[tensor([[-0.2817, 0.5136]]), tensor([2]), tensor([1267])]
[tensor([[-0.4257, 0.8338]]), tensor([4]), tensor([2411])]
new dataloader
[tensor([[-0.3583, -0.6944]]), tensor([3]), tensor([1610])]
[tensor([[-0.6623, -0.3790]]), tensor([3]), tensor([1958])]
[tensor([[-0.5046, -0.6399]]), tensor([3]), tensor([1814])]
[tensor([[-0.5349, 0.2365]]), tensor([2]), tensor([1086])]
[tensor([[-0.1310, 0.1158]]), tensor([0]), tensor([321])]
[tensor([[-0.2085, 0.0727]]), tensor([0]), tensor([422])]
[tensor([[ 0.1263, -0.1597]]), tensor([0]), tensor([142])]
[tensor([[-0.1387, 0.3769]]), tensor([1]), tensor([894])]
[tensor([[-0.0500, 0.8009]]), tensor([3]), tensor([1924])]
[tensor([[-0.6907, 0.6448]]), tensor([4]), tensor([2016])]
[tensor([[-0.2817, 0.5136]]), tensor([2]), tensor([1267])]
[tensor([[-0.4257, 0.8338]]), tensor([4]), tensor([2411])]
这是我们想要的。然而,我认为乔达格的主要答案还是更好;这只是一个暂时有效的快速破解;) 在评论回答中,我实际上赞同乔达格的观点:
torch.manual_seed("0")
for i,elt in enumerate(unlabeled_dataloader):
order.append(elt[2].item())
print(elt)
if i > 10:
break
torch.manual_seed("0")
print("new dataloader")
for i,elt in enumerate( unlabeled_dataloader):
print(elt)
if i > 10:
break
exit(1)
以及输出:
[tensor([[-0.3583, -0.6944]]), tensor([3]), tensor([1610])]
[tensor([[-0.6623, -0.3790]]), tensor([3]), tensor([1958])]
[tensor([[-0.5046, -0.6399]]), tensor([3]), tensor([1814])]
[tensor([[-0.5349, 0.2365]]), tensor([2]), tensor([1086])]
[tensor([[-0.1310, 0.1158]]), tensor([0]), tensor([321])]
[tensor([[-0.2085, 0.0727]]), tensor([0]), tensor([422])]
[tensor([[ 0.1263, -0.1597]]), tensor([0]), tensor([142])]
[tensor([[-0.1387, 0.3769]]), tensor([1]), tensor([894])]
[tensor([[-0.0500, 0.8009]]), tensor([3]), tensor([1924])]
[tensor([[-0.6907, 0.6448]]), tensor([4]), tensor([2016])]
[tensor([[-0.2817, 0.5136]]), tensor([2]), tensor([1267])]
[tensor([[-0.4257, 0.8338]]), tensor([4]), tensor([2411])]
new dataloader
[tensor([[-0.3583, -0.6944]]), tensor([3]), tensor([1610])]
[tensor([[-0.6623, -0.3790]]), tensor([3]), tensor([1958])]
[tensor([[-0.5046, -0.6399]]), tensor([3]), tensor([1814])]
[tensor([[-0.5349, 0.2365]]), tensor([2]), tensor([1086])]
[tensor([[-0.1310, 0.1158]]), tensor([0]), tensor([321])]
[tensor([[-0.2085, 0.0727]]), tensor([0]), tensor([422])]
[tensor([[ 0.1263, -0.1597]]), tensor([0]), tensor([142])]
[tensor([[-0.1387, 0.3769]]), tensor([1]), tensor([894])]
[tensor([[-0.0500, 0.8009]]), tensor([3]), tensor([1924])]
[tensor([[-0.6907, 0.6448]]), tensor([4]), tensor([2016])]
[tensor([[-0.2817, 0.5136]]), tensor([2]), tensor([1267])]
[tensor([[-0.4257, 0.8338]]), tensor([4]), tensor([2411])]
这是我们想要的。然而,我认为乔达格的主要答案还是更好;这只是一个暂时有效的快速破解;) 如果
shuffle=False
,它是稳定的,在您的情况下,您通过设置shuffle=True
明确请求以随机顺序返回数据,这是正确的。但它是“相同”的数据加载器,不是吗?相同的数据集不是相同的加载器。加载器“只是”数据集的接口,其中定义了采样器。采样器按照定义的方式和顺序对数据集进行采样。如果您更改了shuffle,那么您正在更改dataloader使用的采样器,它可以使数据从稳定变为不稳定。您还可以在定义数据加载器时显式指定采样器。感谢您的澄清!所以实际上我有:unlabeled\u sampler=data.sampler.substrandomsampler(unlabeled\u index)
然后unlabeled\u dataloader=data.dataloader(train\u dataset,sampler=unlabeled\u sampler,batch\u size=args.batch\u size,drop\u last=False)
,迭代顺序仍然不稳定。有什么想法吗?我想我现在更了解你的问题了。我发布了一个我相信能回答您问题的答案。如果shuffle=False
,它是稳定的,在您的情况下,您通过设置shuffle=True
明确要求以随机顺序返回数据,这一点很好。但它是“相同”的数据加载器,不是吗?相同的数据集不是相同的加载器。加载器“只是”数据集的接口,其中定义了采样器。采样器按照定义的方式和顺序对数据集进行采样。如果您更改了shuffle,那么您正在更改dataloader使用的采样器,它可以使数据从稳定变为不稳定。您还可以在定义数据加载器时显式指定采样器。感谢您的澄清!所以实际上我有:unlabeled\u sampler=data.sampler.substrandomsampler(unlabeled\u index)
然后unlabeled\u dataloader=data.dataloader(train\u dataset,sampler=unlabeled\u sampler,batch\u size=args.batch\u size,drop\u last=False)
,迭代顺序仍然不稳定。有什么想法吗?我想我现在更了解你的问题了。我发布了一个我相信能回答你问题的答案。谢谢你,让我再测试一个我的想法,然后我会尝试你的答案并接受。对我来说奇怪的是,如果我适当地设置种子,那么内部的随机采样器每次都应该给出相同的随机索引,不是吗?@information\u interchange我相信随机采样器中的随机性发生在创建数据加载器迭代器时(例如,当您对标签执行时,数据加载器中的数据:
). 您需要在每次迭代数据加载器之前立即使用相同的种子值为torch的随机数生成器(例如,torch.manual_seed(1234)
)种子,以确保可复制性。这并不理想,因为系统中的任何其他随机行为最终也会被重复,这可能并不理想。嘿,事实上,我刚刚尝试了这种方法,但不幸的是它不起作用:ValueError:sampler应该是torch.utils.data.sampler的一个实例,但是get sampler=[739,841,1892,…]
哦,这真的很有趣,你说得对。这非常令人惊讶,因为这是pytorch开发人员之一的推荐。不管怎样,我回到了我的第一个解决方案,它同样有效,我已经测试过了。谢谢,让我再测试一个想法,然后我会尝试你的答案并接受。对我来说奇怪的是,如果我适当地设置种子,那么内部的随机采样器每次都应该给出相同的随机索引,不是吗?@information\u interchange我相信随机采样器中的随机性发生在创建数据加载器迭代器时(例如,当您对标签执行时,数据加载器中的数据:
). 您需要在每次迭代数据加载器之前立即使用相同的种子值为torch的随机数生成器(例如,torch.manual_seed(1234)
)种子,以确保可复制性。这并不理想,因为系统中的任何其他随机行为最终也会被重复,这可能是不理想的。嘿,实际上,我刚刚尝试了这种方法,但遗憾的是它不起作用:ValueError:sampler应该是torch.utils.data.sampler的一个实例,但是got sampler=[7398411892,…]
哦,实际上是这样