2024-04-26 06:10:35 发布
网友
我在寻找其他方法来拯救一个在PyTorch训练过的模特。到目前为止,我已经找到了两种选择
我遇到过这种情况,即建议采用方法2而不是方法1
我的问题是,为什么选择第二种方法?这仅仅是因为torch.nn模块具有这两个功能,我们被鼓励使用它们吗
我在他们的github repo上找到了this page,我将把内容粘贴到这里
序列化和恢复模型有两种主要方法
第一个(推荐)仅保存和加载模型参数:
torch.save(the_model.state_dict(), PATH)
随后:
the_model = TheModelClass(*args, **kwargs) the_model.load_state_dict(torch.load(PATH))
第二个选项保存并加载整个模型:
torch.save(the_model, PATH)
the_model = torch.load(PATH)
但是,在这种情况下,序列化数据绑定到特定的类 并且使用了精确的目录结构,因此当 在其他项目中使用,或在一些严重的重构之后使用
这取决于你想做什么
案例#1:保存模型以供自己进行推理:保存模型,恢复模型,然后将模型更改为评估模式。这样做是因为通常有BatchNorm和Dropout层,默认情况下,它们在构造时处于训练模式:
BatchNorm
Dropout
torch.save(model.state_dict(), filepath) #Later to restore: model.load_state_dict(torch.load(filepath)) model.eval()
案例#2:保存模型以稍后恢复训练:如果需要继续训练要保存的模型,则需要保存的不仅仅是模型。您还需要保存优化器的状态、时代、分数等。您可以这样做:
state = { 'epoch': epoch, 'state_dict': model.state_dict(), 'optimizer': optimizer.state_dict(), ... } torch.save(state, filepath)
要恢复训练,您可以执行以下操作:state = torch.load(filepath),然后恢复每个对象的状态,如下所示:
state = torch.load(filepath)
model.load_state_dict(state['state_dict']) optimizer.load_state_dict(state['optimizer'])
由于您正在恢复训练,在加载时恢复状态后,不要调用model.eval()
model.eval()
案例#3:供无法访问您的代码的其他人使用的模型: 在Tensorflow中,您可以创建一个.pb文件来定义模型的体系结构和权重。这非常方便,特别是在使用Tensorflow serve时。在Pytorch中执行此操作的等效方法为:
.pb
Tensorflow serve
torch.save(model, filepath) # Then later: model = torch.load(filepath)
这种方式仍然不是防弹的,因为pytorch仍在经历很多变化,所以我不推荐它
picklePython库实现用于序列化和反序列化Python对象的二进制协议
当您import torch(或使用PyTorch)时,它将为您import pickle,您不需要直接调用pickle.dump()和pickle.load(),这是保存和加载对象的方法
import torch
import pickle
pickle.dump()
pickle.load()
事实上,torch.save()和torch.load()将为您包装pickle.dump()和pickle.load()
torch.save()
torch.load()
答{}提到的另一个答案值得再多注意几点
PyTorch里面有什么? 实际上有两个state_dict
state_dict
PyTorch模型是torch.nn.Module,它有model.parameters()调用来获取可学习的参数(w和b)。 这些可学习的参数一旦随机设置,就会随着时间的推移而更新。 可学习的参数是第一个state_dict
torch.nn.Module
model.parameters()
第二个state_dict是优化器状态dict。您还记得优化器用于改进可学习的参数。但是优化器state_dict是固定的。那里没什么可学的
因为state_dict对象是Python字典,所以它们可以很容易地保存、更新、修改和恢复,从而为PyTorch模型和优化器添加了大量的模块性
让我们创建一个超级简单的模型来解释这一点:
import torch import torch.optim as optim model = torch.nn.Linear(5, 2) # Initialize optimizer 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("Model weight:") print(model.weight) print("Model bias:") print(model.bias) print("---") 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: weight torch.Size([2, 5]) bias torch.Size([2]) Model weight: Parameter containing: tensor([[ 0.1328, 0.1360, 0.1553, -0.1838, -0.0316], [ 0.0479, 0.1760, 0.1712, 0.2244, 0.1408]], requires_grad=True) Model bias: Parameter containing: tensor([ 0.4112, -0.0733], requires_grad=True) --- Optimizer's state_dict: state {} param_groups [{'lr': 0.001, 'momentum': 0.9, 'dampening': 0, 'weight_decay': 0, 'nesterov': False, 'params': [140695321443856, 140695321443928]}]
注意,这是一个最小模型。您可以尝试添加一堆连续数据
model = torch.nn.Sequential( torch.nn.Linear(D_in, H), torch.nn.Conv2d(A, B, C) torch.nn.Linear(H, D_out), )
请注意,只有具有可学习参数的层(卷积层、线性层等)和注册缓冲区(batchnorm层)在模型的state_dict中才有条目
不可学习的东西属于优化器对象state_dict,它包含有关优化器状态的信息以及所使用的超参数
故事的其余部分是相同的;在推理阶段(这是我们在训练后使用模型的阶段)进行预测;我们确实根据我们学到的参数进行预测。因此,对于推断,我们只需要保存参数model.state_dict()
model.state_dict()
torch.save(model.state_dict(), filepath)
以后再使用 model.load\u state\u dict(torch.load(filepath)) model.eval()
注意:不要忘记最后一行model.eval()这在加载模型后是至关重要的
也不要试图保存torch.save(model.parameters(), filepath)。model.parameters()只是生成器对象
torch.save(model.parameters(), filepath)
另一方面,torch.save(model, filepath)保存模型对象本身,但请记住,模型没有优化器的state_dict。检查@Jadiel de Armas的另一个优秀答案,以保存优化器的状态指令
torch.save(model, filepath)
我在他们的github repo上找到了this page,我将把内容粘贴到这里
保存模型的推荐方法
序列化和恢复模型有两种主要方法
第一个(推荐)仅保存和加载模型参数:
随后:
第二个选项保存并加载整个模型:
随后:
但是,在这种情况下,序列化数据绑定到特定的类 并且使用了精确的目录结构,因此当 在其他项目中使用,或在一些严重的重构之后使用
这取决于你想做什么
案例#1:保存模型以供自己进行推理:保存模型,恢复模型,然后将模型更改为评估模式。这样做是因为通常有
BatchNorm
和Dropout
层,默认情况下,它们在构造时处于训练模式:案例#2:保存模型以稍后恢复训练:如果需要继续训练要保存的模型,则需要保存的不仅仅是模型。您还需要保存优化器的状态、时代、分数等。您可以这样做:
要恢复训练,您可以执行以下操作:
state = torch.load(filepath)
,然后恢复每个对象的状态,如下所示:由于您正在恢复训练,在加载时恢复状态后,不要调用
model.eval()
案例#3:供无法访问您的代码的其他人使用的模型: 在Tensorflow中,您可以创建一个
.pb
文件来定义模型的体系结构和权重。这非常方便,特别是在使用Tensorflow serve
时。在Pytorch中执行此操作的等效方法为:这种方式仍然不是防弹的,因为pytorch仍在经历很多变化,所以我不推荐它
picklePython库实现用于序列化和反序列化Python对象的二进制协议
当您
import torch
(或使用PyTorch)时,它将为您import pickle
,您不需要直接调用pickle.dump()
和pickle.load()
,这是保存和加载对象的方法事实上,
torch.save()
和torch.load()
将为您包装pickle.dump()
和pickle.load()
答{}提到的另一个答案值得再多注意几点
PyTorch里面有什么? 实际上有两个
state_dict
PyTorch模型是
torch.nn.Module
,它有model.parameters()
调用来获取可学习的参数(w和b)。 这些可学习的参数一旦随机设置,就会随着时间的推移而更新。 可学习的参数是第一个state_dict
第二个
state_dict
是优化器状态dict。您还记得优化器用于改进可学习的参数。但是优化器state_dict
是固定的。那里没什么可学的因为
state_dict
对象是Python字典,所以它们可以很容易地保存、更新、修改和恢复,从而为PyTorch模型和优化器添加了大量的模块性让我们创建一个超级简单的模型来解释这一点:
此代码将输出以下内容:
注意,这是一个最小模型。您可以尝试添加一堆连续数据
请注意,只有具有可学习参数的层(卷积层、线性层等)和注册缓冲区(batchnorm层)在模型的
state_dict
中才有条目不可学习的东西属于优化器对象
state_dict
,它包含有关优化器状态的信息以及所使用的超参数故事的其余部分是相同的;在推理阶段(这是我们在训练后使用模型的阶段)进行预测;我们确实根据我们学到的参数进行预测。因此,对于推断,我们只需要保存参数
model.state_dict()
以后再使用 model.load\u state\u dict(torch.load(filepath)) model.eval()
注意:不要忘记最后一行
model.eval()
这在加载模型后是至关重要的也不要试图保存
torch.save(model.parameters(), filepath)
。model.parameters()
只是生成器对象另一方面,
torch.save(model, filepath)
保存模型对象本身,但请记住,模型没有优化器的state_dict
。检查@Jadiel de Armas的另一个优秀答案,以保存优化器的状态指令相关问题 更多 >
编程相关推荐