浅谈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数据结构树和二叉树简介
Apr 29 Python
机器学习经典算法-logistic回归代码详解
Dec 22 Python
Python操作Redis之设置key的过期时间实例代码
Jan 25 Python
详解Python中的动态属性和特性
Apr 07 Python
Python中的groupby分组功能的实例代码
Jul 11 Python
Python实现点阵字体读取与转换的方法
Jan 29 Python
django框架CSRF防护原理与用法分析
Jul 22 Python
Python爬虫使用浏览器cookies:browsercookie过程解析
Oct 22 Python
python把一个字符串切开的实例方法
Sep 27 Python
Python descriptor(描述符)的实现
Nov 15 Python
python性能测试工具locust的使用
Dec 28 Python
Python中22个万用公式的小结
Jul 21 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中spl_autoload_register函数的用法总结
2013/11/07 PHP
PHP+AJAX实现投票功能的方法
2015/09/28 PHP
linux下为php添加iconv模块的方法
2016/02/28 PHP
javascript instanceof 内部机制探析
2010/10/15 Javascript
caller和callee的区别介绍及演示结果
2013/03/10 Javascript
JavaScript模块随意拖动示例代码
2014/05/27 Javascript
javascript的事件触发器介绍的实现
2014/06/05 Javascript
实现js保留小数点后N位的代码
2014/11/13 Javascript
AngularJS快速入门
2015/04/02 Javascript
json+jQuery实现的无限级树形菜单效果代码
2015/08/27 Javascript
WebGL利用FBO完成立方体贴图效果完整实例(附demo源码下载)
2016/01/26 Javascript
Servlet实现文件上传,可多文件上传示例
2016/12/05 Javascript
详解js的异步编程技术的方法
2017/02/09 Javascript
vue.js中指令Directives详解
2017/03/20 Javascript
bootstrap多层模态框滚动条消失的问题
2017/07/21 Javascript
vue.js开发实现全局调用的MessageBox组件实例代码
2017/11/22 Javascript
浅谈vue中慎用style的scoped属性
2017/11/28 Javascript
javascript中函数的写法实例代码详解
2018/10/28 Javascript
使用Python的Flask框架表单插件Flask-WTF实现Web登录验证
2016/07/12 Python
python实现在pandas.DataFrame添加一行
2018/04/04 Python
python re库的正则表达式入门学习教程
2019/03/08 Python
python将数据插入数据库的代码分享
2020/08/16 Python
python re的findall和finditer的区别详解
2020/11/15 Python
CSS实现聊天气泡效果
2020/04/26 HTML / CSS
video结合canvas实现视频在线截图功能
2018/06/25 HTML / CSS
中国汽车租赁行业头部企业:一嗨租车
2019/05/16 全球购物
简述进程的启动、终止的方式以及如何进行进程的查看
2013/07/12 面试题
室内拓展活动方案
2014/02/13 职场文书
项目采购员岗位职责
2014/04/15 职场文书
政府个人对照检查材料思想汇报
2014/10/08 职场文书
二手车交易协议书标准版
2014/11/16 职场文书
涪陵白鹤梁导游词
2015/02/09 职场文书
硕士毕业答辩开场白
2015/05/27 职场文书
Nginx域名转发使用场景代码实例
2021/03/31 Servers
理解python中装饰器的作用
2021/07/21 Python
python 标准库原理与用法详解之os.path篇
2021/10/24 Python