【pytorch】pytorch模型可复现设置
文章目录
- 序言
- 1. 可复现设置代码
- 2. 可复现设置代码解析
- 2.1 消除python与numpy的随机性
- 2.2 消除torch的随机性
- 2.3 消除DataLoader的随机性
- 2.4 消除cuda的随机性
- 2.5 避免pytorch使用不确定性算法
- 2.6 使用pytorch-lightning
- 2.7 特殊情况
序言
- 为了让模型在同一设备每次训练的结果可复现,需进行可复现设置
1. 可复现设置代码
def set_seed(seed):
random.seed(seed)
np.random.seed(seed)
os.environ['PYTHONHASHSEED'] = str(seed)
torch.manual_seed(seed)
torch.cuda.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
torch.backends.cudnn.deterministic = True
torch.backends.cudnn.benchmark = False
torch.backends.cudnn.enabled = False
os.environ['CUBLAS_WORKSPACE_CONFIG'] = ':16:8'
torch.use_deterministic_algorithms(True)
set_seed(21)
2. 可复现设置代码解析
2.1 消除python与numpy的随机性
import random
import numpy as np
# 消除numpy和random的随机性
random.seed(SEED)
np.random.seed(SEED)
# 固定python环境变量中的PYTHONHASHSEED,禁止hash随机化
os.environ['PYTHONHASHSEED'] = str(seed)
2.2 消除torch的随机性
import torch
import torch
torch.manual_seed(SEED)
torch.cuda.manual_seed(SEED) # 适用于显卡训练
torch.cuda.manual_seed_all(SEED) # 适用于多显卡训练
2.3 消除DataLoader的随机性
- 使用torch时,一般都会使用DataLoader加载数据集,这个类使用了多线程的处理方式,因此会造成一定随机性
def seed_worker(worker_id):
random.seed(SEED + worker_id)
g = torch.Generator()
g.manual_seed(SEED)
DataLoader(
train_dataset,
batch_size=batch_size,
num_workers=num_workers,
worker_init_fn=seed_worker
generator=g,
)
- 设置shuffle=True并设置随机种子
# 可复现设置代码,可按上述来设置
def setup_seed(seed):
torch.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
np.random.seed(seed)
random.seed(seed)
torch.backends.cudnn.deterministic = True
# 设置随机数种子
setup_seed(21)
# shufle=True,不同训练之间一样的乱序
train_loader2 = DataLoader(dataset=dealDataset, batch_size=32, shuffle=True)
2.4 消除cuda的随机性
- 适用于GPU训练
# 确保每次返回的卷积算法等是固定的
torch.backends.cudnn.deterministic = True
# 禁止cudnn使用非确定性算法
torch.backends.cudnn.enabled = False
# 配合enabled命令使用
# True:自动寻找最适合当前配置的高效算法来优化运行效率
# False:保证实验结果可复现
torch.backends.cudnn.benchmark = False
-
不设置torch.backends.cudnn.enabled = False的话,无法保证训练结果可复现性。但添加这行后会导致训练速度很慢
-
如果cuda是10.2及以上版本,少数cuda操作是不确定的,需要做如下设置
os.environ['CUBLAS_WORKSPACE_CONFIG'] = ':16:8'
或
os.environ['CUBLAS_WORKSPACE_CONFIG'] = ':4096:8'
2.5 避免pytorch使用不确定性算法
- 配置pytorch在可用的情况下,使用确定性算法而不是非确定性算法。如果已知某个操作是不确定的,并且没有确定的替代办法,则抛出RuntimeError错误
torch.use_deterministic_algorithms(True)
2.6 使用pytorch-lightning
-
详见 pytorch-lightning设置
-
该方法保证了可复现的同时,没有牺牲任何训练速度
2.7 特殊情况
- 在某些版本的CUDA中,RNN和LSTM网络可能具有不确定性行为,如LSTM中的dropout,需要注意这一特性。需要关注如何消除不确定性
【参考文章】
[1]. pytorch模型可复现性设置
[2]. DataLoader类设置打乱的随机数种子
[3]. pytorch消除模型训练的随机性
[4]. pytorch模型训练可复现方案
created by shuaixio, 2024.02.24