浅谈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类的定义、继承及类对象使用方法简明教程
May 08 Python
Python删除windows垃圾文件的方法
Jul 14 Python
在Python的Django框架中加载模版的方法
Jul 16 Python
浅谈python jieba分词模块的基本用法
Nov 09 Python
pygame游戏之旅 如何制作游戏障碍
Nov 20 Python
python读csv文件时指定行为表头或无表头的方法
Jun 26 Python
python3 动态模块导入与全局变量使用实例
Dec 22 Python
Python模拟FTP文件服务器的操作方法
Feb 18 Python
Python编程快速上手——强口令检测算法案例分析
Feb 29 Python
python进行参数传递的方法
May 12 Python
Python参数传递实现过程及原理详解
May 14 Python
Python 中 Shutil 模块详情
Nov 11 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效率,提高php性能的一些方法
2011/03/24 PHP
屏蔽机器人从你的网站搜取email地址的php代码
2012/11/14 PHP
php安装xdebug/php安装pear/phpunit详解步骤(图)
2013/12/22 PHP
ThinkPHP空模块和空操作详解
2014/06/30 PHP
PHP中上传多个文件的表单设计例子
2014/11/19 PHP
Windows上php5.6操作mongodb数据库示例【配置、连接、获取实例】
2019/02/13 PHP
浏览器加载、渲染和解析过程黑箱简析
2012/11/29 Javascript
简单的JavaScript互斥锁分享
2014/02/02 Javascript
防止按钮在短时间内被多次点击的方法
2014/03/10 Javascript
iframe子页面与父页面在同域或不同域下的js通信
2014/05/07 Javascript
Javascript玩转继承(一)
2014/05/08 Javascript
滚动条的监听与内容随着滚动条动态加载的实现
2017/02/08 Javascript
JS实现碰撞检测的方法分析
2018/01/19 Javascript
element 结合vue 在表单验证时有值却提示错误的解决办法
2018/01/22 Javascript
微信小程序实现上传图片裁剪图片过程解析
2019/08/22 Javascript
原生JS与JQ获取元素的区别详解
2020/02/13 Javascript
python调用windows api锁定计算机示例
2014/04/17 Python
Python实现调用另一个路径下py文件中的函数方法总结
2018/06/07 Python
pytorch 输出中间层特征的实例
2019/08/17 Python
通过字符串导入 Python 模块的方法详解
2019/10/27 Python
Django 用户登陆访问限制实例 @login_required
2020/05/13 Python
Python如何读写CSV文件
2020/08/13 Python
python 5个顶级异步框架推荐
2020/09/09 Python
CSS3弹性盒模型flex box快速入门心得(必看篇)
2016/05/24 HTML / CSS
大二自我鉴定
2014/01/31 职场文书
人事文员岗位职责
2014/02/16 职场文书
学生安全责任书模板
2014/07/25 职场文书
委托代理人授权委托书范本
2014/09/24 职场文书
2014年酒店前台工作总结
2014/11/14 职场文书
超市工作总结范文2014
2014/12/19 职场文书
2014年机关工会工作总结
2014/12/19 职场文书
实习介绍信范文
2015/05/05 职场文书
项目验收申请报告
2015/05/15 职场文书
2016年公司中秋节致辞
2015/11/26 职场文书
pytorch中[..., 0]的用法说明
2021/05/20 Python
怎么禁用Windows 11快照布局? win11不使用快照布局的技巧
2021/11/21 数码科技