新手小白的pytorch学习第六弹----pytorch基本工作流之保存和加载模型参数方法以及五、六弹的练习

在开始跟着写代码或者看文章之前,我需要说的是,这篇文章的代码是跟着新手小白的pytorch学习第五弹-----pytorch的工作流来的,是连续的,接着的,不然一定会报错的。
或者从 3 部分开始看,因为那是一个完整的过程,不错,这个文章的独立性还是在的。yes!

1 保存和加载模型

我们主要是保存和加载模型的参数

有三种方法:

  1. torch.save()
  2. torch.load()
  3. torch.nn.Module.load_state_dict()

让我们来看看实现目标的步骤:

  1. 我们创建一个名为models的目录,使用pathlib模块
  2. 接着创建一个文件路径来保存模型
  3. 调用torch.save(obj,f) obj就是state_dict, f是我们保存模型的文件名
    对于pytorch来说,保存模型的文件是以.p或者.pth结尾
# 首先创建模型保存的路径
from pathlib import Path

# 1 创建模型目录
MODEL_PATH = Path("models")
MODEL_PATH.mkdir(parents=True, exist_ok=True)

# 2 创建模型保存路径
MODEL_NAME = "01_pytorch_workflow_model_0.pth"
MODEL_SAVE_PATH = MODEL_PATH / MODEL_NAME

# 3 保存模型的 state_dict
print(f"Saving model to:{MODEL_SAVE_PATH}")
torch.save(obj=model_0.state_dict(), f=MODEL_SAVE_PATH)

Saving model to:models\01_pytorch_workflow_model_0.pth

2 加载一个保存的模型的 state_dict()

使用 torch.nn.Module.load_state_dict()

我们为什么不直接调用 torch.nn.Module.load_state_dict() 里面的 torch.load(),因为我们只保存了模型的 state_dict() 而不是整个模型,所以我们首先使用 torch.load() 加上 state_dict(), 然后把 state_dict() 传给我们模型的新的实例(nn.Module的子类)

# 实例化一个新的模型
loaded_model_0 = LinearRegressionModel()

# 加载我们保存的模型的 state_dict()
loaded_model_0.load_state_dict(torch.load(MODEL_SAVE_PATH))

< All keys matched successfully>

哇塞,恭喜我们成功啦~

那让我们开始测试一下吧

# 1 将模型放到评估模式下
loaded_model_0.eval()

# 2 使用 inference_mode 上下文管理器来进行预测
with torch.inference_mode():
    loaded_model_0_pred = loaded_model_0(X_test)
    
plot_predictions(predictions=loaded_model_0_pred)

在这里插入图片描述

# 1 将模型放到评估模式下
model_0.eval()

# 2 使用 inference_mode 上下文管理器来进行预测
with torch.inference_mode():
    model_0_preds = model_0(X_test)
    
print(f"model_0:{model_0.state_dict()}")
print(f"loaded_model_0:{loaded_model_0.state_dict()}")
print(model_0_preds == loaded_model_0_pred)

model_0:OrderedDict([(‘weights’, tensor([0.5784])), (‘bias’, tensor([0.3513]))])
loaded_model_0:OrderedDict([(‘weights’, tensor([0.5784])), (‘bias’, tensor([0.3513]))])
tensor([[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True]])

看看,是一样的吧,哎,这里证明了什么,证明我们的模型加载和保存成功。

3 将我们之前所学习的内容都放到一起

这里基本就是把我们之前学习的东西都整合一下,然后放到一起,代码居多,看过新手小白的pytorch学习第五弹-----pytorch的工作流的应该是非常之明白的哈。

# 导入我们所需要的包
import torch
import matplotlib.pyplot as plt

torch.__version__

‘2.3.1+cu118’

话说,这一段内容我经常忘记。。。。。。

# 创建与设备无关的代码
device = "cuda" if torch.cuda.is_available() else "cpu"
device

‘cuda’

# 数据
weights = 0.7
bias = 0.3

start = 0
end = 1
step = 0.02

X = torch.arange(start, end, step).unsqueeze(dim=1)
y = weights * X + bias

# 将数据分为训练集和测试集
train_split = int(0.8 * len(X))
X_train, y_train = X[:train_split], y[:train_split]
X_test, y_test = X[train_split:], y[train_split:]

# 查看一下训练集和测试集的长度,一般训练集占80%, 测试集占20%
len(X_train), len(y_train), len(X_test), len(y_test)

(40, 40, 10, 10)

# 咱们来可视化一下我们的数据
def plot_predictionsV2(train_data = X_train,
                       train_labels = y_train,
                       test_data = X_test,
                       test_labels = y_test,
                       predictions = None):
    '''
    绘制训练数据、测试数据和预测数据的散点图
    '''
    
    plt.figure(figsize=(10, 7))
    # 绘制训练数据的散点图, 蓝色
    plt.scatter(train_data, train_labels, c="b", s=4, label="Training data")
    
    # 绘制测试数据的散点图, 绿色
    plt.scatter(test_data, test_labels, c="g", s=4, label="Testing data")
    
    plt.legend()
    
    if predictions is not None:
        # 绘制预测数据的散点图, 红色
        plt.scatter(test_data, predictions, c="r", s=4, label="Predictions data")
    
plot_predictionsV2()

在这里插入图片描述

import torch.nn as nn
# 定义模型
class LinearRegressionModelV2(nn.Module):
    def __init__(self):
        super().__init__()
        
        # 这里的代码与之前不同的是,我们使用 pytorch 自带的线性模型,不再像之前一样自定义参数啦
        self.linear = nn.Linear(in_features=1,out_features=1)
        
    def forward(self, x):
        return self.linear(x)
    
# 实例化模型
torch.manual_seed(42)
model_1 = LinearRegressionModelV2()
model_1.state_dict()

OrderedDict([(‘linear.weight’, tensor([[0.7645]])),
(‘linear.bias’, tensor([0.8300]))])

import torch.optim as optim
# 损失函数和优化器
loss_fn = nn.L1Loss()
optimizer = optim.SGD(params=model_1.parameters(), lr=0.01)
# 训练
# 设置一些容器存放我们需要的信息
epoch_counts = []
test_loss_values = []
train_loss_values = []

epochs = 150
for epoch in range(epochs):
    # 进入训练模式
    model_1.train()
    model_1_train_pred = model_1(X_train)
    model_1_train_loss = loss_fn(model_1_train_pred, y_train)
    optimizer.zero_grad()
    model_1_train_loss.backward()
    optimizer.step()
    
    # 进入评估模式
    model_1.eval()
    with torch.inference_mode():
        model_1_test_pred = model_1(X_test)
        model_1_test_loss = loss_fn(model_1_test_pred, y_test)
        
    if epoch % 10 == 0:
        epoch_counts.append(epoch)
        train_loss_values.append(model_1_train_loss)
        test_loss_values.append(model_1_test_loss)
        
        print(f"Epoch:{epoch} | train loss:{model_1_train_loss} | test loss:{model_1_test_loss}")

Epoch:0 | train loss:0.5321359634399414 | test loss:0.5470342040061951
Epoch:10 | train loss:0.41692614555358887 | test loss:0.41232436895370483
Epoch:20 | train loss:0.3017162084579468 | test loss:0.2776145935058594
Epoch:30 | train loss:0.18650636076927185 | test loss:0.14290480315685272
Epoch:40 | train loss:0.07129647582769394 | test loss:0.008412850089371204
Epoch:50 | train loss:0.022868335247039795 | test loss:0.04911516234278679
Epoch:60 | train loss:0.019271593540906906 | test loss:0.04428599402308464
Epoch:70 | train loss:0.01583278924226761 | test loss:0.03601343557238579
Epoch:80 | train loss:0.01240016520023346 | test loss:0.02842777408659458
Epoch:90 | train loss:0.008967976085841656 | test loss:0.02015523985028267
Epoch:100 | train loss:0.0055291736498475075 | test loss:0.011882692575454712
Epoch:110 | train loss:0.0020982332061976194 | test loss:0.004297024104744196
Epoch:120 | train loss:0.0012645035749301314 | test loss:0.013801807537674904
Epoch:130 | train loss:0.0012645035749301314 | test loss:0.013801807537674904
Epoch:140 | train loss:0.0012645035749301314 | test loss:0.013801807537674904

# 进入评估模式
model_1.eval()
with torch.inference_mode():
    model_1_test_pred = model_1(X_test)
    model_1_test_loss = loss_fn(model_1_test_pred, y_test)
    
plot_predictionsV2(predictions=model_1_test_pred)

在这里插入图片描述

print(model_1.state_dict())
print(f"weights={weights}, bias={bias}")

OrderedDict([(‘linear.weight’, tensor([[0.6968]])), (‘linear.bias’, tensor([0.3025]))])
weights=0.7, bias=0.3

哇塞,绿色的点和红色的点重合了,可以看出性能还不错昂
开心啊,有结果就是让人感到开心呢

保存和加载模型参数
1 首先创建模型所在的目录
2 创建模型参数所在的文件路径
3 保存模型参数

# 导入我们所需要的包
from pathlib import Path

# 1 创建模型所在的目录
MODE_PATH = Path("models")
MODEL_PATH.mkdir(parents=True, exist_ok=True)

# 2 创建模型参数所在的文件路径
MODEL_NAME = Path("01_pytorch_workflow_model_1.pth")
MODEL_SAVE_PATH = MODE_PATH / MODEL_NAME
 
# 3 保存模型参数
print(MODEL_SAVE_PATH)
torch.save(obj=model_1.state_dict(), f=MODEL_SAVE_PATH)

models\01_pytorch_workflow_model_1.pth
可以看到models目录下面多了个pth文件喔

# 加载模型参数
loaded_model_1 = LinearRegressionModelV2()
loaded_model_1.load_state_dict(torch.load(f=MODEL_SAVE_PATH))

< All keys matched successfully>

# 看看我们是否加载成功
print(f"loaded_model_1:{loaded_model_1.state_dict()}")
print(f"model_1:{model_1.state_dict()}")

with torch.inference_mode():
    loaded_model_1_pred = loaded_model_1(X_test)
print(model_1_test_pred == loaded_model_1_pred)

loaded_model_1:OrderedDict([(‘linear.weight’, tensor([[0.6968]])), (‘linear.bias’, tensor([0.3025]))])
model_1:OrderedDict([(‘linear.weight’, tensor([[0.6968]])), (‘linear.bias’, tensor([0.3025]))])
tensor([[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True]])

ok, 我们保存和加载模型都成功啦!
恭喜恭喜,both of us!(注意这里上扬的语调~哈哈哈哈哈)

4 练习Exercise

老生常谈了,我们所需要的工具包是必须要导入的昂

# 导入我们所需要的包
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import torch.optim as optim

torch.__version__

‘2.3.1+cu118’

device = "cuda" if torch.cuda.is_available else "cpu"
device

‘cuda’

实话实说,我感觉我没有用上这个device,没事没事,我感觉之后的学习会用上,相信我。ok,马上要正式开始我们的习题了,准备好了吗? Let’s start!

  1. Create a straight line dataset using the linear regression formula (weight * X + bias).
  • Set weight=0.3 and bias=0.9 there should be at least 100 datapoints total.
  • Split the data into 80% training, 20% testing.
  • Plot the training and testing data so it becomes visual.
weight = 0.3
bias = 0.9

start = 0
end = 2
step = 0.01

X = torch.arange(start, end, step).unsqueeze(dim=1)
y = weight * X + bias

# 划分数据集为训练集和测试集
train_split = int(0.8 * len(X))
X_train, y_train = X[:train_split], y[:train_split]
X_test, y_test = X[train_split:], y[train_split:]

len(X_train), len(y_train), len(X_test), len(y_test)

(160, 160, 40, 40)

def plot_predictions(train_data = X_train,
                     train_labels = y_train,
                     test_data = X_test,
                     test_labels = y_test,
                     predictions = None):
    '''
    绘制测试数据、训练数据以及预测数据的散点图
    '''
    plt.figure(figsize=(20, 14))
    
    # 绘制训练数据,颜色是蓝色
    plt.scatter(train_data, train_labels, c="b", s=4, label="Training data")
    
    # 绘制测试数据,颜色是绿色
    plt.scatter(test_data, test_labels, c="g", s=4, label="Testing data")
    
    if predictions is not None:
        # 绘制预测数据,颜色是红色
        plt.scatter(test_data, predictions, c="r", s=4, label="Predictions data")

因为数据变多了,原来的尺寸就会很不好看,于是我把这里修改了 plt.figure(figsize=(20, 14))就好看多啦

plot_predictions()

在这里插入图片描述

  1. Build a PyTorch model by subclassing nn.Module.
  • Inside should be a randomly initialized nn.Parameter() with requires_grad=True, one for weights and one for bias.
  • Implement the forward() method to compute the linear regression function you used to create the dataset in 1.
  • Once you’ve constructed the model, make an instance of it and check its state_dict().
  • Note: If you’d like to use nn.Linear() instead of nn.Parameter() you can.
# 创建线性模型
class LinearRegressionModule(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(in_features=1, out_features=1)
        
    def forward(self, x):
        return self.linear(x)

# 创建一个模型实例
model = LinearRegressionModule()

# 打印出模型的参数
print(model.state_dict())

OrderedDict([(‘linear.weight’, tensor([[-0.2280]])), (‘linear.bias’, tensor([-0.0902]))])

  1. Create a loss function and optimizer using nn.L1Loss() and torch.optim.SGD(params, lr) respectively.
  • Set the learning rate of the optimizer to be 0.01 and the parameters to optimize should be the model parameters from the model you created in 2.
  • Write a training loop to perform the appropriate training steps for 300 epochs.
  • The training loop should test the model on the test dataset every 20 epochs.
# 创建损失函数
loss_fn = nn.L1Loss()

# 创建优化器
optimizer = optim.SGD(params=model.parameters(), lr=0.01)

# 训练循环
epochs = 300
for epoch in range(epochs):
    # 进入训练模式
    model.train()
    y_pred = model(X_train)
    loss = loss_fn(y_pred, y_train)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    
    if epoch % 20 == 0:
        # 进入评估模式
        model.eval()
        
        with torch.inference_mode():
            test_pred = model(X_test)
            test_loss = loss_fn(test_pred, y_test)
        
        print(f"Epoch:{epoch} | train loss:{loss} | test loss:{test_loss}")

Epoch:0 | train loss:1.4099230766296387 | test loss:1.9136593341827393
Epoch:20 | train loss:1.0835180282592773 | test loss:1.428254246711731
Epoch:40 | train loss:0.7571130990982056 | test loss:0.9428492784500122
Epoch:60 | train loss:0.4307084083557129 | test loss:0.4574446678161621
Epoch:80 | train loss:0.10430345684289932 | test loss:0.027960410341620445
Epoch:100 | train loss:0.04662444069981575 | test loss:0.09040948003530502
Epoch:120 | train loss:0.0285215824842453 | test loss:0.05508122593164444
Epoch:140 | train loss:0.010423463769257069 | test loss:0.019072124734520912
Epoch:160 | train loss:0.007052215747535229 | test loss:0.011607959866523743
Epoch:180 | train loss:0.007052215747535229 | test loss:0.011607959866523743
Epoch:200 | train loss:0.007052215747535229 | test loss:0.011607959866523743
Epoch:220 | train loss:0.007052215747535229 | test loss:0.011607959866523743
Epoch:240 | train loss:0.007052215747535229 | test loss:0.011607959866523743
Epoch:260 | train loss:0.007052215747535229 | test loss:0.011607959866523743
Epoch:280 | train loss:0.007052215747535229 | test loss:0.011607959866523743

  1. Make predictions with the trained model on the test data.
  • Visualize these predictions against the original training and testing data (note: you may need to make sure the predictions are not on the GPU if you want to use non-CUDA-enabled libraries such as matplotlib to plot).
# 进入评估模式
model.eval()

with torch.inference_mode():
    y_pred = model(X_test)
    
plot_predictions(predictions=y_pred)

在这里插入图片描述

  1. Save your trained model’s state_dict() to file.
  • Create a new instance of your model class you made in 2. and load in the state_dict() you just saved to it.
  • Perform predictions on your test data with the loaded model and confirm they match the original model predictions from 4.
# 保存模型参数,分为三步
# 1 创建模型所在的目录
from pathlib import Path
MODE_PATH = Path("models")
MODE_PATH.mkdir(parents=True, exist_ok=True)

# 2 创建模型参数文件
MODE_NAME = "01_pytorch_workflow_exercise_model.pth"
MODE_SAVE_PATH = MODE_PATH / MODE_NAME

# 3 保存模型参数
print(MODE_SAVE_PATH)
torch.save(obj=model.state_dict(), f=MODE_SAVE_PATH)

models\01_pytorch_workflow_exercise_model.pth

# 加载模型参数
# 1 实例化一个nn.Module的子类
loaded_model = LinearRegressionModule()

# 2 加载模型
loaded_model.load_state_dict(torch.load(f=MODE_SAVE_PATH))

< All keys matched successfully>

# 测试加载的模型
print(f"model:{model.state_dict()}")
print(f"loaded_model:{loaded_model.state_dict()}")

model:OrderedDict([(‘linear.weight’, tensor([[0.3056]])), (‘linear.bias’, tensor([0.9026]))])
loaded_model:OrderedDict([(‘linear.weight’, tensor([[0.3056]])), (‘linear.bias’, tensor([0.9026]))])

可以看出这里的值是一样的昂

# 用我们加载的模型参数来测试一下具体的数据看看
loaded_model.eval()
with torch.inference_mode():
    loaded_model_pred = loaded_model(X_test)
    
model.eval()
with torch.inference_mode():
    model_pred = loaded_model(X_test)

print(model_pred == loaded_model_pred)

tensor([[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],
[True],

[True],
[True],
[True],
[True]])
Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings…

ok, 到这里我们就把练习题做完啦,对我们的知识点得到了很大的改进,棒棒哒~

重庆鸡公煲尊嘟很好吃,下次还要吃呢!下次文档要搞个目录,感觉方便一点。

如果我的文档让您感觉:oh, 还不错呢!

记得给我一个赞赞,赞赞

靴靴,谢谢~

  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值