python 模型保存与调用_pytorch保存和加载模型

torch.save:将序列化的对象保存到磁盘。此函数使用Python的pickle进行序列化。使用此功能可以保存各种对象的模型,tensor和dict。

state_dict 是什么?

在PyTorch中,torch.nn.Module模型的可学习参数(即权重和偏差)包含在模型的参数中(可通过model.parameters()获取)。 state_dict 只是一个Python字典对象,它将每个图层映射到其参数tensor。请注意,只有具有可学习参数的层(卷积层,线性层等)和已注册的缓冲区(batchnorm的running_mean)才在模型的state_dict中存在。torch.optim也有state_dict,其中包含有关优化器状态以及所用超参数的信息。由于state_dict对象是Python词典,因此可以轻松地保存,更新,更改和还原它们,从而为PyTorch模型和优化器增加了很多模块化。

# Define model

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

# Initialize model

model = TheModelClass()

# Initialize optimizer

optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

# Print model's state_dict

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

print("Optimizer's state_dict:")

for var_name in optimizer.state_dict():

print(var_name, "\t", optimizer.state_dict()[var_name])

output:

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]}]

Saving & Loading Model for Inference

save:

torch.save(model.state_dict(), PATH)

load:

model = TheModelClass(*args, **kwargs)

model.load_state_dict(torch.load(PATH))

model.eval()

保存模型以进行推理时,仅需要保存经过训练的模型的学习参数。用torch.save函数保存模型的state_dict将为您提供最大的灵活性,以便以后还原模型,这就是为什么推荐使用此方法来保存模型的原因。常见的PyTorch约定是使用.pt或.pth文件扩展名保存模型。请记住,在运行推理之前,必须调用model.eval() 来将dropout and batch normalization layers设置为eval() 模式,不这样做将产生不一致的推断结果。

请注意,load_state_dict()函数采用字典对象,而不是保存对象的路径。这意味着您必须先反序列化保存的state_dict,然后再将其传递给load_state_dict()函数。即,不能使用model.load_state_dict(PATH)进行加载。

Saving & Loading a General Checkpoint for Inference and/or Resuming Training

Sava:

torch.save({

'epoch': epoch,

'model_state_dict': model.state_dict(),

'optimizer_state_dict': optimizer.state_dict(),

'loss': loss,

...

}, PATH)

Load:

model = TheModelClass(*args, **kwargs)

optimizer = TheOptimizerClass(*args, **kwargs)

checkpoint = torch.load(PATH)

model.load_state_dict(checkpoint['model_state_dict'])

optimizer.load_state_dict(checkpoint['optimizer_state_dict'])

epoch = checkpoint['epoch']

loss = checkpoint['loss']

model.eval()

# - or -

model.train()

保存用于检查或继续训练的常规checkpoint时,要保存的不只是模型的state_dict,保存优化器的state_dict也很重要,因为它包含随着模型训练而更新的缓冲区和参数,可能要保存的其他是您停止的epoch,最新记录的训练损失,外部torch.nn.Embedding层等。要保存多个组件时,把他们组织字典格式,在外面用torch.sava()保存。常见的PyTorch约定是使用.tar文件扩展名保存这些checkpoint。

要加载项目,请首先初始化模型和优化器,然后使用torch.load()在本地加载字典。从这里,您可以通过简单地查询字典来轻松访问保存的项目。

请记住,在运行推理之前,必须调用model.eval()来将dropout 和 batch normalization layers设置为eval模式。不这样做将产生不一致的推断结果。

如果您希望恢复训练,请调用model.train()以确保这些层处于训练模式。

Saving Multiple Models in One File

Save:

torch.save({

'modelA_state_dict': modelA.state_dict(),

'modelB_state_dict': modelB.state_dict(),

'optimizerA_state_dict': optimizerA.state_dict(),

'optimizerB_state_dict': optimizerB.state_dict(),

...

}, PATH)

Load:

modelA = TheModelAClass(*args, **kwargs)

modelB = TheModelBClass(*args, **kwargs)

optimizerA = TheOptimizerAClass(*args, **kwargs)

optimizerB = TheOptimizerBClass(*args, **kwargs)

checkpoint = torch.load(PATH)

modelA.load_state_dict(checkpoint['modelA_state_dict'])

modelB.load_state_dict(checkpoint['modelB_state_dict'])

optimizerA.load_state_dict(checkpoint['optimizerA_state_dict'])

optimizerB.load_state_dict(checkpoint['optimizerB_state_dict'])

modelA.eval()

modelB.eval()

# - or -

modelA.train()

modelB.train()

保存由多个torch.nn.Modules组成的模型(例如GAN,序列到序列模型或模型集合)时,将采用与保存常规checkpoint相同的方法。换句话说,保存每个模型的state_dict和相应的优化器的字典。如前所述,您可以保存任何其他可以帮助您恢复训练的项,只需将它们添加到字典中即可。常见的PyTorch约定是使用.tar文件扩展名保存这些checkpoint。要加载模型,请首先初始化模型和优化器,然后使用torch.load()在本地加载字典。从这里,您可以通过简单地查询字典来轻松访问保存的项目。

请记住,在运行推理之前,必须调用model.eval()来将dropout 和 batch normalization layers设置为评估模式,不这样做将产生不一致的推断结果。

如果您希望恢复训练,请调用model.train()将这些层设置为训练模式。

Warmstarting Model Using Parameters from a Different Model

Save:

torch.save(modelA.state_dict(), PATH)

Load:

modelB = TheModelBClass(*args, **kwargs)

modelB.load_state_dict(torch.load(PATH), strict=False)

在transfer learning或训练新的复杂模型时,部分加载模型是常见方案。利用经过训练的参数,即使只有少数几个可用的参数,也将有助于热启动训练过程,并希望与从头开始训练相比,可以更快地收敛模型。无论是从缺少某些key(这里说的key,是字典中的key-value)的部分state_dict加载,还是加载比要加载的模型更多的key的state_dict,都可以在load_state_dict()函数中将strict参数设置为False,以忽略不匹配的keys。如果要将参数从一层加载到另一层,但是某些键不匹配,只需更改要加载的state_dict中参数key的名称,以匹配要加载到的模型中的key。

Saving & Loading Model Across Devices

1、Save on GPU, Load on CPU

Save:

torch.save(model.state_dict(), PATH)

Load:

device = torch.device('cpu')

model = TheModelClass(*args, **kwargs)

model.load_state_dict(torch.load(PATH, map_location=device))

2、Save on GPU, Load on GPU

Save:

torch.save(model.state_dict(), PATH)

Load:

device = torch.device("cuda")

model = TheModelClass(*args, **kwargs)

model.load_state_dict(torch.load(PATH))

model.to(device)

# Make sure to call input = input.to(device) on any input tensors that you feed to the model

3、Save on CPU, Load on GPU

Save:

torch.save(model.state_dict(), PATH)

Save:

device = torch.device("cuda")

model = TheModelClass(*args, **kwargs)

model.load_state_dict(torch.load(PATH, map_location="cuda:0"))

# Choose whatever GPU device number you want model.to(device)

# Make sure to call input = input.to(device) on any input tensors that you feed to the model

4、Saving torch.nn.DataParallel Models

Save:

torch.save(model.module.state_dict(), PATH)

Load:

# Load to whatever device you want

torch.nn.DataParallel 是一个模型包装程序,可以并行使用GPU,要以一般方式保存DataParallel模型,请保存model.module.state_dict()。这样,您可以灵活地将所需的模型加载到所需的任何设备。

你可能感兴趣的:(python,模型保存与调用)