这两天在用Pytorch写模型训练的时候突然发现,本该是一模一样的两个网络的输出结果却不同,仔细排查后发现问题出在了 torch.DataLoader()
这个函数上,更具体的,出在这个函数的 shuffer
参数上。当设置 shuffer = True
时,即使所有设定都一样,dataloader产生的数据batch的内容在两份代码中是不同的。
上网一搜,发现这个问题很多人遇到了,也给出了一些解决办法,比如普遍的固定全局随机种子:
if args.seed is not None:
random.seed(args.seed)
torch.manual_seed(args.seed) #为CPU设置种子用于生成随机数,以使得结果是确定的
torch.cuda.manual_seed(args.seed) #为当前GPU设置随机种子;
torch.backends.cudnn.deterministic = True
当然,这种随机种子的设置一开始我就有固定,所以问题压根不在设置全局随机种子上,而是 DataLoader() 函数本身的随机种子不受全局随机种子的影响,即使设置了全局随机种子,DataLoader() 函数的 shuffer
还是会用自己的随机种子来打乱顺序。
解决方法:
道理很简单,既然DataLoader() 函数的 shuffer
有自己的随机种子,那就固定住 DataLoader() 的随机种子即可:
DataLoader(dataset, batch_size=batch_size, shuffle=True, generator=torch.Generator().manual_seed(SEED))
在 shuffer = True
时,将 DataLoader() 的 generator
参数使用 torch.Generator().manual_seed(SEED)
来固定随机种子,这样就可以实现 DataLoader() 打乱后的数据顺序是一致的了!
参考:https://pythonjishu.com/ihltcmrubugviyd/