多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 .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)
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环境,就不会出现问题
# 获取当前脚本的文件目录
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)) # 直接添加/
## 两种连接方式
对每一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)
import numpy
import sys;
sys.path.append(“/home/a/”)
import b #from b import sum #从 b 文件导入sum 函数
sys.path.append(“/home/p/”)
import c