1.使用随机种子、deterministic使得实验结果可复现
随机数种子seed确定时,模型的训练结果将始终保持一致。
随机数种子seed确定时使用相同的网络结构,跑出来的效果完全不同,用的学习率,迭代次数,batch size 都是一样。
如果配合上设置 Torch 的随机种子为固定值的话,应该可以保证每次运行网络的时候相同输入的输出是固定的。
4种随机种子:
import torch.backends.cudnn as cudnn # gpu深度学习加速包cudnn
# 几种随机种子
random.seed(opt.manualSeed)
np.random.seed(opt.manualSeed)
torch.manual_seed(opt.manualSeed) # 为cpu设置随机种子
torch.cuda.manual_seed(opt.manualSeed) # 为GPU设置随机种子
cudnn.deterministic = True # 每次返回的卷积实现算法将是确定的,即默认算法,模型的训练结果将始终保持一致。
2.关于benchmak(基准)和diterministic(确定性的)
- Benchmark模式会提升计算速度,但是由于计算中有随机性,每次网络前馈结果略有差异。
torch.backends.cudnn.benchmark = True 将会让程序在开始时花费一点额外时间,为整个网络的每个卷积层搜索最适合它的卷积实现算法,进而实现网络的加速。
适用场景是网络结构固定(不是动态变化的),网络的输入形状(包括 batch size,图片大小,输入的通道)是不变的,其实也就是一般情况下都比较适用。
反之,如果卷积层的设置一直变化,将会导致程序不停地做优化,反而会耗费更多的时间。
PyTorch 默认情况(即 cudnn.benchmark=False ),输入尺寸的变化并不影响效率。
- 设置 torch.backends.cudnn.deterministic = True,每次返回的卷积实现算法将是确定的,即默认算法。
如果配合上设置 Torch 的随机种子为固定值的话,应该可以保证每次运行网络的时候相同输入的输出是固定的。即每次返回的卷积算法将是确定的,模型的训练结果将始终保持一致。
3.实例
① repVGG网络模型 train.py代码中:
# 判断输入参数是否固定了随机数种子
if args.seed is not None:
random.seed(args.seed)
torch.manual_seed(args.seed) # 为cpu设置随机种子
cudnn.deterministic = True
warnings.warn('You have chosen to seed training. '
'This will turn on the CUDNN deterministic setting, '
'which can slow down your training considerably! '
'You may see unexpected behavior when restarting '
'from checkpoints.')
②vdsr网络模型 main_vdsr.py代码中:
opt.seed = random.randint(1, 10000) # 设置种子为[1,10000)之间的随机整数
print("Random Seed: ", opt.seed)
torch.manual_seed(opt.seed) #设置 (CPU) 生成随机数的种子,并返回一个torch.Generator对象。
if cuda:
torch.cuda.manual_seed(opt.seed) # 为GPU设置随机种子
cudnn.benchmark = True # 自动搜索最优卷积实现方法,实现网络加速