pytorch学习笔记(三)

pytorch学习笔记(三)

一、模型保存

用pathlib库中的方法来保存模型参数

1)保存模型参数
from pathlib import Path

MODEL_PATH = Path("models") #Path更好表示路径
# parents表示当前路径是否存在多级嵌套,exist_ok表示当前文件夹存在也不影响
MODEL_PATH.mkdir(parents = True, exist_ok = True)
MODEL_NAME = "02_pytorch_workflow_model_0.pth" # pth文件用于保存模型参数
MODEL_SAVE_PATH = MODEL_PATH / MODEL_NAME  # 总路径,合并
#PosixPath('models/02_pytorch_workflow_model_0.pth')

# 将模型参数保存到此路径
# obj:我要保存的模型参数,f:保存到的路径
torch.save(obj = model_0.state_dict(), f = MODEL_SAVE_PATH)
2)调用已保存的模型
loaded_model_0 = LinearRegressionModel() # 建立一个线性回归模型,并初始化参数
# 加载训练好的参数到loaded_model_0
# load_state_dict( )里面的参数不要直接写路径,用torch.load()转一下
loaded_model_0.load_state_dict(torch.load(f = MODEL_SAVE_PATH))

二、分类任务的处理(从头到尾处理整个分类任务)

from sklearn.datasets import make_circles
n_samples = 1000
# noise模拟自然界真实的扰动,random_state指定随机种子,确保每次运行代码时生成的数据集相同
X,y = make_circles(n_samples, noise = 0.03, random_state = 666)

#可以把数据映射成pandas的表格的形式更好看
import pandas as pd
circles = pd.DataFrame({"X1":X[:0], "X2":X[:1], "label":y})
circels.head(10) # 显示表中前10行数据

在这里插入图片描述

circles.label.value_counts() # 统计每个类中有多少个
# 将样本点可视化看一下
import matplotlib.pyplot as plt
# plt.cm.RdYlBu做一个色彩映射,更好看
# c = y 根据y的值映射到预定义色彩空间RdYlBu上
plt.scatter(x=X[:,0], y = X[:,1], c = y, cmap = plt.cm.RdYlBu) 

在这里插入图片描述

import torch

X = torch.from_numpy(X).type(torch.float)
y = torch.from_numpy(y).type(torch.float)

# 把一个numpy转成tensor时候一定要加.type(torch.float)  由于他们两个float默认精度不一样

划分数据集

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 666)

建立分类模型

import torch
from torch import nn
device = "cuda" if torch.cuda.is_available() else "cpu"
# 上述是通用的

class CircleModelV0(nn.module):
	def __init__(self):
		super().__init()
		# self
		self.layer_1 = nn.Linear(in_features = 2, out_features = 5)
		self.layer_2 = nn.Linear(in_features = 5 out_features = 1)
		self.relu = nn.ReLU()
	def forward(self, x):
		return self.layer_2(self.relu(self.layer_1(x)))
	
model_0 = CircleModelV0().to(device)	
# 二分类交叉熵损失BCE
torch.nn.BCELoss()
torch.nn.BCEWithLogitsLoss()
#logits回归,把原始值经过logits函数压缩到0,1这个区间
loss_fn = torch.nn.BCEWithLogitsLoss()

optimizer = torch.optim.SGD(params = model_0.parameters(), lr = 0.1)

# sigmoid 1 / (1 + e^-x)
y_logits = model_0(X_test.to(device))
y_pred_prob = torch.sigmoid(y_logits) # 把元素数据压缩到0,1范围内
y_pred_labels = torch.round(y_pred_prob) # 把大于0.5记作1,小于0.5记为0
y_pred_labels = y_pred_labels.squeeze() # 从[200,1]压缩到[200]‘
# 统计准确率
def accuracy_fn(y_true, y_pred):
  correct = torch.sum(y_true == y_pred).item()

  acc = (correct / len(y_true)) * 100

  return acc

# 训练模型
torch.manual_seed(666)
epochs = 200
X_train, y_train = X_train.to(device), y_train.to(device)
X_test, y_test = X_test.to(device), y_test.to(device)
for epoch in range(epochs):
  model_0.train() # 先把模型调到训练模式
  y_logits = model_0(X_train).squeeze() 
  y_pred = torch.round(torch.sigmoid(y_logits)) # 预测结果用0、1表示
  # 计算损失函数用y_logits而不用y_pred,因为定义的损失函数loss_fn是BCEWithLogitsLoss带logits
  loss = loss_fn(y_logits, y_train)
  
  acc = accuracy_fn(y_train, y_pred)
  # 每次反向传播之前要删除上一次的梯度
  # 第一次反向传播后,梯度为grad1。第二次反向传播后,梯度会变为grad1+grad2,而不是我们期望的 grad2
  optimizer.zero_grad()

  loss.backward()

  optimizer.step()
  # 评估模式
  model_0.eval()
  with torch.inference_mode():
    test_logits = model_0(X_test).squeeze()
    test_pred = torch.round(torch.sigmoid(test_logits))

    test_loss = loss_fn(test_logits, y_test)
    test_acc = accuracy_fn(y_test, test_pred)

  print(f"{epoch} | Loss:{loss} | acc:{acc} | Test Loss:{test_loss} | Test Acc:{test_acc}")

三、流程总结

1. 从某个数据集中拿数据,最原始不经过处理的数据(这里用的是sklearn的circle数据集)
2. 看看数据什么样,用各种可视化的方法
3. 将最原始的数据转成tensor
4. 选取合适的模型并构建模型
5. 数据集划分(训练集和测试集)
6.开始训练:每个epoch得到预测值和实际值的差,计算loss,梯度下降,回传(每个模型都是一样的)
7.测试:打印Acc和loss
8.找个地方把模型存下来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值