PyTorch系列

您所在的位置:网站首页 复现性试验 PyTorch系列

PyTorch系列

2023-07-30 17:09| 来源: 网络整理| 查看: 265

话不多说,先上代码:

def get_random_seed(seed): random.seed(seed) os.environ['PYTHONHASHSEED'] = str(seed) np.random.seed(seed) torch.manual_seed(seed) torch.cuda.manual_seed(seed) torch.backends.cudnn.deterministic = True torch.backends.cudnn.benchmark = False get_random_seed(42)

上述是使用 PyTorch 时比较常见的设置随机种子的代码。通常来说,在不同的 CPU 和 GPU 上,即使设置了相同的随机种子,也不能够保证能复现出相同的结果。但是理论上,在同一设备上是能够进行复现的,一般需要在主程序前,同时固定 PyTorch 、Python、Numpy 的随机种子。

这里解释一下代码中的部分代码:

1.os.environ[‘PYTHONHASHSEED’] = str(seed)

主要是为了禁止 hash 随机化。

2.torch.manual_seed(seed)

与 torch.cuda.manual_seed(seed) 的功能是类似的,一个是设置当前 CPU 的随机种子,而另一个是设置当前 GPU 的随机种子,如果存在多个 GPU 可以使用 torch.cuda.manual_seed_all(seed) 对全部 GPU 都设置随机种子。

3.torch.backends.cudnn.deterministic = True

这行代码就如同其名字一样,确定是否使用确定性卷积算法(默认是 False ),如果为 True,则能保证在相同设备上的相同输入能够实现相同输出。

4.torch.backends.cudnn.benchmark = False

如果设置 torch.backends.cudnn.benchmark = True 会让程序在一开始时增加额外的预处理时间,以让整个 model 的卷积层寻找到最适合的、最有效率的卷积实现算法,进而实现网络加速,但是与此同时可能会导致结果不可复现。

补充 1:

在这里插入图片描述

在 PyTorch 官网有上图这么一段话,仅使用 torch.manual_seed 就可以固定所有设备的 RNG 的随机种子,包括CPU 和 CUDA 。但是,目前普遍的还是使用文章一开始的那个代码,至于原因…

补充 2:

在确保实验结果可复现,还应该要注意 DataLoader,这是经常被忽略掉的地方,做法是使用 worker_init_fn 去保证可复现性(这里主要是多进程加载数据时会产生这个问题)。

def seed_worker(worker_id): worker_seed = torch.initial_seed() % 2**32 numpy.random.seed(worker_seed) random.seed(worker_seed) DataLoader( train_dataset, batch_size=batch_size, num_workers=num_workers, worker_init_fn=seed_worker )

补充 3:

在 model 中,不仅是卷积层,在其他的 operations 也存在使用非确定性算法的情况,如果想要设置所有的 operations 都使用确定性算法,则可使用 torch.use_deterministic_algorithms(True) ,但是这里会存在一个问题,如果你的 model 中存在一些无法使用确定性算法的 operation,就会报错 RuntimeError ,例如 AdaptiveMaxPool2d 等。

补充 4:

复现依然是个难题,很少见到有人能做到完全复现,所以,只要是能复现到差不多效果,也就不错了。这里面涉及到非常多且难的专业知识,我目前掌握的并不充分,我也会持续学习下去…文中如有错误,欢迎留言指正及补充。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3