Pytorch搭建神经网络完成监督学习-分类任务

该博客介绍了如何创建训练集并使用PyTorch训练一个神经网络模型进行四分类任务。首先,通过随机种子设定一致的随机数生成,然后在[-10,10]区间生成1000个点,结合两个非线性函数将点分为四个区域。接着,定义了一个具有隐藏层的神经网络,使用交叉熵损失函数和Adam优化器进行训练。经过1500次迭代后,使用新的测试集验证模型,并计算了准确性。最后,展示了训练结果和预测的准确性。
摘要由CSDN通过智能技术生成

classifica

一、创建训练集

为了保证后续过程中产生的随机数都是一致的(方便测试),我们首先种下一颗随机种子。

import torch
import matplotlib.pyplot as plt
import torch.nn.functional as F
import numpy as np

def setup_seed(seed):
    torch.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)

setup_seed(50)

在[-10, 10]区间上随机生成1000个离散点,并将其可视化。

#create trainning set
batch_n = 1000
x = torch.linspace(-10, 10, batch_n).reshape(batch_n, 1)
y = torch.randn(batch_n, 1)

plt.figure()
plt.scatter(x.data.numpy(), y.data.numpy())
plt.show()

trainning set

创造两个非线性函数,这里用y=0.5cos(x)+0.4sin(2x)+0.3sin(3x)和y=0.002*x^3+0.02*x^2吧。将其可视化在图像上。

def Myfunc(x):
    y = 0.5*np.cos(x) + 0.4*np.sin(2*x) + 0.3*np.sin(3*x)
    return y

def Myfunc2(x):
    y = 0.002*np.power(x, 3) + 0.01*np.power(x-3, 2)
    return y

plt.figure()
plt.scatter(x.data.numpy(), y.data.numpy())
plt.plot(x.data.numpy(), Myfunc(x.data.numpy()), 'g-')
plt.plot(x.data.numpy(), Myfunc2(x.data.numpy()), 'g-')
plt.show()

split-line

我想做什么?我想利用这两个非线性函数,将平面分成四个区域。如果一个点同时位于两条直线之上,我们认为他处于区域[0];同时位于两条直线之下,处于区域[1];还有一上一下的情形……。

我们将(x, y)合并为训练集trainning set,然后为这些点贴上相应区域的标签。那么平面上这1000个离散点就被分为了四类。

train_set = torch.tensor(torch.cat((x, y), 1), dtype=torch.float32)
label = torch.tensor(torch.zeros(batch_n), dtype=torch.int64)

for i in range(batch_n):
    _y = Myfunc(x[i].data) - y[i].data
    __y = Myfunc2(x[i].data) - y[i].data
    if _y > 0 and __y > 0:
        label[i] = 0
    elif _y > 0 and __y <= 0:
        label[i] = 1
    elif _y <= 0 and __y > 0:
        label[i] = 2
    else:
        label[i] = 3

plt.figure()
plt.title('Training Set:%d Samples' % batch_n)
plt.plot(x.data.numpy(), Myfunc(x.data.numpy()), 'b-', label='split-line')
plt.plot(x.data.numpy(), Myfunc2(x.data.numpy()), 'b-')
colors = label.data.numpy()
plt.scatter(train_set.data.numpy()[:, 0], train_set.data.numpy()[:, 1], c=label.data.numpy(), s=20, lw=0, cmap='RdYlGn')
plt.legend()
plt.show()

trainning set

到此,训练集创建完毕。

二、搭建神经网络

输入给神经网络的是一个“点”,有(x, y)两个参数,所以神经网络输入层维度是2;神经网络要将这个些点分为四类,输出层维度是4;隐藏层我们使用30个神经元,选用sigmoid激活函数。

使用CrossEntropyLoss(交叉熵)损失函数,Adam优化器,初始化学习率0.3

class Net(torch.nn.Module):
    def __init__(self, in_dim, hidden_dim, out_dim):
        super(Net, self).__init__()
        self.hidden = torch.nn.Linear(in_dim, hidden_dim)
        self.predict = torch.nn.Linear(hidden_dim, out_dim)

    def forward(self, x):
        x = self.hidden(x)
        x = F.sigmoid(x)
        x = self.predict(x)
        return x

net = Net(2, 30, 4)
loss_func = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters(), lr=0.3)

三、训练神经网络

用for循环做1500次迭代训练。

for i in range(1500):
    pre_y = net(train_set)
    loss = loss_func(pre_y, label)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    print("loss:{}".format(loss))

四、创建测试集验证模型

我们已经用训练集对神经网络完成了训练。接下来我们创建一个含有2000个样本的测试集来验证我们的训练成果。

重新种下一颗随机数种子,确保创建的测试集是新的。

#create test set
batch_n = 2000
setup_seed(100)
x = torch.linspace(-10, 10, batch_n).reshape(batch_n, 1)
y = torch.randn(batch_n, 1)

test_set = torch.tensor(torch.cat((x, y), 1), dtype=torch.float32)
label = torch.tensor(torch.zeros(batch_n), dtype=torch.int64) #初始化

for i in range(batch_n):
    _y = Myfunc(x[i].data) - y[i].data
    __y = Myfunc2(x[i].data) - y[i].data
    if _y > 0 and __y > 0:
        label[i] = 0
    elif _y > 0 and __y <= 0:
        label[i] = 1
    elif _y <= 0 and __y > 0:
        label[i] = 2
    else:
        label[i] = 3

放进神经网络前向传播,并得到预测的标签。

pre_y = net(test_set)
pre_label = torch.max(pre_y, 1)[1]

计算准确率

#calculate accuracy
cnt = 0
for i in range(batch_n):
    if pre_label[i] == label[i]:
        cnt = cnt + 1
accuracy = float(cnt)/float(batch_n)*100

可视化训练成果。

五、总代码及训练成果

import torch
import matplotlib.pyplot as plt
import torch.nn.functional as F
import numpy as np

#random seed
def setup_seed(seed):
    torch.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)

setup_seed(50)

#create trainning set
batch_n = 1000
x = torch.linspace(-10, 10, batch_n).reshape(batch_n, 1)
y = torch.randn(batch_n, 1)

def Myfunc(x):
    y = 0.5*np.cos(x) + 0.4*np.sin(2*x) + 0.3*np.sin(3*x)
    return y

def Myfunc2(x):
    y = 0.002*np.power(x, 3) + 0.01*np.power(x-3, 2)
    return y

train_set = torch.tensor(torch.cat((x, y), 1), dtype=torch.float32)
label = torch.tensor(torch.zeros(batch_n), dtype=torch.int64)

for i in range(batch_n):
    _y = Myfunc(x[i].data) - y[i].data
    __y = Myfunc2(x[i].data) - y[i].data
    if _y > 0 and __y > 0:
        label[i] = 0
    elif _y > 0 and __y <= 0:
        label[i] = 1
    elif _y <= 0 and __y > 0:
        label[i] = 2
    else:
        label[i] = 3

plt.figure()
plt.subplot(1, 2, 1)
plt.title('Training Set:%d Samples' % batch_n)
plt.plot(x.data.numpy(), Myfunc(x.data.numpy()), 'b-', label='split-line')
plt.plot(x.data.numpy(), Myfunc2(x.data.numpy()), 'b-')
colors = label.data.numpy()
plt.scatter(train_set.data.numpy()[:, 0], train_set.data.numpy()[:, 1], c=label.data.numpy(), s=20, lw=0, cmap='RdYlGn')
plt.legend()

#network
class Net(torch.nn.Module):
    def __init__(self, in_dim, hidden_dim, out_dim):
        super(Net, self).__init__()
        self.hidden = torch.nn.Linear(in_dim, hidden_dim)
        self.predict = torch.nn.Linear(hidden_dim, out_dim)

    def forward(self, x):
        x = self.hidden(x)
        x = F.sigmoid(x)
        x = self.predict(x)
        return x

net = Net(2, 30, 4)
loss_func = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(net.parameters(), lr=0.3)

#trainning
for i in range(1500):
    pre_y = net(train_set)
    loss = loss_func(pre_y, label)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    print("loss:{}".format(loss))

#create test set
batch_n = 2000
setup_seed(100)
x = torch.linspace(-10, 10, batch_n).reshape(batch_n, 1)
y = torch.randn(batch_n, 1)

test_set = torch.tensor(torch.cat((x, y), 1), dtype=torch.float32)
label = torch.tensor(torch.zeros(batch_n), dtype=torch.int64)

for i in range(batch_n):
    _y = Myfunc(x[i].data) - y[i].data
    __y = Myfunc2(x[i].data) - y[i].data
    if _y > 0 and __y > 0:
        label[i] = 0
    elif _y > 0 and __y <= 0:
        label[i] = 1
    elif _y <= 0 and __y > 0:
        label[i] = 2
    else:
        label[i] = 3

#forward
pre_y = net(test_set)
pre_label = torch.max(pre_y, 1)[1]

#calculate accuracy
cnt = 0
for i in range(batch_n):
    if pre_label[i] == label[i]:
        cnt = cnt + 1
accuracy = float(cnt)/float(batch_n)*100

plt.subplot(1, 2, 2)
plt.title('Prediction:%d Samples' % batch_n)
plt.plot(x.data.numpy(), Myfunc(x.data.numpy()), 'b--', label='split-line')
plt.plot(x.data.numpy(), Myfunc2(x.data.numpy()), 'b--')
plt.scatter(test_set.data.numpy()[:, 0], test_set.data.numpy()[:, 1], c=pre_label.data.numpy(), s=20, lw=0, cmap='RdYlGn')
plt.legend()


plt.text(6.5, -3.3, 'Accuracy=%.2f %%' % accuracy, fontdict={'size': 10, 'color':  'red'})
plt.text(-10, -3.3, 'Supervised Learning - Classification', fontdict={'size': 12, 'color':  'black'})
plt.show()

classifica

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值