原文地址:

https://www.zhangshengrong.com/p/9MNlDK09NJ/

================================================

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

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

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

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的可重复性问题(如何使实验结果可复现)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

=================================================

【转载】 浅谈PyTorch的可重复性问题(如何使实验结果可复现)的更多相关文章

  1. 转载-浅谈Ddos攻击攻击与防御

    EMail: jianxin#80sec.comSite: http://www.80sec.comDate: 2011-2-10From: http://www.80sec.com/ [ 目录 ]一 ...

  2. [转载]浅谈JavaScript函数重载

     原文地址:浅谈JavaScript函数重载 作者:ChessZhang 上个星期四下午,接到了网易的视频面试(前端实习生第二轮技术面试).面了一个多小时,自我感觉面试得很糟糕的,因为问到的很多问题都 ...

  3. <转载>浅谈C/C++的浮点数在内存中的存储方式

    C/C++浮点数在内存中的存储方式 任何数据在内存中都是以二进制的形式存储的,例如一个short型数据1156,其二进制表示形式为00000100 10000100.则在Intel CPU架构的系统中 ...

  4. 转载--浅谈spring4泛型依赖注入

    转载自某SDN-4O4NotFound Spring 4.0版本中更新了很多新功能,其中比较重要的一个就是对带泛型的Bean进行依赖注入的支持.Spring4的这个改动使得代码可以利用泛型进行进一步的 ...

  5. (转载) 浅谈python编码处理

    最近业务中需要用 Python 写一些脚本.尽管脚本的交互只是命令行 + 日志输出,但是为了让界面友好些,我还是决定用中文输出日志信息. 很快,我就遇到了异常: UnicodeEncodeError: ...

  6. [转载]浅谈组策略设置IE受信任站点

    在企业中,通常会有一些业务系统,要求必须加入到客户端IE受信任站点,才能完全正常运行访问,在没有域的情况下,可能要通过管理员手动设置,或者通过其它网络推送方法来设置. 有了域之后,这项工作就可以很好的 ...

  7. [转载]浅谈C/C++内存泄漏及其检测工具

    http://dev.yesky.com/147/2356147_3.shtml 对于一个c/c++程序员来说,内存泄漏是一个常见的也是令人头疼的问题.已经有许多技术被研究出来以应对这个问题,比如Sm ...

  8. 浅谈Java中的深拷贝和浅拷贝

    转载: 浅谈Java中的深拷贝和浅拷贝 假如说你想复制一个简单变量.很简单: int apples = 5; int pears = apples; 不仅仅是int类型,其它七种原始数据类型(bool ...

  9. 浅谈Oracle事务【转载竹沥半夏】

    浅谈Oracle事务[转载竹沥半夏] 所谓事务,他是一个操作序列,这些操作要么都执行,要么都不执行,是一个不可分割的工作单元.通俗解释就是事务是把很多事情当成一件事情来完成,也就是大家都在一条船上,要 ...

  10. 浅谈Java中的深拷贝和浅拷贝(转载)

    浅谈Java中的深拷贝和浅拷贝(转载) 原文链接: http://blog.csdn.net/tounaobun/article/details/8491392 假如说你想复制一个简单变量.很简单: ...

随机推荐

  1. INFINI Gateway 如何防止大跨度查询

    背景 业务每天生成一个日期后缀的索引,写入当日数据. 业务查询有时会查询好多天的数据,导致负载告警. 现在想对查询进行限制--只允许查询一天的数据(不限定是哪天),如果想查询多天的数据就走申请. 技术 ...

  2. C#.NET Winform使用线程承载WCF (硬编码配置)

    winform同步承载WCF时,遇到大量请求,可能会阻塞UI线程.这时就需要开个线程来承载WCF. 1.硬编码形式创建WCF服务,WCFServer类: using CommonUtils; usin ...

  3. k8s节点状态Init:0/1

    k8s节点状态Init:0/1 在节点机器上打印日志: journalctl -f -u kubelet 出现以下内容: 5月 29 15:27:34 k8snode2 kubelet[2249]: ...

  4. 你唯一需要的是“Wide Events”,而非“Metrics、Logs、Traces”

    Charity Majors 的这句话可能是对科技行业当前可观察性状态的最好总结--完全的.大规模的混乱.大家都很困惑.什么是 trace?什么是 span?一行日志就是一个 span 吗?如果我有日 ...

  5. http请求方式GET,POST工具类RestTemplate

    http请求方式GET,POST工具类RestTemplate import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serial ...

  6. 2-SET详解

    前置知识 SET问题的标准定义:在计算机科学中,布尔可满足性问题(有时称为命题可满足性问题,缩写为SATISFIABILITY或SAT)是确定是否存在满足给定布尔公式的解释的问题.(全是废话) 说人话 ...

  7. 阿里云日志Nginx日志分析

    每分钟接口访问次数的前200条统计 not request_uri : "/heartbeat.html" | SELECT time_series(time, '1m', '%H ...

  8. PromQL全方位解读:监控与性能分析的关键技术

    本文全面探索PromQL,从基础语法到高级操作,详细介绍了数据聚合.时间序列分析及内置函数应用,旨在提升用户构建复杂监控策略和性能分析的能力. 关注[TechLeadCloud],分享互联网架构.云服 ...

  9. Mysql 日期查询今天、昨天、近7天、近30天、本月、上一月、本季

    今天 select * from 表名 where to_days(时间字段名) = to_days(now()); 昨天 SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ...

  10. mysql 二进制的读取与写入

    插入语句 用binary转换函数可将字符串转为二进制 insert into mytable (id, bin) values(1, binary('abcdef')) 查询语句 用cast进行类型转 ...