重拾pytorch,练手(二)——三组坐标点的非线性分类

本文介绍了如何在PyTorch中构建一个简单的神经网络模型,解决数据类型不匹配问题,并演示了如何处理和可视化数据,以及训练过程和决策边界绘制。
摘要由CSDN通过智能技术生成

代码参考bilibili UP主——小黑黑讲AI

【bilibili】基于pytorch实现一个神经网络,训练非线性的分类模型

本人并不是这位UP。

前言部分记录下总是容易出错的地方

  1. 总是提示说mat1和mat2的数据类型不符,这个太坑了,numpy的float是float64,要换成torch的float32,或者直接torch.float类型就行了;
  2. 有关tensor,确实乱七八糟的,一定要自己看看是不是想要的shape
  3. 变量命名方式,可以参考torch官网来,保证自己代码的风格一致,比如X是feature,y是label啥的,pred是测试的结果。
# 制造数据
import numpy as np
import matplotlib.pyplot as plt
def make_data(num, seed=10):
    np.random.seed(seed)
    r_rand = np.random.standard_normal(num)*0.3
    t_rand = np.random.random(num)*np.pi*2
    center = np.array([[0,0]]*num)+np.array([r_rand*np.cos(t_rand),r_rand*np.sin(t_rand)]).T
    plt.scatter(center[:,0],center[:,1], c='r')

    r_rand = np.random.standard_normal(num)*0.3+2
    t_rand = np.random.random(num)*np.pi*2
    center1 = np.array([[0,0]]*num)+np.array([r_rand*np.cos(t_rand),r_rand*np.sin(t_rand)]).T
    plt.scatter(center1[:,0],center1[:,1], c='g')

    r_rand = np.random.standard_normal(num)*0.5
    t_rand = np.random.random(num)*np.pi*2
    c = 2.5
    op =[[c,c],[c,-c],[-c,c],[-c,-c]]*num
    np.random.shuffle(op)
    corner = np.array(op[:num])+np.array([r_rand*np.cos(t_rand),r_rand*np.sin(t_rand)]).T
    plt.scatter(corner[:,0],corner[:,1], c='b')

    return center, center1, corner
make_data(100,seed=100)
plt.show()

简单的获得需要分类的数据点

import torch
import torch.nn as nn
device_label = 'dml' # 这里如果是dml,则需要安装directml库,对amd老显卡使用
if torch.cuda.is_available():
    device = 'cuda'
elif device_label == 'dml':
    import torch_directml
    device = torch_directml.device()
else:
    device = 'cpu'
class Network(nn.Module):
    def __init__(self):
        super().__init__()
        # self.flatten = nn.Flatten()
        
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(2, 10),
            nn.ReLU(),
            nn.Linear(10, 3),
            nn.ReLU(),
            nn.Linear(3, 3),
        )

    def forward(self, x):
        # x = self.flatten(x)
        x = self.linear_relu_stack(x)
        return x
# 数据处理,以及导入模型
in_dim = 2
hid_dim = 10
out_dim = 3

learning_rate = 1e-3
batch_size = 10
epochs = 1000

def dataset():
    c1, c2, c3 = make_data(100)
    plt.show()

    c1 = torch.tensor(c1,dtype=torch.float).to(device)
    c2 = torch.tensor(c2,dtype=torch.float).to(device)
    c3 = torch.tensor(c3,dtype=torch.float).to(device)

    X = torch.cat((c1, c2, c3), 0).to(device)
    y = torch.tensor([0] * len(c1) + [1] * len(c2) + [2] * len(c3)).to(device)
    
    return X, y

model = Network().to(device)
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

def train(model, X, y, epochs, loss_fn, optimizer):
    model.train()
    for epoch in range(epochs):
        pred = model(X)
        loss = loss_fn(pred, y)

        loss.backward()
        optimizer.step()
        optimizer.zero_grad()

        if (epoch+1) % 100 == 0:
            loss, current = loss.item(), (epoch+1) * len(X)
            print(f"loss: {loss:>7f}  epochs: {current:>5d}")
# 开始迭代训练
X, y = dataset()
train(model, X, y, epochs, loss_fn, optimizer)
    

再次确认获取训练数据

import tqdm
# 绘制等高图
def draw_decision_boundary(model, xlim ,ylim):
    # 生成网格数据点
    xx, yy = np.meshgrid(np.linspace(xlim[0], xlim[1], 100),
                         np.linspace(ylim[0], ylim[1], 100))
    x_pred = xx.ravel()
    y_pred = yy.ravel()
    z = list()
    bar = tqdm.tqdm(zip(x_pred,y_pred))
    i =0
    for X in bar:
        X = torch.FloatTensor([X]).to(device)
        with torch.no_grad():
            pred = model(X).max(1)[1].item()
            z.append(pred)
        i+=1
        bar.desc = f'{i} / {len(x_pred)}'
    z = np.array(z).reshape(xx.shape)
    return xx, yy, z
x,y,z = draw_decision_boundary(model, [-4, 4],[-4, 4])
plt.contourf(x, y, z)
make_data(100)
plt.show()

10000 / 10000: 10000it [00:10, 927.89it/s]

直接画等高图方便好看

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值