首页 > 编程知识 正文

pytorch实现像分类网络,pytorch定义神经网络

时间:2023-05-04 08:20:41 阅读:189138 作者:1619

这一节,用pytorch实现神经网络分类问题,再次熟悉pytorch搭建神经网络的步骤。

1. 问题的提出

分类问题是将数据划分种类的一种问题,常见的有二分类和多分类问题,这节就是做一个简单的二分类问题。

同样,我们先做一组数据。其中第一组数据的标签为0,第二组数据标签为1。

# x0,x1是数据,y0,y1是标签n_data = torch.ones(100, 2) # 数据的基本形态x0 = torch.normal(2*n_data, 1) # 类型0 x data (tensor), shape=(100, 2)y0 = torch.zeros(100) # 类型0 y data (tensor), shape=(100, )x1 = torch.normal(-2*n_data, 1) # 类型1 x data (tensor), shape=(100, 1)y1 = torch.ones(100) # 类型1 y data (tensor), shape=(100, )

将两组数据进行融合,并用散点图表示出来,明显地看到可以将数据分为2类,即红绿各代表一类。

2. 神经网络模型的搭建和训练

神经网络模型的搭建和上一节回归问题基本一样,也是先搭建网络框架,再创建模型、优化器、损失函数。

要注意的是,在这个分类问题中我们输入的数据x是2维的,输出的预测值也是2维的(几分类问题输出就是几维),因此各个网络层的神经单元数要改变。

input_dim = 2hidden_dim = 10out_dim = 2

还有一点不同之处在于损失函数选用的是交叉熵(CrossEntropy) ,这是在做回归问题时常用的损失函数,而分类问题中最后一层的激活函数常选用的是softmax

有关交叉熵这有一篇博客介绍的很清晰,可以看一下。

pytorch中将两者集成在了torch.nn.CrossEntropyLoss() 这个函数中了,我们直接调用就好。

loss_func = nn.CrossEntropyLoss() 3. 结果展示

同样,我们输出训练过程中的loss值图像,发现损失值是在不断减小的,也就意味着模型拟合的越来越好。

要注意的是,这时给出的prediction并不是最后的分类值,而是一个Tensor数据格式,如[0.3,0.7],表示神经网络预测的样本属于每类的概率,所以需要取这个概率的最大值来表示最后的分类。

prediction = torch.max(F.softmax(out), 1)[1]

最后的分类结果展示图:

4. 结语

代码参考了莫烦大神的教程,完整代码放在这里:

# 神经网络的搭建--分类任务 #import torchimport matplotlib.pyplot as pltimport torch.nn.functional as F # 激励函数都在这# x0,x1是数据,y0,y1是标签n_data = torch.ones(100, 2) # 数据的基本形态x0 = torch.normal(2*n_data, 1) # 类型0 x data (tensor), shape=(100, 2)y0 = torch.zeros(100) # 类型0 y data (tensor), shape=(100, )x1 = torch.normal(-2*n_data, 1) # 类型1 x data (tensor), shape=(100, 1)y1 = torch.ones(100) # 类型1 y data (tensor), shape=(100, )# 注意 x, y 数据的数据形式是一定要像下面一样 (torch.cat 是在合并数据)x = torch.cat((x0, x1), 0).type(torch.FloatTensor) # FloatTensor = 32-bit floatingy = torch.cat((y0, y1), ).type(torch.LongTensor) # LongTensor = 64-bit integerplt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:, 1], c=y.data.numpy(), s=100, lw=0, cmap='RdYlGn')plt.show()# 建立神经网络class Net(torch.nn.Module): # 继承 torch 的 Module def __init__(self, n_feature, n_hidden, n_output): super(Net, self).__init__() # 继承 __init__ 功能 self.hidden = torch.nn.Linear(n_feature, n_hidden) # 隐藏层线性输出 self.out = torch.nn.Linear(n_hidden, n_output) # 输出层线性输出 def forward(self, x): # 正向传播输入值, 神经网络分析出输出值 x = F.relu(self.hidden(x)) # 激励函数(隐藏层的线性值) x = self.out(x) # 输出值, 但是这个不是预测值, 预测值还需要再另外计算 return xnet = Net(n_feature=2, n_hidden=10, n_output=2) # 几个类别就几个 output# 训练网络optimizer = torch.optim.SGD(net.parameters(), lr=0.02) # 算误差的时候, 注意真实值!不是! one-hot 形式的, 而是1D Tensor, (batch,)# 但是预测值是2D tensor (batch, n_classes)loss_func = torch.nn.CrossEntropyLoss()plt.ion() # 画图plt.show()for t in range(100): out = net(x) # 喂给 net 训练数据 x, 输出分析值 loss = loss_func(out, y) # 计算两者的误差 optimizer.zero_grad() loss.backward() optimizer.step() # 可视化展示 if t % 2 == 0: plt.cla() # 过了一道 softmax 的激励函数后的最大概率才是预测值 prediction = torch.max(F.softmax(out), 1)[1] pred_y = prediction.data.numpy().squeeze() target_y = y.data.numpy() plt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:, 1], c=pred_y, s=100, lw=0, cmap='RdYlGn') accuracy = sum(pred_y == target_y) / 200. # 计算准确度 plt.text(1.5, -4, 'Accuracy=%.2f' % accuracy, fontdict={'size': 20, 'color': 'red'}) plt.pause(0.1)plt.ioff() # 停止画图plt.show() 补充:激励函数和损失函数的选择

在神经网络中针对不同问题会用到不同的激励函数和损失函数,比如上节回归问题用到的就是relu激活函数和mse损失函数,而这节分类问题我们最后一层用到的就是softmax激活函数和crossentropy损失函数。

针对最后一层激活函数的选择和损失函数的选择,有一个图可以参考,来自这篇博客。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。