为何设置random.seed(42)无法在PyTorch中获得一致结果?
问题原因及解决方案
你遇到的问题核心在于:PyTorch的参数初始化依赖于自身独立的随机数生成器,和你设置的random、numpy.random完全是两个互不影响的体系。所以你只给Python原生随机库和NumPy设了种子,并没有控制PyTorch内部的随机性,自然每次初始化网络参数都会不一样。
具体原因
torch.nn.Linear(也就是你代码里的fc1)这类层的参数初始化,是调用PyTorch内置的随机采样逻辑实现的——比如默认用均匀分布或正态分布初始化权重,这些操作都是基于PyTorch自己的随机数生成器(torch.Generator),和random、numpy.random的生成器没有关联。你之前设置的种子只影响这两个库的随机行为,管不到PyTorch的初始化流程。
解决方法
要让PyTorch的网络初始化结果固定,你需要专门设置PyTorch的随机种子,包括CPU和GPU(如果用到的话)的相关配置:
import random import numpy as np import torch # 初始化Python原生随机种子 random.seed(42) # 初始化NumPy随机种子 np.random.seed(42) # 初始化PyTorch CPU随机种子 torch.manual_seed(42) # 如果你的环境有可用的CUDA设备,还需要配置GPU的随机性 if torch.cuda.is_available(): # 设置单GPU种子 torch.cuda.manual_seed(42) # 多GPU场景下,给所有GPU设置种子 torch.cuda.manual_seed_all(42) # 禁用cuDNN的非确定性算法,避免额外的随机波动 torch.backends.cudnn.deterministic = True # 关闭cuDNN的自动调优,确保每次用相同的卷积算法 torch.backends.cudnn.benchmark = False
把这段代码放在你主文件的最开头(在导入neuralnet之前),之后再初始化net = neuralnet.Net(),就能得到完全一致的参数初始化结果了。
额外注意
如果你的neuralnet.py文件里还有自定义的随机操作(比如手动用torch.rand生成参数),也要确保这些代码能继承到你设置的全局种子,不过根据你的描述,参数初始化是由torch.nn.Module完成的,所以上面的配置就足够解决问题了。
内容的提问来源于stack exchange,提问作者user637140




