pytorch(二十七):模型的保存与加载
pytorch保存模型非常简单,主要有两种方法:
- 只保存参数;(官方推荐)
- 保存整个模型 (结构+参数)。
由于保存整个模型将耗费大量的存储,故官方推荐只保存参数,然后在建好模型的基础上加载。本文介绍两种方法,但只就第一种方法进行举例详解。
一、只保存参数
1.保存
一般地,采用一条语句即可保存参数:
torch.save(model.state_dict(), path)
其中model指定义的模型实例变量,如 model=vgg16( ), path是保存参数的路径,如 path='./model.pth' , path='./model.tar', path='./model.pkl', 保存参数的文件一定要有后缀扩展名。
特别地,如果还想保存某一次训练采用的优化器、epochs等信息,可将这些信息组合起来构成一个字典,然后将字典保存起来:
state = {'model': model.state_dict(), 'optimizer': optimizer.state_dict(), 'epoch': epoch}
torch.save(state, path)
2.加载
针对上述第一种情况,也只需要一句即可加载模型:
model.load_state_dict(torch.load(path))
针对上述第二种以字典形式保存的方法,加载方式如下:
checkpoint = torch.load(path)
model.load_state_dict(checkpoint['model'])
optimizer.load_state_dict(checkpoint['optimizer'])
epoch = checkpoint(['epoch'])
需要注意的是,只保存参数的方法在加载的时候要事先定义好跟原模型一致的模型,并在该模型的实例对象(假设名为model)上进行加载,即在使用上述加载语句前已经有定义了一个和原模型一样的Net, 并且进行了实例化 model=Net( ) 。
另外,如果每一个epoch或每n个epoch都要保存一次参数,可设置不同的path,如 path='./model' + str(epoch) +'.pth',这样,不同epoch的参数就能保存在不同的文件中,选择保存识别率最大的模型参数也一样,只需在保存模型语句前加个if判断语句即可。
下面给出一个具体的例子程序,该程序只保存最新的参数:
#-*- coding:utf-8 -*-
'''本文件用于举例说明pytorch保存和加载文件的方法'''
__author__ = 'puxitong from UESTC'
import torch as torch
import torchvision as tv
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
import torchvision.transforms as transforms
from torchvision.transforms import ToPILImage
import torch.backends.cudnn as cudnn
import datetime
import argparse
# 参数声明
batch_size = 32
epochs = 10
WORKERS = 0 # dataloder线程数
test_flag = True #测试标志,True时加载保存好的模型进行测试
ROOT = '/home/pxt/pytorch/cifar' # MNIST数据集保存路径
log_dir = '/home/pxt/pytorch/logs/cifar_model.pth' # 模型保存路径
# 加载MNIST数据集
transform = tv.transforms.Compose([
transforms.ToTensor(),
transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])])
train_data = tv.datasets.CIFAR10(root=ROOT, train=True, download=True, transform=transform)
test_data = tv.datasets.CIFAR10(root=ROOT, train=False, download=False, transform=transform)
train_load = torch.utils.data.DataLoader(train_data, batch_size=batch_size, shuffle=True, num_workers=WORKERS)
test_load = torch.utils.data.DataLoader(test_data, batch_size=batch_size, shuffle=False, num_workers=WORKERS)
# 构造模型
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 64, 3, padding=1)
self.conv2 = nn.Conv2d(64, 128, 3, padding=1)
self.conv3 = nn.Conv2d(128, 256, 3, padding=1)
self.conv4 = nn.Conv2d(256, 256, 3, padding=1)
self.pool = nn.MaxPool2d(2, 2)
self.fc1 = nn.Linear(256 * 8 * 8, 1024)
self.fc2 = nn.Linear(1024, 256)
self.fc3 = nn.Linear(256, 10)
def forward(self