• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    PyTorch 如何设置随机数种子使结果可复现

    由于在模型训练的过程中存在大量的随机操作,使得对于同一份代码,重复运行后得到的结果不一致。

    因此,为了得到可重复的实验结果,我们需要对随机数生成器设置一个固定的种子。

    CUDNN

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

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

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

    Pytorch

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

    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数目(线程数)不变,基本上也能够重复实验结果。

    补充:pytorch 固定随机数种子踩过的坑

    1.初步固定

     def setup_seed(seed):
         torch.manual_seed(seed)
         torch.cuda.manual_seed_all(seed)
         torch.cuda.manual_seed(seed)
         np.random.seed(seed)
         random.seed(seed)
         torch.backends.cudnn.deterministic = True
         torch.backends.cudnn.enabled = False
         torch.backends.cudnn.benchmark = False
         #torch.backends.cudnn.benchmark = True #for accelerating the running
     setup_seed(2019)

    2.继续添加如下代码:

    tensor_dataset = ImageList(opt.training_list,transform)
    def _init_fn(worker_id): 
        random.seed(10 + worker_id)
        np.random.seed(10 + worker_id)
        torch.manual_seed(10 + worker_id)
        torch.cuda.manual_seed(10 + worker_id)
        torch.cuda.manual_seed_all(10 + worker_id)
    dataloader = DataLoader(tensor_dataset,                        
                        batch_size=opt.batchSize,     
                        shuffle=True,     
                        num_workers=opt.workers,
                        worker_init_fn=_init_fn)

    3.在上面的操作之后发现加载的数据多次试验大部分一致了

    但是仍然有些数据是不一致的,后来发现是pytorch版本的问题,将原先的0.3.1版本升级到1.1.0版本,问题解决

    4.按照上面的操作后虽然解决了问题

    但是由于将cudnn.benchmark设置为False,运行速度降低到原来的1/3,所以继续探索,最终解决方案是把第1步变为如下,同时将该部分代码尽可能放在主程序最开始的部分,例如:

    import torch
    import torch.nn as nn
    from torch.nn import init
    import pdb
    import torch.nn.parallel
    import torch.nn.functional as F
    import torch.backends.cudnn as cudnn
    import torch.optim as optim
    import torch.utils.data
    from torch.utils.data import DataLoader, Dataset
    import sys
    gpu_id = "3,2"
    os.environ["CUDA_VISIBLE_DEVICES"] = gpu_id
    print('GPU: ',gpu_id)
    def setup_seed(seed):
         torch.manual_seed(seed)
         torch.cuda.manual_seed_all(seed)
         torch.cuda.manual_seed(seed)
         np.random.seed(seed)
         random.seed(seed)
         cudnn.deterministic = True
         #cudnn.benchmark = False
         #cudnn.enabled = False
    
    setup_seed(2019)
    

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

    您可能感兴趣的文章:
    • 简述python&pytorch 随机种子的实现
    • Pytorch在dataloader类中设置shuffle的随机数种子方式
    • pytorch通过训练结果的复现设置随机种子
    上一篇:Python Parser的用法
    下一篇:python 使用Tensorflow训练BP神经网络实现鸢尾花分类
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    PyTorch 如何设置随机数种子使结果可复现 PyTorch,如何,设置,随机数,