pytorch模型复现踩坑记, upsample不可靠

先说结论:

pytorch的上采用模块具有随机性,为了复现模型建议使用nearest模式,不要轻易使用trilinear!

固定随机种子使模型可复现在具体实验中是非常重要的。网上提供了许多操作方法,简单粗暴就是上如下代码:

manual_seed = config.get('manual_seed', None)
        if manual_seed is not None:
            logger.info(f'Seed the RNG for all devices with {manual_seed}')
            os.environ['PYTHONHASHSEED'] = str(manual_seed)
            torch.manual_seed(manual_seed)
            torch.cuda.manual_seed(manual_seed)
            torch.cuda.manual_seed_all(manual_seed)  # if you are using multi-GPU
            random.seed(manual_seed)
            np.random.seed(manual_seed)
            torch.backends.cudnn.deterministic = True
            torch.backends.cudnn.benchmark = False
            torch.backends.cudnn.enabled = True

在主函数开头运行上述代码段,固定随机种子,能解决大部分问题

但是,仍有一部分模型在训练和测试时无法复现

为了避免重复造轮子,不可能所有模型都从0开始写,用一些public的代码是非常必要的。但不同的人习惯不一样,模型结构也不一样,不是每一个模型都能顺利的调通,特别是在遇到无法复现的时候,根本找不出问题在哪里!

例如,扒拉了一个代码,固定随机种子后,在相同的参数下重复跑两次,最初几个epoch的loss,dice都是相同的,但在某一次开始,loss的最后几位小数开始发生变化,再过几个epoch后变化越来越大,然后就变得毫无关系了。重复多次,都无法复现实验结果。

通过重复实验和测试,发现问题出在nn.upsample中

不添加upsample,使用反卷积时,模型可复现;使用upsample后,模型便出现上述不确定的情况。

也有网友指出,upsample导致模型可复现性变差,这一点在PyTorch的官方库issue#12207中有提到

原文中说you can try to make the operation deterministic ... by setting torch.backends.cudnn.deterministic = True

这里是try ***,不是you can  。

 

在我的实验中测试的公开代码中有如下模块

self.conv = UnetConv3(in_size + out_size, out_size, is_batchnorm, kernel_size=(3,3,3), padding_size=(1,1,1))
self.up = nn.Upsample(scale_factor=(2, 2, 2), mode='trilinear')

这是Unet的上采样过程,这里加入了deep supervision,所以和丐版Unet中的上采样有区别:

self.conv = UnetConv3(in_size, out_size, is_batchnorm)
self.up = nn.ConvTranspose3d(in_size, out_size, kernel_size=(4,4,1), stride=(2,2,1), padding=(1,1,0))

这两个地方都为了扩大featuremap,但使用了不同的层。同时,两个模型的其他地方也没明显的区别。

在之前我自己写的模块中,也用到了反卷积和上采样,那么问题就出在了mode上

upsample的方式有好几种,我之前可复现的模型中使用的是neareast,而这里是trilinear (处理的三维图像)

将模型改为如下:

self.conv = UnetConv3(in_size + out_size, out_size, kernel_size=(3,3,3), padding_size=(1,1,1))
self.up = nn.Upsample(scale_factor=(2, 2, 2), mode='nearest')

又经过重复实验,复现成功!

 

参考资料:

https://www.shuzhiduo.com/A/q4zVxqbx5K/

https://pytorch.org/docs/stable/nn.functional.html?highlight=upsample#torch.nn.functional.upsample

https://zhuanlan.zhihu.com/p/109166845

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值