当前位置: 首页 > news >正文

深度学习——PyTorch保存模型与调用模型


神经网络保存模型与调用模型

在深度学习的实际应用中,模型训练通常需要大量的数据和计算资源。如果每次使用时都从头开始训练,不仅效率低下,还会浪费大量时间。因此,将训练好的模型保存下来,并在需要时直接调用,是非常重要的步骤。本文将详细介绍在 PyTorch 框架下如何保存模型与调用模型。


一、为什么要保存模型?

  1. 节省时间和计算成本:训练神经网络可能需要数小时甚至数天,保存模型可以避免重复训练。

  2. 迁移学习:保存预训练模型,方便后续在其他任务上进行微调。

  3. 模型部署:在推理阶段,通常只需要加载已经训练好的模型权重进行预测。

  4. 实验复现:保存模型可以帮助研究人员复现实验结果,保证实验的可重复性。


二、模型保存的方式

在 PyTorch 中,保存模型主要有两种方式:

1. 保存整个模型

torch.save(model, "model.pth")
  • model:整个模型对象。

  • "model.pth":保存的文件名(扩展名常用 .pth.pt)。

优点:简单,保存后直接可以加载使用。
缺点:依赖代码结构,如果模型类定义发生变化,可能无法加载。

2. 只保存模型参数(推荐)

torch.save(model.state_dict(), "model_params.pth")
  • model.state_dict():返回一个包含所有模型参数的字典。

优点:更灵活、通用,加载时只需保证模型结构一致即可。
缺点:加载时需要先重新定义模型结构,再加载参数。


三、模型调用(加载)

1. 加载整个模型

model = torch.load("model.pth")
model.eval()  # 切换为推理模式

注意:调用时必须确保有相同的代码环境和依赖。

2. 加载模型参数

# 先定义模型结构
model = MyModelClass()
# 再加载参数
model.load_state_dict(torch.load("model_params.pth"))
model.eval()

推荐做法,因为这样更灵活,尤其在迁移学习或分布式训练时。


四、完整示例

下面给出一个小例子,演示如何训练、保存和调用模型。

import torch
import torch.nn as nn
import torch.optim as optim# ====== 定义模型 ======
class SimpleNet(nn.Module):def __init__(self):super(SimpleNet, self).__init__()self.fc1 = nn.Linear(10, 20)self.fc2 = nn.Linear(20, 1)def forward(self, x):x = torch.relu(self.fc1(x))x = self.fc2(x)return xmodel = SimpleNet()
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.01)# ====== 模拟训练 ======
x = torch.randn(100, 10)
y = torch.randn(100, 1)
for epoch in range(5):outputs = model(x)loss = criterion(outputs, y)optimizer.zero_grad()loss.backward()optimizer.step()print(f"Epoch [{epoch+1}/5], Loss: {loss.item():.4f}")# ====== 保存模型 ======
# 方法1:保存整个模型
torch.save(model, "whole_model.pth")# 方法2:保存参数(推荐)
torch.save(model.state_dict(), "model_params.pth")

解释

  • SimpleNet 继承自 nn.Module,是一个最简单的全连接网络。

  • nn.Linear(in_features, out_features):定义全连接层(权重矩阵 + 偏置)。

  • ReLU 激活函数:非线性变换,提升模型表达能力。

  • forward(x):定义前向传播过程。

  • 实例化模型,得到一个 SimpleNet对象

  • criterion = nn.MSELoss()

    • 损失函数:均方误差(Mean Squared Error),常用于回归任务。

    • 计算预测值与真实值之间的平方差。

  • optimizer = optim.SGD(model.parameters(), lr=0.01)

    • 优化器:随机梯度下降(SGD)。

    • model.parameters() 表示需要优化的参数(网络的权重和偏置)。

    • lr=0.01:学习率,控制每次更新参数的幅度。

  • 使用 torch.randn 生成随机数据,模拟训练集。

    • x 的维度 (100, 10):100 条输入,每条是 10 个特征。

    • y 的维度 (100, 1):100 条输出,每条是 1 个目标值。

  • 前向传播model(x) 得到预测结果。

  • 计算损失criterion(outputs, y)

  • 梯度清零:PyTorch 的梯度是累积的,需要 optimizer.zero_grad()

  • 反向传播loss.backward() 自动计算每个参数的梯度。

  • 更新参数optimizer.step() 根据梯度更新权重。

  • 打印结果:显示当前 epoch 的损失值。

调用模型

# 方法1:加载整个模型
loaded_model = torch.load("whole_model.pth")
loaded_model.eval()# 方法2:加载模型参数
new_model = SimpleNet()
new_model.load_state_dict(torch.load("model_params.pth"))
new_model.eval()# 测试推理
test_input = torch.randn(1, 10)
print(new_model(test_input))

五、保存与调用中的注意事项

  1. 训练模式 vs 推理模式

    • 在推理前调用 model.eval(),关闭 DropoutBatchNorm 的训练行为。

    • 在继续训练时调用 model.train()

  2. 保存优化器状态
    如果需要在中断后继续训练,不仅要保存模型参数,还需要保存优化器状态:

    torch.save({'epoch': epoch,'model_state_dict': model.state_dict(),'optimizer_state_dict': optimizer.state_dict(),'loss': loss
    }, "checkpoint.pth")
    

    调用时:

    checkpoint = torch.load("checkpoint.pth")
    model.load_state_dict(checkpoint['model_state_dict'])
    optimizer.load_state_dict(checkpoint['optimizer_state_dict'])
    start_epoch = checkpoint['epoch']
    loss = checkpoint['loss']
    
  3. 文件扩展名
    .pth.pt 都是常见的约定,不影响实际功能。

  4. 跨设备加载
    如果模型是在 GPU 上保存的,但在 CPU 上加载,需要指定:

    torch.load("model_params.pth", map_location=torch.device('cpu'))
    

六、总结

  • 保存方式:保存整个模型(简单) vs 保存参数(推荐)。

  • 调用方式:需注意模型结构定义和推理模式设置。

  • 高级用法:保存和加载优化器状态,以便断点续训。

通过合理地保存和调用模型,可以显著提高实验效率,方便模型复现与部署。


文章转载自:

http://5cWVEOT1.pLpth.cn
http://kqYAn0xC.pLpth.cn
http://p7CzjGXO.pLpth.cn
http://02TJyLJF.pLpth.cn
http://iwU38JHe.pLpth.cn
http://41Aa0TrA.pLpth.cn
http://QmCaxMYL.pLpth.cn
http://HvrucnOO.pLpth.cn
http://d88wulPr.pLpth.cn
http://FhGrATvg.pLpth.cn
http://9iZ85hau.pLpth.cn
http://6Eh7Anpa.pLpth.cn
http://QFrgEv7V.pLpth.cn
http://Sm14TTWB.pLpth.cn
http://vWjWZfrT.pLpth.cn
http://CVXS7VZ7.pLpth.cn
http://1VmzmOwa.pLpth.cn
http://8maz8BeF.pLpth.cn
http://JhOiqUSN.pLpth.cn
http://JaMKDq70.pLpth.cn
http://yDOYC9Lc.pLpth.cn
http://Hb74ZQ7U.pLpth.cn
http://tjOyINoc.pLpth.cn
http://zYIbH1Oh.pLpth.cn
http://CvBWigp2.pLpth.cn
http://ZDfN08DQ.pLpth.cn
http://slbYSUT5.pLpth.cn
http://Mz2Se85E.pLpth.cn
http://KDZUD2ju.pLpth.cn
http://zyxKqz2S.pLpth.cn
http://www.dtcms.com/a/370485.html

相关文章:

  • Go基础(⑤Consul)
  • 验证平台中所有的组件应该派生自UVM中的类
  • 企业微信智能表格高效使用指南
  • 自动化运维之ansible
  • 2025年上海市星光计划第十一届职业院校技能大赛高职组“信息安全管理与评估”赛项交换部分前6题详解(仅供参考)
  • Orin-Apollo园区版本:订阅多个摄像头画面拼接与硬编码RTMP推流
  • 多线程(六) ~ 定时器与锁
  • OpenSSL 1.0.1e 下载解压和运行方法(小白适用 附安装包)​
  • Qt图表功能学习
  • 【营销策略算法】关联规则学习-购物篮分析
  • 部署AIRI
  • 深度学习基础概念回顾(Pytorch架构)
  • 基于LSTM深度学习的网络流量测量算法matlab仿真
  • 【PyTorch实战:Tensor变形】5、 PyTorch Tensor指南:从基础操作到Autograd与GPU加速实战
  • 【基础-判断】@Entry装饰的自定义组件将作为页面的入口。在单个页面中可以使用多个@Entry装饰不同自定义组件。
  • 驱动开发系列71 - GLSL编译器实现 - 指令选择
  • 贪心算法应用:化工反应器调度问题详解
  • OpenAvatarChat项目在Windows本地运行指南
  • canal+DataX实现数据全量/实时同步
  • Jenkins运维之路(自动获得分支tag自动构建)
  • 服务器内存和普通计算机内存在技术方面有什么区别?
  • 同一台nginx中配置多个前端项目的三种方式
  • 【LeetCode热题100道笔记】排序链表
  • Shell 脚本实现系统监控与告警
  • 【算法--链表】86.分割链表--通俗讲解
  • 基于区块链的IoMT跨医院认证系统:Python实践分析
  • 用内存顺序实现 三种内存顺序模型
  • rh134第五章复习总结
  • Java包装类型
  • Linux awk 命令使用说明