浅谈PyTorch的可重复性问题(如何使实验结果可复现)


Posted in Python onFebruary 20, 2020

由于在模型训练的过程中存在大量的随机操作,使得对于同一份代码,重复运行后得到的结果不一致。因此,为了得到可重复的实验结果,我们需要对随机数生成器设置一个固定的种子。

许多博客都有介绍如何解决这个问题,但是很多都不够全面,往往不能保证结果精确一致。我经过许多调研和实验,总结了以下方法,记录下来。

全部设置可以分为三部分:

1. CUDNN

cudnn中对卷积操作进行了优化,牺牲了精度来换取计算效率。如果需要保证可重复性,可以使用如下设置:

from torch.backends import cudnn
cudnn.benchmark = False      # if benchmark=True, deterministic will be False
cudnn.deterministic = True

不过实际上这个设置对精度影响不大,仅仅是小数点后几位的差别。所以如果不是对精度要求极高,其实不太建议修改,因为会使计算效率降低。

2. Pytorch

torch.manual_seed(seed)      # 为CPU设置随机种子
torch.cuda.manual_seed(seed)    # 为当前GPU设置随机种子
torch.cuda.manual_seed_all(seed)  # 为所有GPU设置随机种子

3. Python & Numpy

如果读取数据的过程采用了随机预处理(如RandomCrop、RandomHorizontalFlip等),那么对python、numpy的随机数生成器也需要设置种子。

import random
import numpy as np
random.seed(seed)
np.random.seed(seed)

最后,关于dataloader:

注意,如果dataloader采用了多线程(num_workers > 1), 那么由于读取数据的顺序不同,最终运行结果也会有差异。也就是说,改变num_workers参数,也会对实验结果产生影响。目前暂时没有发现解决这个问题的方法,但是只要固定num_workers数目(线程数)不变,基本上也能够重复实验结果。

对于不同线程的随机数种子设置,主要通过DataLoader的worker_init_fn参数来实现。默认情况下使用线程ID作为随机数种子。如果需要自己设定,可以参考以下代码:

GLOBAL_SEED = 1
 
def set_seed(seed):
  random.seed(seed)
  np.random.seed(seed)
  torch.manual_seed(seed)
  torch.cuda.manual_seed(seed)
  torch.cuda.manual_seed_all(seed)
 
GLOBAL_WORKER_ID = None
def worker_init_fn(worker_id):
  global GLOBAL_WORKER_ID
  GLOBAL_WORKER_ID = worker_id
  set_seed(GLOBAL_SEED + worker_id)
 
dataloader = DataLoader(dataset, batch_size=16, shuffle=True, num_workers=2, worker_init_fn=worker_init_fn)

以上这篇浅谈PyTorch的可重复性问题(如何使实验结果可复现)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python调用C/C++动态链接库的方法详解
Jul 22 Python
Python实现Tab自动补全和历史命令管理的方法
Mar 12 Python
Python使用scrapy采集时伪装成HTTP/1.1的方法
Apr 08 Python
Python中规范定义命名空间的一些建议
Jun 04 Python
Python的标准模块包json详解
Mar 13 Python
python中的迭代和可迭代对象代码示例
Dec 27 Python
Python实现定时执行任务的三种方式简单示例
Mar 30 Python
Python3.8中使用f-strings调试
May 22 Python
django连接oracle时setting 配置方法
Aug 29 Python
基于Python绘制美观动态圆环图、饼图
Jun 03 Python
Python如何设置指定窗口为前台活动窗口
Aug 12 Python
用python基于appium模块开发一个自动收取能量的小助手
Sep 25 Python
pytorch 模型的train模式与eval模式实例
Feb 20 #Python
pytorch dataloader 取batch_size时候出现bug的解决方式
Feb 20 #Python
pytorch 使用加载训练好的模型做inference
Feb 20 #Python
pytorch中的inference使用实例
Feb 20 #Python
python encrypt 实现AES加密的实例详解
Feb 20 #Python
Python关于反射的实例代码分享
Feb 20 #Python
Python3监控疫情的完整代码
Feb 20 #Python
You might like
PHP mkdir()定义和用法
2009/01/14 PHP
PHP设计模式 注册表模式
2012/02/05 PHP
PHP中auto_prepend_file与auto_append_file用法实例分析
2014/09/22 PHP
简单实现php上传文件功能
2017/09/21 PHP
ext监听事件方法[初级篇]
2008/04/27 Javascript
javascript 图片上一张下一张链接效果代码
2010/03/12 Javascript
jQuery实现瀑布流布局
2014/12/12 Javascript
sails框架的学习指南
2014/12/22 Javascript
JavaScript中ES6 Babel正确安装过程
2016/07/18 Javascript
Express框架之connect-flash详解
2017/05/31 Javascript
基于vue2.0动态组件及render详解
2018/03/17 Javascript
javascrit中undefined和null的区别详解
2019/04/07 Javascript
layui table单元格事件修改值的方法
2019/09/24 Javascript
JavaScript实现图片合成下载的示例
2020/11/19 Javascript
Python简单连接MongoDB数据库的方法
2016/03/15 Python
python网络编程调用recv函数完整接收数据的三种方法
2017/03/31 Python
Python中用post、get方式提交数据的方法示例
2017/09/22 Python
Python字典及字典基本操作方法详解
2018/01/30 Python
Python 反转字符串(reverse)的方法小结
2018/02/20 Python
使用selenium模拟登录解决滑块验证问题的实现
2019/05/10 Python
Python自动化之数据驱动让你的脚本简洁10倍【推荐】
2019/06/04 Python
Django应用程序入口WSGIHandler源码解析
2019/08/05 Python
Python列表删除元素del、pop()和remove()的区别小结
2019/09/11 Python
python中Ansible模块的Playbook的具体使用
2020/05/28 Python
美国精品地毯网站:Boutique Rugs
2020/03/04 全球购物
如何定义一个可复用的服务
2014/09/30 面试题
学术会议欢迎词
2014/01/09 职场文书
个人安全承诺书
2014/05/22 职场文书
教师个人考察材料
2014/12/16 职场文书
2015年校医个人工作总结
2015/07/24 职场文书
村官2015年度工作总结
2015/10/14 职场文书
廉政党课工作报告案例
2019/06/21 职场文书
SQL Server基本使用和简单的CRUD操作
2021/04/05 SQL Server
background-position百分比原理详解
2021/05/08 HTML / CSS
Python利用FlashText算法实现替换字符串
2022/03/31 Python
SQL Server 忘记密码以及重新添加新账号
2022/04/26 SQL Server