pytorch 模型复现

一般来说,设置相同的随机种子,在相同参数条件下,能使pytorch模型复现出相同的结果。随机种子的设置代码如下:

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系列 | 随机种子与可复现性pytorch reproducibility

但当我采用这种方式时,却并不管用。从pytorch相关issue中了解到:有些算法是不确定的,如果你的网络模型中使用了这类算法,那么即使你设置了相同的随机种子也无法完全复现。虽然可以通过torch.backends.cudnn.deterministic = True选用确定性的算法,但某些算法只有不确定的实现方式。

在代码中添加torch.use_deterministic_algorithms(True),它会强制使用确定性算法,如果使用了不确定算法,则会出现RuntimeError错误。我在添加该代码后得到如下提示:

RuntimeError: Deterministic behavior was enabled with either torch.use_deterministic_algorithms(True) or at::Context::setDeterministicAlgorithms(true), but this operation is not deterministic because it uses CuBLAS and you have CUDA >= 10.2. To enable deterministic behavior in this case, you must set an environment variable before running your PyTorch application: CUBLAS_WORKSPACE_CONFIG=:4096:8 or CUBLAS_WORKSPACE_CONFIG=:16:8. For more information, go to https://docs.nvidia.com/cuda/cublas/index.html#cublasApi_reproducibility

它提示我通过设置环境变量CUBLAS_WORKSPACE_CONFIG=:4096:8CUBLAS_WORKSPACE_CONFIG=:16:8可以启用确定性操作。

于是我在代码中添加了os.environ['CUBLAS_WORKSPACE_CONFIG']=":4096:8"。随后出现了如下错误:

RuntimeError: reflection_pad2d_backward_cuda does not have a deterministic implementation, but you set ‘torch.use_deterministic_algorithms(True)’. You can turn off determinism just for this operation, or you can use the ‘warn_only=True’ option, if that’s acceptable for your application. You can also file an issue at https://github.com/pytorch/pytorch/issues to help us prioritize adding deterministic support for this operation.

上面提到反向传播中使用的reflection_pad2d_backward_cuda 只有非确定算法实现方式。而强制使用torch.use_deterministic_algorithms(True)将会抛出错误。(可以通过torch.use_deterministic_algorithms(True, warn_only=True)将错误改为警告)

现在问题很明确了,不确定性算法无法避免(或许可以修改代码替换掉模型中的不确定性算法)。但通过上面的一系列设置,其实我们已经把算法的不确定性降到了最低,这种情况下能使复现的结果比较接近,不会偏差太大。

为验证固定随机种子的效果,我做了三组实验,条件分别为①固定随机种子,尽可能选用随机参数(设置torch.backends.cudnn.deterministic = True);②只固定随机种子;③不进行限定。
在相同实验条件下进行100次实验,每次实验中网络进行10次反向传播,得到输出结果(选取输出张量的第一个值)如下:

Fix seed & deterministicFix seedNo restrictions
0.3155944940.3127974270.500693619
0.308120430.3132260440.451529086
0.3143489960.31047523-0.18644166
0.3107444050.31160301-0.123521239
0.3146435020.3130797450.147185132
0.3133639690.313408256-0.154002443

其方差依次为:0.00228085 0.002338273 0.264102969。可以看到,相比不固定随机种子,固定随机种子得到的结果方差更小,结果更加接近。

如果结果能比较接近的话,其实也不用太过纠结是否能完全复现。

扩展

我在训练的过程中发现,当代码在cpu上运行时,结果是可以复现的。而切换到gpu上时,就出现了上面的问题,不确定性算法是在gpu中引入的。

上面的错误中说reflection_pad2d_backward_cuda does not have a deterministic implementation,显然,reflection_pad2d_backward_cuda 是cuda上的操作,即gpu上进行的。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
对于经典的 PyTorch 模型,你可以按照以下步骤进行操作: 1. 确定要的经典模型:选择你想要的经典模型,可以是在计算机视觉、自然语言处理或其他领域中广泛应用的模型,例如 AlexNet、VGG、ResNet 等。 2. 收集模型的相关论文和代码:查找并阅读原始论文,以了解模型的具体结构和训练方法。同时,搜索已经实的代码库或者 GitHub 上的开源项目,以获取相关的参考代码。 3. 创建 PyTorch 模型:根据论文中描述的模型结构,使用 PyTorch 创建一个对应的模型类。这包括定义模型的网络层、初始化权重等操作。 4. 实模型训练:根据论文中描述的训练方法,实相应的训练步骤。这可能包括数据预处理、损失函数定义、优化器选择以及训练循环等。 5. 数据准备:准备用于训练和测试模型的数据集。这可能涉及数据下载、数据预处理、数据划分等。 6. 训练模型:使用准备好的数据集对模型进行训练。根据需要,可以设置训练超参数、学习率调度器等。 7. 模型评估:使用测试集或交叉验证集对训练好的模型进行评估。可以计算准确率、损失值等指标。 8. 模型优化(可选):根据需要,尝试改进模型的性能。这可能包括调整超参数、尝试不同的优化器、增加正则化等。 9. 结果分析:分析模型的性能和训练过程,比较实模型与原论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值