pytorch常用代码,持续更新

1、单GPU,多GPU模型参数名字不一样

多GPU加载需要module名字
如果有时候报错 DataParallel找不到属性,加入
self.model = torch.nn.DataParallel(self.model) #默认有.module 名字
加载参数层也要加self.model.module.

            ######### multi gpu  load one gpu need mudule.
            print ("model  load  param   ###########################")
            pretrained_dict = torch.load("model_ir_se50.pth")
            self.model_dict = self.model.state_dict()  #get the name:value
            param={}
            for k, v in pretrained_dict.items():
                if k[7:] !="module" :
                    param["module."+k] = pretrained_dict[k]

            pretrained_dict = { k: v for k, v in param.items() if k in self.model_dict}
            self.model_dict.update(pretrained_dict)
            self.model.load_state_dict(self.model_dict)

1.1多GPU 训练代码

写法1 .cuda

torch.nn.DataParallel(self.model).cuda()

os.environ['CUDA_VISIBLE_DEVICES'] = "2,3"
use_cuda = torch.cuda.is_available()
torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

model = resnet()
 if use_cuda:
       self.model = torch.nn.DataParallel(self.model).cuda()
       ######### multi gpu  load one gpu need mudule.
       print ("model  load  param   ###########################")
       pretrained_dict = torch.load("model_ir_se50.pth")
       self.model_dict = self.model.state_dict()  #get the name:value
       param={}
       for k, v in pretrained_dict.items():
           if k[7:] !="module" :
               param["module."+k] = pretrained_dict[k]

       pretrained_dict = { k: v for k, v in param.items() if k in self.model_dict}
       self.model_dict.update(pretrained_dict)
       self.model.load_state_dict(self.model_dict)
       print('{}_{} model generated'.format(conf.net_mode, conf.net_depth))       


   # print model param  打印模型参数量
      type_size=4
      para = sum([np.prod(list(p.size())) for p in self.model.parameters()])
      print('res50Model {} : params: {:4f}M'.format(self.model._get_name(), para * type_size / 1000 / 1000))

在pytorch1.0之后的版本中,用 .cuda写法

os.environ['CUDA_VISIBLE_DEVICES'] = "2,3" #不管电脑的环境是多少块卡,现在只用电脑的23卡,并且默认修改成01的编号
use_cuda = torch.cuda.is_available()
if torch.cuda.device_count() > 1: #模型变成并行的
    print("Let's use", torch.cuda.device_count(), "GPUs!")
    model = nn.DataParallel(model)
if torch.cuda.is_available():  #参数搬到GPU   .cuda(),默认制定的所有GPU,
    model.cuda()
###加载模型参数   .module.state_dict()
model.save.state_dict()
model_dict = torch.load(args.pretrained_model_path).module.state_dict()
# 载入参数
model.module.load_state_dict(model_dict)
    

以前的版本用,device_ids,
nn.DataParallel(model, device_ids=GPUs)

 # device_ids: GPU的编号(默认全部GPU)
 '''
 定义device,其中需要注意的是“cuda:0”代表起始的device_id为0,如果直接是“cuda”,同样默认是从0开始。可以根据实际需要修改起始位置,如“cuda:1”。"cuda"默认是“cuda:0”
单GPU,直接model.to(device)就可以在单个GPU上训练,但如果是多个GPU就需要用到nn.DataParallel函数,然后在进行一次to(device)
 '''
 
    device =  torch.device("cuda:1" if torch.cuda.is_available() else "cpu") #制定GPU从1卡开始
    self.model = nn.DataParallel(self.model,device_ids=[1,2,3])   
    self.model.to(device)   

pytorch常用代码,持续更新_第1张图片

1.2 多GPU保存测试操作

1、官方建议的模型保存方式,只保存参数:
这样可以更灵活,加载模型测试,不用管GPU 号,服务器环境的错误
torch.save(model.module.state_dict(), “model.pkl”) #pth 一样
torch.save(model.state_dict(), “model.pkl”) #pth 一样单GPU保存
两者只是区别名字 module
但是需要先加载模型py 文件,再加载参数,两步走

import torchvision
import torch
from torchvision import transforms
import os
import numpy as np
from PIL import Image
import sys
sys.path.append("/home/shiyy/nas/all_workspace/InsightFace_Pytorch-master")  #有model.py
from model import Backbone

## 保存的是多GPU 参数,有module,名字,model加载后面可以torch.nn.DataParallel
transform=transforms.Compose([
            transforms.Resize(112),
            # transforms.CenterCrop(224),
            transforms.ToTensor(),
            transforms.Normalize(mean=[0.5],
                                 std=[1])
                            ])


os.environ['CUDA_VISIBLE_DEVICES'] = "0,1,2"
    
def pytorch_out():
    model = Backbone(50, 0.6, "ir_se") ##get the net #50  0.6 ir_sge
    model = torch.nn.DataParallel(model).cuda() #the start is 0  because "cuda:0"
    
    ######### multi gpu  load one gpu need mudule.
    print ("model  load  param   ###########################")
    pretrained_dict = torch.load("best_model_2020-03-16-01-21_accuracy%3A0.8854285714285715_step%3A48000_ir_se.pth")
    model_dict = model.state_dict()  #get the name:value
    param={}
    for k, v in pretrained_dict.items():
        if k[7:] !="module" :
            param["module."+k] = pretrained_dict[k]

    pretrained_dict = { k: v for k, v in param.items() if k in model_dict}
    model_dict.update(pretrained_dict)
    model.load_state_dict(model_dict)
    ##模型参数加载结束
    ## 开始评估代码

    model.eval()###must to write
    torch.no_grad()

2、也可以直接保存模型(参数+图),测试环境不变可以这样,

torch.save(model, “model.pkl”) #如果是多GPU就要多GPU,并且GPU号也要一样
torch.load( “model.pkl”)
这样做很实用,特别是我们需要反复建模和调试的时候。这种情况下模型的加载很方便,因为模型的图已经和参数保存在一起,我们不需要根据不同的模型设置相应的超参,更换对应的网络结构,
但是需要注意,这种方式加载的是多GPU下模型。如果服务器环境变化不大,或者和训练时候是同一个GPU环境,就不会出现问题

2、得到图片路径的文件,代码

    # 获取当前脚本的文件目录
    root_dir = os.path.dirname(os.path.realpath(__file__))  #  /home/data  最后面没有/
     imageDirs = "imgs"  #相对路径
    imageDirs = os.path.join(root_dir, imageDirs)  #会添加  /  
    landmarkDirs = list(map((root_dir + '/').__add__, landmarkDirs)) # 直接添加/
    ## 两种连接方式

3.tensor numpy互转

对每一tensor先转换成numpy类型,然后在进行操作
return torch.Tensor( np.array( [self.vgg16(item).numpy() for item in data] ) )

tensor – > numpy 方法是 .numpy()
numpy–>tensor 方法是 torch.from_numpy()

1.ndarray->tensor :

b=torch.from_numpy(a)

2.tensor->ndarray:

b=a.numpy()

‘’’
但这么写会报错……
RuntimeError: Can’t call numpy() on Variable that requires grad. Use var.detach().numpy() instead.
‘’’
修改为
b=a.detach().numpy()

‘’’
gpu上的tensor不能直接转为numpy
‘’’
b=a.cpu().numpy()

3.ndarray->list

b=a.tolist()

4.list->ndarray

b=numpy.array(a)

4 导入不同文件py 文件

import numpy
import sys;
sys.path.append(“/home/a/”)
import b #from b import sum #从 b 文件导入sum 函数
sys.path.append(“/home/p/”)
import c

你可能感兴趣的:(pytorch常用代码,持续更新)