PyTorch模型保存与加载

文章目录

      • 1.什么是状态字典:state_dict?
      • 2. 保存和加载推理模型
        • 2.1 保存/加载state_dict(推荐使用)
        • 2.2 保存/加载完整模型
      • 3. 保存和加载 Checkpoint 用于推理/继续训练
      • 4. 在一个文件中保存多个模型
      • 5. 使用在不同模型参数下的热启动模式
      • 6. 通过设备保存/加载模型
        • 6.1 保存到 CPU、加载到 CPU
        • 6.2 保存到 GPU、加载到 GPU
        • 6.3 保存到 CPU,加载到 GPU
        • 6.4 保存 torch.nn.DataParallel 模型

当保存和加载模型时,需要熟悉三个核心功能:

  1. torch.save:将序列化对象保存到磁盘。此函数使用Python的pickle模块进行序列化。使用此函数可以保存如模型、tensor、字典等各种对象。
  2. torch.load:使用pickle的unpickling功能将pickle对象文件反序列化到内存。此功能还可以有助于设备加载数据。
  3. torch.nn.Module.load_state_dict:使用反序列化函数 state_dict 来加载模型的参数字典。

1.什么是状态字典:state_dict?

在PyTorch中,torch.nn.Module模型的可学习参数(即权重和偏差)包含在模型的参数中,(使用model.parameters()可以进行访问)。 state_dict是Python字典对象,它将每一层映射到其参数张量。注意,只有具有可学习参数的层(如卷积层,线性层等)的模型 才具有state_dict这一项。目标优化torch.optim也有state_dict属性,它包含有关优化器的状态信息,以及使用的超参数。

因为state_dict的对象是Python字典,所以它们可以很容易的保存、更新、修改和恢复,为PyTorch模型和优化器添加了大量模块。

下面通过从简单模型训练一个分类器中来了解一下state_dict的使用。

# 定义模型
class TheModelClass(nn.Module):
    def __init__(self):
        super(TheModelClass, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1 = nn.Linear(16 * 5 * 5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16 * 5 * 5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

# 初始化模型
model = TheModelClass()

# 初始化优化器
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

# 打印模型的状态字典
print("Model's state_dict:")
for param_tensor in model.state_dict():
    print(param_tensor, "\t", model.state_dict()[param_tensor].size())

# 打印优化器的状态字典
print("Optimizer's state_dict:")
for var_name in optimizer.state_dict():
    print(var_name, "\t", optimizer.state_dict()[var_name])

输出:

Model's state_dict:
conv1.weight     torch.Size([6, 3, 5, 5])
conv1.bias   torch.Size([6])
conv2.weight     torch.Size([16, 6, 5, 5])
conv2.bias   torch.Size([16])
fc1.weight   torch.Size([120, 400])
fc1.bias     torch.Size([120])
fc2.weight   torch.Size([84, 120])
fc2.bias     torch.Size([84])
fc3.weight   torch.Size([10, 84])
fc3.bias     torch.Size([10])

Optimizer's state_dict:
state    {}
param_groups     [{'lr': 0.001, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0, 'nesterov': False, 'params': [4675713712, 4675713784, 4675714000, 4675714072, 4675714216, 4675714288, 4675714432, 4675714504, 4675714648, 4675714720]}]

2. 保存和加载推理模型

2.1 保存/加载state_dict(推荐使用)

  • 保存
torch.save(model.state_dict(), PATH)
  • 加载
model = TheModelClass(*args, **kwargs)
model.load_state_dict(torch.load(PATH))
model.eval()

当保存好模型用来推断的时候,只需要保存模型学习到的参数,使用torch.save()函数来保存模型state_dict,它会给模型恢复提供 最大的灵活性,这就是为什么要推荐它来保存的原因。

注意1:在 PyTorch 中最常见的模型保存使‘.pt’或者是‘.pth’作为模型文件扩展名。
请记住,在运行推理之前,务必调用model.eval()去设置 dropout 和 batch normalization 层为评估模式。如果不这么做,可能导致 模型推断结果不一致。

注意2:
load_state_dict()函数只接受字典对象,而不是保存对象的路径。这就意味着在你传给load_state_dict()函数之前,你必须反序列化 你保存的state_dict。例如,你无法通过 model.load_state_dict(PATH)来加载模型。

2.2 保存/加载完整模型

  • 保存
torch.save(model, PATH)
  • 加载
# 模型类必须在此之前被定义
model = torch.load(PATH)
model.eval()

此部分保存/加载过程使用最直观的语法并涉及最少量的代码。以 Python pickle 模块的方式来保存模型。这种方法的缺点是序列化数据受 限于某种特殊的类而且需要确切的字典结构。这是因为pickle无法保存模型类本身。相反,它保存包含类的文件的路径,该文件在加载时使用。 因此,当在其他项目使用或者重构之后,您的代码可能会以各种方式中断。

注意:在 PyTorch 中最常见的模型保存使用‘.pt’或者是‘.pth’作为模型文件扩展名。
请记住,在运行推理之前,务必调用model.eval()设置 dropout 和 batch normalization 层为评估模式。如果不这么做,可能导致模型推断结果不一致。

3. 保存和加载 Checkpoint 用于推理/继续训练

4. 在一个文件中保存多个模型

5. 使用在不同模型参数下的热启动模式

6. 通过设备保存/加载模型

6.1 保存到 CPU、加载到 CPU

6.2 保存到 GPU、加载到 GPU

6.3 保存到 CPU,加载到 GPU

6.4 保存 torch.nn.DataParallel 模型

【本文转载自】:
PyTorch专栏(七):模型保存与加载那些事:https://cloud.tencent.com/developer/article/1507565

你可能感兴趣的:(PyTorch,服务器,svn,linux)