pytorch学习的一点儿tips(9)

今天训练模型,官方文献中的正确率是83.5%,我下午的时候训练正确率在百分之六十左右,我很纳闷,why?后来发现自己输出验证集的正确率的代码写错了,再后来又开始看程序,我发现不能笃信范本程序的超参数,当你把程序做了一些更改之后,或者是说写了自己的版本后,超参数是要做出一些改变的。


验证集的使用

一直不清楚验证集怎么使用,问了我的npy,算是大概明白了。

验证集是用来挑选出最好的模型的,如果只在训练集上训练,很有可能会发生过拟合,即在训练集上的指标达到最好,因此,可以将训练完一轮的模型放在验证集上,看一下验证集上的指标,挑选出在验证集上指标最好的model,然后将测试集的数据应用在模型上,这样得到的指标数值就是论文中的指标数值。

            if val_acc>best_acc:

                best_acc=val_acc
                beat_model=deepcopy(model.state_dict())
                model.load_state_dict(beat_model)

要提前声明

best_acc, beat_model = 0, None

声明的语句要放在epoch循环之外,不然保存的一直是最后一个模型


使用logger.info输出device

import torch
from loguru import logger


device='cuda' if torch.cuda.is_available() else 'cpu'
hyperpm=dict()
hyperpm['device']=device

for key, value in hyperpm.items():
    logger.info(f'{key:20}:{value:>20}')

这样就不会报错,但是如果device这样写

device=torch.device('cuda' if torch.cuda.is_available() else 'cpu')

就会报错:


seed的作用

保证代码的结果可以复现

seed( ) 用于指定随机数生成时所用算法开始的整数值。
1.如果使用相同的seed( )值,则每次生成的随即数都相同;
2.如果不设置这个值,则系统根据时间来自己选择这个值,此时每次生成的随机数因时间差异而不同。
3.设置的seed()值仅一次有效

https://blog.csdn.net/weixin_41013470/article/details/82956178

这篇博文里讲了黑盒理论很有意思,把种子扔进黑盒,同一粒种子只能得到相同的结果。

在一个模型训练的时候,想要复现程序的结果,在pytorch框架中,要给什么设置随机数种子呢?

pytorch官方文档中关于复现的文章

https://pytorch.org/docs/stable/notes/randomness.html

目前已知的是numpy, python, pytorch(cpu, gpu)

def set_rng_seed(seed):
    random.seed(seed) #为python设置随机种子
    np.random.seed(seed)  #为numpy设置随机种子
    torch.manual_seed(seed)   #为CPU设置随机种子
    torch.cuda.manual_seed(seed)   #为当前GPU设置随机种子
    torch.cuda.manual_seed_all(seed)   #为所有GPU设置随机种子
    torch.backends.cudnn.deterministic = True

设定了所有种子后每次结果还是不一样 pytorch可重复 可复现问题

这个问题耗费了我一下午加一晚上,现在终于算解决了,但是我现在依旧不清楚是哪里的问题,现在在用控制变量法排查问题

好吧,发现问题了

需要设置:

torch.use_deterministic_algorithms(True)

但是报错了:

RuntimeError: Deterministic behavior was enabled with either `torch.use_deterministic_algorithms(True)` or `at::Context::setDeterministicAlgorithms(true)`, but this operation is not deterministic because it uses CuBLAS and you have CUDA >= 10.2. To enable deterministic behavior in this case, you must set an environment variable before running your PyTorch application: CUBLAS_WORKSPACE_CONFIG=:4096:8 or CUBLAS_WORKSPACE_CONFIG=:16:8. For more information, go to https://docs.nvidia.com/cuda/cublas/index.html#cublasApi_reproducibility

来自官方文档:

Furthermore, if you are using CUDA tensors, and your CUDA version is 10.2 or greater, you should set the environment variable CUBLAS_WORKSPACE_CONFIG according to CUDA documentation: cuBLAS :: CUDA Toolkit Documentation

翻译:

如果CUDA版本为10.2或更高,则少数CUDA操作不确定,除非设置了环境变量 CUBLAS_WORKSPACE_CONFIG=:4096:8 或 CUBLAS_WORKSPACE_CONFIG=:16:8 。

解决方法:

https://neusncp.com/user/blog?id=766

加上这一句代码

os.environ['CUBLAS_WORKSPACE_CONFIG']=':16:8'    

或者是这一句

os.environ['CUBLAS_WORKSPACE_CONFIG']=':4096:8'

折腾了一天,终于解决了

总结

def set_rng_seed(seed):
    random.seed(seed) #为python设置随机种子
    np.random.seed(seed)  #为numpy设置随机种子
    torch.manual_seed(seed)   #为CPU设置随机种子
    torch.cuda.manual_seed(seed)   #为当前GPU设置随机种子
    os.environ['PYTHONHASHSEED'] = str(seed)
    torch.cuda.manual_seed_all(seed)   #为所有GPU设置随机种子
    torch.backends.cudnn.benchmark = False
    torch.backends.cudnn.deterministic = True
    torch.backends.cudnn.enabled = True
    os.environ['CUBLAS_WORKSPACE_CONFIG'] = ':16:8'
    torch.use_deterministic_algorithms(True)

你可能感兴趣的:(学习)