随机种子
在看一些论文的代码的时候总是会遇到种子(seed)的设置,一直没有太在意,就知道是为了使得代码的结果可以正确复现,今天做个总结。经常见到的是torch.manual_seed()和np.random.seed()。
torch.manual_seed()
官方api
注意,torch.manusl_seed()为cpu设置随机种子,torch.cuda.manual_seed()为GPU设置随机数种子,torch.cuda.manual_seed_all()为所有GPU设置随机数种子。random.seed()为random模块设置随机种子。
这个是pytorch中的随机种子的设置,torch.manual_seed()函数经常与torch.rand()或者troch.randn这样的生成随机数的函数搭配使用。通过设置一个固定的随机种子可以使得每次生成的随机数是相同的,如果不指定seed的值,每次生成的随机数可能就不一样。具体是什么样的需要看代码来理解。
- 不设置随机种子时候
# 第一遍执行程序
a = torch.randn(2,2)
b = torch.randn(2,2)# a的值输出为下
tensor([[ 0.3923, -0.2236],[-0.3195, -1.2050]])
# b的值输出为下
tensor([[ 1.0445, -0.6332],[ 0.5731, 0.5409]])
# 第二遍执行程序
a = torch.randn(2,2)
b = torch.randn(2,2)# a的值输出为下
tensor([[-0.3919, -1.0427],[ 1.3186, 0.7476]])
# b的值输出为下
tensor([[-1.3265, -1.2413],[-0.1028, -0.9498]])
- 设置随机种子
# 第一遍执行程序
torch.manual_seed(1)
a = torch.randn(2,2)
b = torch.randn(2,2)
# a的值输出为下
tensor([[0.6614, 0.2669],[0.0617, 0.6213]])
# b的值输出为下
tensor([[-0.4519, -0.1661],[-1.5228, 0.3817]])
# 第二遍执行程序
torch.manual_seed(1)
a = torch.randn(2,2)
b = torch.randn(2,2)
# a的值输出为下
tensor([[0.6614, 0.2669],[0.0617, 0.6213]])
# b的值输出为下
tensor([[-0.4519, -0.1661],[-1.5228, 0.3817]])
这时我们就可以发现,在设置了随机种子之后,第一遍执行程序和第二遍执行程序生成的随机数是一样的。同时我们也要注意在同一个程序的两次调用中生成的随机数是不一样的。
np.random.seed()
可以与random.randmom()配合使用。
例子
下面是一种随机种子的设置。
def setup_seed(seed):np.random.seed(seed) # numpy 的设置random.seed(seed) # python random moduleos.environ['PYTHONHASHSEED'] = str(seed) # 为了使得hash随机化,使得实验可以复现torch.manual_seed(seed) # 为cpu设置随机种子if torch.cuda.is_available():torch.cuda.manual_seed(seed) # 为当前GPU设置随机种子torch.cuda.manual_seed_all(seed) # 如果使用多GPU为,所有GPU设置随机种子torch.backends.cudnn.benchmark = False # 设置为True,会使得cuDNN来衡量自己库里面的多个卷积算法的速度,然后选择其中最快的那个卷积算法。torch.backends.cudnn.deterministic = True # 每次返回的卷积算法将是确定的,即默认算法。如果配合上设置 Torch 的随机种子为固定值的话,# 应该可以保证每次运行网络的时候相同输入的输出是固定的