PyTorch编程基础03--用PyTorch实现一个简单模型

1.准备可复现的随机数据

可复现是指:一个程序在相同设备上多次运行,可以得到相同的结果。在调试程序过程中,常使用这种方式来复现问题,方便地找出上一次运行时所出现的问题。
具体做法是,在程序开始时固定torch的随机数种子,并固定numpy的随机数种子。

import torch
import numpy as np
torch.manual_seed(0)
torch.cuda.manual_seed_all(0)
torch.backends.cudnn.deterministic=True
torch.backends.cudnn.benchmark=False
np.random.seed(0)

这部分代码必须放在程序的最开始位置。这样才可以保证每次生成的随机模拟数据,以及模型的初始权重相同。
在sklearn库的datasets模块中,通过调用make_moons()函数可以生成两组半圆形数据。

import sklearn.datasets
import matplotlib.pyplot as plt
X, Y = sklearn.datasets.make_moons(200, noise=0.2)
data1 = []
data2 = []
for i in range(200):
    if Y[i] == 0:
        data1.append(X[i])
    else:
        data2.append(X[i])
X1, X2, Y1, Y2 = [], [], [], []
for i in data1:
    X1.append(i[0])
    Y1.append(i[1])
for j in data2:
    X2.append(j[0])
    Y2.append(j[1])

plt.scatter(X1, Y1, c='b', marker='+', label="data1")
plt.scatter(X2, Y2, c='r', marker='.', label="data2")
plt.legend()
plt.show()

在这里插入图片描述


2.实现并训练模型

2.1定义模型

import torch.nn as nn
class LogicNet(nn.Module):  # 继承nn.Module类,构建模型
    def __init__(self, inputdim, hiddendim, outputdim):  # 初始化网络结构
        super(LogicNet, self).__init__()
        self.Linear1 = nn.Linear(inputdim, hiddendim)  # 定义全连接层
        self.Linear2 = nn.Linear(hiddendim, outputdim)  # 定义全连接层
        self.criterion = nn.CrossEntropyLoss()  # 定义交叉熵函数

    def forward(self, x):  # 搭建用两层全连接组成的模型
        x = self.Linear1(x)  # 将输入数据传入第一层
        x = torch.tanh(x)  # 对第一层的结果进行非线性变换
        x = self.Linear2(x)  # 将网络数据传入第二层
        return x

    def predict(self, x):  # 实现LogicNet类的预测接口
        # 调用自身模型,并对结果进行softmax处理,分别得出预测数据属于哪一类的概率
        pred = torch.softmax(self.forward(x), dim=1)
        return torch.argmax(pred, dim=1)  # 返回每组预测概率中最大的索引
    
    def getloss(self, x, y):  # 实现LogicNet类的损失值计算接口
        y_pred = self.forward(x)
        loss = self.criterion(y_pred, y)  # 计算损失值的交叉熵
        return loss

2.2搭建并训练模型

只需要将定义好的模型类LogicNet实例化,即可完成模型的真正搭建。待模型搭建完成后,还需要定义训练模型所需的优化器,优化器会在训练模型时的反向传播过程中使用。

model = LogicNet(inputdim=2, hiddendim=3, outputdim=2)  # 实例化模型
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)  # 定义优化器
xt = torch.from_numpy(X).type(torch.FloatTensor)  # 将numpy数据转换为张量
yt = torch.from_numpy(Y).type(torch.LongTensor)
epochs = 1000  # 定义迭代次数
losses = []  # 定义列表,用于接收每一步的损失值
for i in range(epochs):
    loss = model.getloss(xt, yt)
    losses.append(loss.item())  # 保存中间状态的损失值
    optimizer.zero_grad()  # 清空之前的梯度
    loss.backward()  # 反向传播损失值
    optimizer.step()  # 更新参数
  • inputdim:输入数据的维度。因为本实例中输入的数据是一个具有x和y两个坐标值的数据,所以维度是2。
  • hiddendim:隐藏层的节点个数。这个值可以随意定义,节点个数越大,则网络的拟合效果越好。但太大的节点个数会为网络带来训练困难、泛化性差的问题。
  • outputdim:模型输出的维度,这个参数具有一定的规律。在分类模型中,模型的最终结果是几类,该参数就设成几。
plt.plot(range(1000), losses, '-')
plt.xlabel('step number')
plt.ylabel('Loss')
plt.title('step number vs. Training loss')
plt.show()

在这里插入图片描述


2.3评估及使用模型

import sklearn.metrics as metrics
print(metrics.accuracy_score(model.predict(xt), yt))  # 输出0.975

注意:在实际运行时,神经网络节点的初始值时随机的。而在训练过程中,它是基于网络节点中的原始值进行调节的。所以,每次训练完的模型在进行评估时都会得到不同的分数。但是总体的评估值会在一个范围内浮动,不会有太大的差异。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值