用PyTorch实现一个简单的分类器

作者: 佚名 2020-06-04 12:55:44

 回想了一下自己关于 pytorch 的学习路线,一开始找的各种资料,写下来都能跑,但是却没有给自己体会到学习的过程。有的教程一上来就是写一个 cnn,虽然其实内容很简单,但是直接上手容易让人找不到重点,学的云里雾里。有的教程又浅尝辄止,师傅领到了门槛跟前,总感觉自己还没有进门,教程就结束了。

所以我总结了一下自己当初学习的路线,准备继续深入巩固自己的 pytorch 基础;另一方面,也想从头整理一个教程,从没有接触过 pytorch 开始,到完成一些最新论文里面的工作。以自己的学习笔记整理为主线,大家可以针对参考。

第一篇笔记,我们先完成一个简单的分类器。主要流程分为以下三个部分:

1,自定义生成一个训练集,具体为在二维平面上的一些点,分为两类;

2,构建一个浅层神经网络,实现对特征的拟合,主要是明白在 pytorch 中网络结构如何搭建;

3,完成训练和测试部分的工作,熟悉 pytorch 如何对网络进行训练和测试。

1. 自定义生成数据集

  1. n_data = torch.ones(100, 2)  
  2. x0 = torch.normal(2*n_data, 1)  
  3. y0 = torch.zeros(100)  
  4. x1 = torch.normal(-2*n_data, 1)  
  5. y1 = torch.ones(100)  
  6. x = torch.cat((x0, x1)).type(torch.FloatTensor)  
  7. y = torch.cat((y0, y1)).type(torch.LongTensor) 

这篇文章我们先考虑在一个自己定义的简单数据集上实现分类,这样子可以最简单的了解一个神经网络的模型,如何用 pytorch 搭建起来。

这个代码对 numpy 比较熟悉的同学应该也可以猜出来它的内容,只是在 numpy 中是一个 numpy array,在 pytorch 中是一个 tensor。这里我简单的介绍一下这几行代码的作用,给有需要的同学捋顺思路。

首先 n_data 是基准数据,用来生成其它数据,内容为一个 100 行 2 列 的 tensor,其中的值都为 1。x0 是一类数据的坐标值,通过这个 n_data 来生成。

具体的生成的办法是用 torch.normal() 这个函数,第一个参数为 mean,第二个参数是 std。所以返回的结果 x0 是一个和 n_data 形状一样,但是其中的数据在以 2 为平均值,以 1 为标准差的正态分布中随机选取的。y0 则是一个 100 维的 tensor,其中的值都为 0。

我们可以这样理解 x0 和 y0,x0 的形状是 100 行 2 列的 tensor,其中的值以 2 为中心进行随机分布,符合正态分布,而这些点的标签我们设置为 y0,也就是 0。与此相反,x1 对应的中心为 -2,且标签为 y1,也就是每个点的标签都为 1。

最后生成的 x 和 y,就是将所有的数据合并起来,x0 和 x1 合并起来作为数据,y0 和 y1 合并起来作为标签。

2. 构建一个浅层神经网络

  1. class Net(torch.nn.Module):  
  2.     def __init__(self, n_feature, n_hidden, n_output):  
  3.         super(Net, self).__init__()  
  4.         self.n_hidden = torch.nn.Linear(n_feature, n_hidden)  
  5.         self.out = torch.nn.Linear(n_hidden, n_output)  
  6.     def forward(self, x_layer):  
  7.         x_layer = torch.relu(self.n_hidden(x_layer))  
  8.         x_layer = self.out(x_layer) 
  9.          x_layer = torch.nn.functional.softmax(x_layer)  
  10.         return x_layer  
  11. net = Net(n_feature=2n_hidden=10n_output=2 
  12. # print(net)  
  13. optimizer = torch.optim.SGD(net.parameters(), lr=0.02)  
  14. loss_func = torch.nn.CrossEntropyLoss() 

上面的 Net() 类就是如何构建一个神经网络的步骤。我们如果是第一次用 pytorch 写一个神经网络,那么这个就是一个足够简单的例子了。其中的内容由两部分组成,分别是 __init__() 函数和 forward() 函数。

大家可以简单的这样子理解:__init__() 函数中,是对网络结构的定义,都有哪些层,每层又有什么功能。例如这个函数中,self.n_hidden 就是定义了一个线性拟合函数,也就是全连接层,在此处相当于一个向隐藏层的映射。输入是 n_feature,输出是隐藏层的神经元个数 n_hidden。然后 self.out 也一样是一个全连接层,输入是刚才的隐藏层的神经元个数 n_hidden,输出是最后的输出结果 n_output。

接着就是 forward() 函数,在这里相当于定义我们神经网络的执行顺序。所以这里可以看到,先对输入的 x_layer 执行上面的隐藏层函数,也就是第一个全连接 self.n_hidden(),然后对输出再执行激活函数 relu。接下来如法炮制,经过一个输出层 self.out(),得到最后的输出。然后将输出 x_layer 返回。

optimizer 就是这里定义的优化方式,其中的 lr 是学习率的参数。然后损失函数我们选择交叉熵损失函数,也就是上面的最后一行代码。优化算法和损失函数,可以在 pytorch 中直接选择不同的 api 接口,形式上直接参考上面这种固定形式便可。

3. 完成训练和测试

  1. for i in range(100):  
  2.     out = net(x)  
  3.     # print(out.shape, y.shape)  
  4.     loss = loss_func(out, y)  
  5.     optimizer.zero_grad()  
  6.     loss.backward()  
  7.     optimizer.step() 

接下来我们看一下如何进行训练的过程。net() 是我们对 Net() 类实例化出来的一个对象,所以利用 net() 可以直接完成模型的运行,out 就是模型预测出来的结果,loss 则是和真实值按照交叉熵损失函数计算出来的误差。

下面的三行代码是一个标准形式,表示了如何进行梯度的反向传播。到此其实我们的训练已经完成了,这个网络现在可以直接拿来对测试的数据集进行预测分类了。

  1. # train result  
  2. train_result = net(x)  
  3. # print(train_result.shape)  
  4. train_predict = torch.max(train_result, 1)[1]  
  5. plt.scatter(x.data.numpy()[:, 0], x.data.numpy()[:, 1], c=train_predict.data.numpy(), s=100lw=0cmap='RdYlGn' 
  6. plt.show() 

为了让大家更好的理解这个模型的作用,这里我们来做一些可视化的工作,看看一个模型的学习效果。通过 python 很常见的一个数据可视化的库 matplotlib 可以实现这个目标,具体的 matplotlib 的用法就不介绍了。

这里的作用是显示出来训练好的模型对训练集的分类效果,可以理解为训练误差。

  1. # test  
  2. t_data = torch.zeros(100, 2)  
  3. test_data = torch.normal(t_data, 5)  
  4. test_result = net(test_data)  
  5. prediction = torch.max(test_result, 1)[1]  
  6. plt.scatter(test_data[:, 0], test_data[:, 1], s=100c=prediction.data.numpy(), lw=0cmap='RdYlGn' 
  7. plt.show() 

然后我们以 0 为 mean,随机生成一些数据,来看看模型会怎么去分类这些数据点。

虽然没有画出来那条训练好的分割线,但是我们也可以看到模型学习了一个分割的界面,来将数据划分为两类。

PyTorch 分类器 神经网络
上一篇:机器学习将给电力行业带来巨大变革 下一篇:从AI测温到安防机器人 智能安防会是新的“守门神”吗?
评论
取消
暂无评论,快去成为第一个评论的人吧

更多资讯推荐

ResNet假说被推翻?Reddit小哥:这么多年都没人搞懂Ta的原理

ResNet 发布至今已经有六年多了,但它的工作原理至今仍然是个迷。最近Reddit 上一个网友发帖表示,是否ResNet的创新出发点就有问题?

佚名 ·  2021-10-18 17:50:32
真 · 神经网络发明人福岛邦彦获奖,Schmidhuber、李飞飞点赞

1980 年,福岛邦彦首次使用卷积神经网络实现了模式识别,他被认为是真正的卷积神经网络发明者。

机器之心编辑部 ·  2021-10-15 10:32:42
深度学习正改变物理系统模拟,速度最高提升20亿倍那种

他们用强化学习优化游戏NPC的寻路行为,用GAN生成丰富的NPC脸型。

梦晨 ·  2021-10-12 15:15:01
用Transformer进行图像语义分割,性能超最先进的卷积方法

Transformer跨界计算机视觉领域真是越来越频繁了、效果也越来越成功了!

丰色 ·  2021-05-21 10:06:01
每次矩阵相乘用不到一个光子,手写数字识别准度超90%,光学神经网络效率提升数个量级

康奈尔大学等机构的这项研究证明了光学神经网络在原理上比传统神经网络具有更多基本的能效优势。在光子预算限制为每个标量乘积少于一个光子,研究者使用光学神经网络实现了非常高的手写数字分类准确度。

力元、杜伟 ·  2021-05-19 10:22:42
多尺度表征10亿像素图像,斯坦福神经场景表征新方法入选SIGGRAPH

斯坦福大学近日的一项研究给出了解决方案,他们提出了一种新的隐式 - 显式混合网络架构和相应训练策略,可以在训练和推理过程中根据信号的局部复杂度来自适应地分配资源。

佚名 ·  2021-05-17 10:05:08
LeCun联手博士后arxiv发文,遭reddit网友质疑:第一张图就错了

两个月前自监督学习领域出了一篇重磅论文,LeCun和他的学生共同完成新模型Barlow Twins,reddit网友指出,第一张图就错了!

佚名 ·  2021-05-11 14:26:30
新的人工神经元设备可以使用极少能量运行神经网络计算

加州大学圣地亚哥分校的研究人员开发了一种新的人工神经元装置,训练神经网络来执行任务。

佚名 ·  2021-04-29 08:50:39
Copyright©2005-2021 51CTO.COM 版权所有 未经许可 请勿转载