pytorch GPU和CPU模型相互加载

一 模型保存加载方法

注意:torch.load 进行加载模型的时候,会根据模型训练方式(CPU训练或者GPU训练),自动选择加载设备

1.1、直接保存模型(参数+网络)

# 保存模型
torch.save(model, 'model.pth')

# 加载模型
model = torch.load('model.pth')

1.2、只保存参数;(官方推荐)

由于保存整个模型将耗费大量的存储,故官方推荐只保存参数,然后在建好模型的基础上加载

# 保存模型参数
torch.save(model.state_dict(), path)

# 加载模型参数
model.load_state_dict(torch.load(path))

特别地,如果还想保存某一次训练采用的优化器、epochs等信息,可将这些信息组合起来构成一个字典,然后将字典保存起来:

# 要保存的 模型参数、optimizer、epoch 的字典state
state = {'model': model.state_dict(), 
		'optimizer': optimizer.state_dict(), 
		'epoch': epoch}


# **************** 模型保存****************
# 保存 字典 state
torch.save(state, path)


# **************** 模型加载****************
# 加载保存的字典 state
checkpoint = torch.load(path)

# 依次加载 模型参数、optimizer、epoch 
model.load_state_dict(checkpoint['model'])
optimizer.load_state_dict(checkpoint['optimizer'])
epoch = checkpoint(['epoch'])

需要注意的是,只保存参数的方法在加载的时候要事先定义好跟原模型一致的模型,并在该模型的实例对象(假设名为model)上进行加载,即在使用上述加载语句前已经有定义了一个和原模型一样的Net, 并且进行了实例化 model=Net( ) 。

1.3、model.state_dict() 和 model.load_state_dict() 函数解释

model.state_dict(), model.load_state_dict()、model.parameters() 的解释请看:

PyTorch模型保存深入理解 - 简书

关于model.parameters(), model.named_parameters(), model.children(), model.named_children(), model.modules(), model.named_modules() 请看:

PyTorch中的model.modules(), model.children(), model.named_children(), model.parameters(), model.nam... - 简书

二 GPU和CPU模型相互加载

1、单CPU 和 单GPU 模型相互加载

pytorch允许把在GPU上训练的模型加载到CPU上,也允许把在CPU上训练的模型加载到GPU上。

加载模型参数的时候,在GPU和CPU训练的模型是不一样的,这两种模型是不能混为一谈的,下面分情况进行操作说明。

情况一:模型参数(CPU->CPU,GPU->GPU)  

模型是GPU模型,预加载的训练参数也是GPU;模型是CPU模型,预加载的训练参数也是CPU,这种情况下我们都只用直接用下面的语句即可:

torch.load('model_dict.pth')

情况二:模型参数(GPU->CPU) 

模型是CPU模型,预加载的训练参数却是GPU,那么需要将先将GPU模型参数加载到 CPU上:

torch.load('model_dict.pkl', map_location=lambda storage, loc: storage)

torch.load('model_dict.pkl', map_location='cpu')  # pytorch0.4.0及以上版本

情况三:模型参数(CPU->GPU, CPU->GPU1) 

模型是GPU或者GPU1模型,预加载的训练参数却是CPU, 那么需要将CPU模型参数加载到 GPU上:

# CPU->GPU 
torch.load('model_dic.pkl', map_location=lambda storage, loc: storage.cuda)

# CPU->GPU1   模型是GPU1,预加载的训练参数却是CPU:
torch.load('model_dic.pkl', map_location=lambda storage, loc: storage.cuda(1))

2、多GPU上训练的模型保存和加载

2.1 多GPU保存模型保存

多GPU模式下的情况:

# 以下两种模型都是在多GPU上训练, 只有当(GPU >=2)时候才使用
model= torch.nn.DaraParallel(model) # 数据并行
model = torch.nn.parallel.DistributedDataParallel(model) #分布式训练

多GPU训练模型保存参数时,可以去掉 “module.”前缀,这样以后CPU或者单GPU模式加载模型时,相对比较方便。

a、多GPU保存参数与网络:

torch.save(model.module,'model.pth')

b、多GPU只保存参数:

model.module 操作可以去掉多GPU训练模型时候加的module前缀

#方式1----只保存参数, model.module操作可以去掉多GPU保存参数时候加的module前缀
torch.save(model.module.state_dict(), 'model.pth')

2.2 加载多GPU模型参数(去掉“module.”前缀)

在单gpu或cpu上加载一个在多gpu上训练的模型时,会报类似如下错误:

Unexpected key(s) in state_dict: "module.pretrained.conv1.0.weight", "module.pretrained.conv1.1.weight"

这是因为在多GPU上训练的模型保存时,在参数名前多加了一个“module.”前缀,保存时并没有把“module”前缀 去掉,因此加载参数的时候把这个前缀去掉就行了:

from collections import OrderedDict
# 模型初始化, CPU上模型
model = net()

# 模型参数加载到的设备
device = torch.device('cpu')
# device = torch.device('cuda:0')

# 多GPU 模型参数加载到 CPU上,这里xxx.pth保存的只是参数
state_dict = torch.load('xxx.pth', map_location=device)

# 多GPU 模型参数去掉 module
state_dict_new = OrderedDict()
for k, v in state_dict.items():
    name = k[7:]  # 去掉 `module.`
	# name = k.replace(“module.", "")
    state_dict_new[name] = v

# 模型加载参数(去掉module)
model.load_state_dict(state_dict_new)

2.3 多GPU模型参数直接加载

2.2 节主要是在保存和加载多GPU模型时,去掉“module.”前缀,这一节主要讲,另一种加载多GPU模型的方法

Case-1. 载入为多GPU网络+权重, 模型为单GPU或者CPU

load() 加载多GPU网络+权重后,获取module部分权重moduel_part,然模型就可以直接加载moduel_part了,此时模型CPU或者GPU都可以

# 模型初始化
model   = Mode()        # CPU 模型
model   = Mode().cuda() # 单GPU 模型
# 加载 多GPU 网络+权重
pretrained_model = torch.load('muti_gpus_model.pth')   

# 只获取 module 部分的数据,可以用于 单GPU或者CPU模型加载
moduel_part      = pretrained_model.module 

# 获取module部分的参数字典,可以用于保存或者加载模型参数
pretained_dict  = pretained_model.module.state_dict()

# 加载模型参数
model.load_state_dict(pretained_dict)

# cpu模型存储, model.state_dict() 是只保存模型权重
torch.save(model.state_dict(), 'mode.pth') 

Case-2.载入多GPU权重, 模型为多GPU模型

多GPU模型模型初始化后,多GPU权重可以直接加载

model = Model().cuda(0)   # 网络结构
# 将model转为muit-gpus模式
model = torch.nn.DataParallel(model, device_ids=[0])
# 载入多GPU 网络 weights  
checkpoint = torch.load(model_path, map_location=lambda storage, loc: storage)
# 用 多GPU weights 直接初始化网络 多GPU模型 
model.load_state_dict(checkpoint) 

Case-3.载入CPU权重

注意:第三个多GPU模型 weight参数载入使用的是 model.module.load_state_dict(checkpoint)


(1)
# 模型放到 CPU
model = Model()
# cpu 模型 直接载入 weights
checkpoint = torch.load(model_path, map_location=lambda storage, loc: storage)

******************************************
(2)
# 模型放到 单GPU
model = Model().cuda()
# 载入weights   到 cuda 中
checkpoint = torch.load(model_path, map_location=lambda storage, loc: storage.cuda(0)) 
# 单GPU 模型直接 载入 cuda的weights
model.load_state_dict(checkpoint)  # 用weights初始化网络

****************************************** 
(3)
model = Model().cuda()   # 网络结构
# 模型放到 muti-gpus 中
# device_ids根据自己需求改!
model = torch.nn.DataParallel(model, device_ids=[0, 1])
# 载入weights   到 cuda 中
checkpoint = torch.load(model_path, map_location=lambda storage, loc: storage.cuda(0))
# 多GPU模型 model.module 模块直接 载入 cuda的weights
model.module.load_state_dict(checkpoint)  # 用weights初始化网络
  • 17
    点赞
  • 76
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 在使用PyTorch进行深度学习任务时,可以通过将计算从CPU转移到GPU上来加快模型训练和推理的速度。下面是使用PyTorch将计算从CPU转移到GPU的步骤: 1.首先,需要检查计算机是否具有支持CUDA的GPU。使用以下代码可以检查GPU是否可用: ``` import torch if torch.cuda.is_available(): device = torch.device("cuda") # 使用GPU else: device = torch.device("cpu") # 使用CPU ``` 2.接下来,将模型和数据加载到设备上。可以使用以下代码将模型和张量加载到所选设备上: ``` model = YourModel().to(device) # 将模型加载到设备上 input_data = torch.randn(batch_size, input_size).to(device) # 将输入数据加载到设备上 ``` 这将确保模型和数据都在GPU上进行计算。 3.在训练过程中,使用以下代码将输入数据和模型参数传递给GPU: ``` for epoch in range(num_epochs): # ... output = model(input_data) # 将输入数据传递给模型 loss = loss_function(output, target) # 计算损失函数 model.zero_grad() # 清除梯度 loss.backward() # 反向传播计算梯度 optimizer.step() # 更新参数 # ... ``` 即使计算不再在CPU上进行,PyTorch可以自动将相关操作标记为需要在GPU上执行。 需要注意的是,将计算从CPU转移到GPU上可能需要一定的时间,因为需要将数据从主内存复制到显存。因此,在小规模数据集上,将计算移动到GPU可能会导致速度下降。但是,对于大规模数据集和复杂的模型,使用GPU进行计算通常可以显著加快训练和推理速度。 最后,当训练或推理完成后,可以使用以下代码将模型和数据从GPU转移到CPU上: ``` model = model.to("cpu") # 将模型加载CPU上 input_data = input_data.to("cpu") # 将输入数据加载CPU上 ``` 这样可以释放GPU显存,并在不需要GPU计算的情况下减少资源消耗。 ### 回答2: 在PyTorch中,将模型CPU转移到GPU是非常简单的。首先,确保您的系统上已经安装了正确的PyTorch和CUDA版本,并且您的计算机具有至少一个NVIDIA GPU。 首先,将模型转移到GPU之前,需要确保将模型和输入数据都转换成PyTorch Tensor对象。然后,使用`to()`方法将Tensor转移到GPU上。 下面是一个简单的示例代码: ```python import torch # 定义模型 model = YourModel() # 将模型参数从CPU转移到GPU model.to(torch.device("cuda")) # 定义输入数据并转移到GPU input_data = torch.tensor([1, 2, 3]) input_data = input_data.to(torch.device("cuda")) # 在GPU上运行模型 output = model(input_data) # 将结果转移到CPU上 output = output.to(torch.device("cpu")) ``` 在上面的代码中,`to(torch.device("cuda"))`将模型参数和输入数据都转移到GPU上。然后,可以在GPU上运行模型并得到输出结果。最后,使用`to(torch.device("cpu"))`将结果转移到CPU上,以便进一步处理或输出。 需要注意的是,在转移到GPU之前,确保您的GPU上有足够的内存来存储模型和输入数据。如果GPU内存不够,可能会导致内存溢出错误。 此外,还可以使用`torch.cuda.is_available()`来检查系统是否有可用的GPU。如果返回True,表示系统上有可用的GPU,否则表示只能在CPU上运行。 ### 回答3: 在PyTorch中,将计算从CPU转移到GPU可以显著加速训练和推断过程。下面是将PyTorch代码从CPU迁移到GPU的步骤: 1. 首先,需要确保系统上已安装并配置了可以使用的GPU驱动程序和CUDA工具包,以便PyTorch可以利用GPU资源。 2. 在PyTorch代码中,首先需要将模型和输入数据加载CPU上。可以使用`torch.device`函数指定设备,将其设置为`'cpu'`。 3. 接下来,创建模型实例并将其移动到设备上。可以使用`model.to(device)`函数将模型加载到指定设备。例如,`model = model.to(device)`将模型加载CPU上。 4. 对于输入数据,同样使用`input_variable = input_variable.to(device)`将其移动到设备上。这里的`input_variable`可以是张量、数据加载器或数据集,取决于具体的代码实现。 5. 如果使用了优化器(如SGD或Adam),同样需要将其关联的参数移动到指定设备上。可以使用`optimizer = optimizer.to(device)`将优化器加载到设备上。 6. 最后,迭代训练过程中的每个批次或推断过程中的每个样本时,确保将数据也加载到设备上。可以使用`inputs, labels = inputs.to(device), labels.to(device)`将每个批次加载到指定设备。 这样一来,PyTorch将使用GPU来进行计算,从而加速模型训练和推断过程。在某些情况下,将计算从CPU转移到GPU还可以节省内存,并允许处理更大规模的数据集。 总结起来,将PyTorch代码从CPU转移到GPU的步骤是加载模型、输入数据和优化器到设备上,并确保在计算过程中也将数据加载到设备上。这样可以利用GPU资源进行加速计算。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值