关于pytroch的随机数种子
训练产生不同结果的原因
训练过程
在训练过程中,相同的训练集、测试集划分方式,相同的权重初始化,相同的超参数,但是每次训练结果不同,可能有以下几个原因:
- Dropout的存在
- PyTorch、Python、Numpy中的随机种子没有固定
- 训练数据集被随机打乱了顺序
- 向上采样和插值函数/类的向后是不确定的(PyTorch的问题)
(注意:哪怕这些东西全部固定了,模型的结果依旧不能完全的复现出来,因为硬件设备的不同。)
代码
def set_seed(seed=1029):
# 固定python和numpy的随机种子
random.seed(seed) # python random seed
os.environ['PYTHONHASHSEED'] = str(seed) # hash random seed
np.random.seed(seed) # Numpy random seed
# 固定pytorch的随机种子
torch.manual_seed(seed) # pytorch CPU random seed
torch.cuda.manual_seed(seed) # pytorch GPUrandom seed
torch.cuda.manual_seed_all(seed) # pytorch if you are using multi-GPU.
#
torch.backends.cudnn.benchmark = True
torch.backends.cudnn.deterministic = True # Cudnn
cudnn.benchmark
其中torch.backends.cudnn.benchmark
如果为Ture,将会让程序在开始时花费一点额外时间,为整个网络的每个卷积层搜索最适合它的卷积实现算法,进而实现网络的加速。它可以让内置的 cuDNN 的 auto-tuner 自动寻找最适合当前配置的高效算法,来达到优化运行效率的问题。
但是是有使用前提的,适用场景是网络结构固定(不是动态变化的),网络的输入形状(包括 batch size,图片大小,输入的通道)是不变的,其实也就是一般情况下都比较适用。反之,如果卷积层的设置一直变化,网络的输入数据在每次 iteration 都变化的话,会导致 cnDNN 每次都会去寻找一遍最优配置,这样反而会降低运行效率。
cudnn.deterministic
Benchmark模式会提升计算速度,但是由于计算中有随机性,每次网络前馈结果略有差异。如果想要避免这种结果波动,设置为True