Pytorch在训练深度神经网络的过程中,有许多随机的操作,如基于numpy库的数组初始化、卷积核的初始化,以及一些学习超参数的选取,为了实验的可复现性,必须将整个训练过程固定住

固定随机种子的目的

  1. 方便其他人复现我们的代码
  2. 方便模型验证
  3. 方便验证我们的模型是哪些超参数在起决定性效果
  4. 方便对比不同模型架构的差异
  5. 通常在模型训练后期,调整随机种子能有意想不到的结果

代码结构

# Fix random seed for reproducibility
def same_seeds(seed):
	  torch.manual_seed(seed)
	  if torch.cuda.is_available():
		    torch.cuda.manual_seed(seed)
		    torch.cuda.manual_seed_all(seed)
	  np.random.seed(seed)
	  random.seed(seed)
	  torch.backends.cudnn.benchmark = False
	  torch.backends.cudnn.deterministic = True
same_seeds(0)

解释

Sets the seed for generating random numbers. Returns a torch.Generator object.

为CPU中设置种子,设置生成随机数的种子。 返回一个 torch.Generator 对象。

注意这里考虑的是在CPU上面的计算if条件里面考虑的才是GPU Cuda的计算,是为了**保证代码在没有GPU Cuda的环境下依旧能为运算单元设定随机种子,下面cuda的种子设置是一种更复杂的情况

Sets the seed for generating random numbers on all GPUs. It’s safe to call this function if CUDA is not available; in that case, it is silently ignored.

所有GPU设置种子,生成随机数,相比上一句代码,着重考虑了代码环境中有多个GPU并行计算单元的情况

如果没有GPU,执行将会被忽略

  • np.random.seed(seed)
    固定Numpy产生的随机数,使得在相同的随机种子所产生随机数是相同的,这句话将会对所有在Numpy库中的随机函数产生作用
  • random.seed(seed)
    上面一句主要是对Numpy库设置随机种子,这句话则是设置整个Python基础环境中的随机种子
  • torch.backends.cudnn.benchmark = False
    benchmark 设置False,是为了保证不使用选择卷积算法的机制,使用固定的卷积算法
  • torch.backends.cudnn.deterministic = True
    为了确定使用相同的算法,保证得到一样的结果

引自知乎“孤勇者"的评论:
即使是固定的卷积算法,由于其实现不同,其随机性可能是不可控制的,
相同的值,同一个算法卷积出来有细微差别,deterministic设置True保证使用确定性的卷积算法,二者配合起来,才能保证卷积操作的一致性

通常最后两句话是连在一起用的,总的意思是让模型使用相同的卷积核(不去通过选择的方法来提升模型的训练速度),牺牲训练速度以换取模型的可复现性

如此一来,将极大提升代码的可复现性,如果有其他进一步限制代码随机性、增强可复现性的命令,欢迎评论区补充,作者也会同步更新,谢谢 😃


写在最后

各位看官,都看到这里了,麻烦动动手指头给博主来个点赞8,您的支持作者最大的创作动力哟!
才疏学浅,若有纰漏,恳请斧正
本文章仅用于各位作为学习交流之用,不作任何商业用途,若涉及版权问题请速与作者联系,望悉知

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐