在本章节中,并不会对神经网络进行介绍,因此如果不了解神经网络的话,强烈推荐先去看《西瓜书》,或者看一下我的上一篇博客:数据挖掘入门系列教程(七点五)之神经网络介绍

本来是打算按照《Python数据挖掘入门与实践》里面的步骤使用神经网络来识别验证码,但是呢,验证码要自己生成,然后我又想了一下,不是有大名鼎鼎的MNIST数据集吗,为什么不使用它呢,他不香吗?

MNIST(Mixed National Institute of Standards and Technology database)相信大家基本上都了解过他,大部分的机器学习入门项目就是它。它是一个非常庞大的手写数字数据集(官网)。里面包含了0~9的手写的数字。部分数据如下:

数据集分为两个部分,训练集和测试集。然后在不同的集合中分为两个文件,数据Images文件和Labels文件。在数据集中一个有60,000个训练数据和10,000个测试数据。图片的大小是28*28。

下载数据集

万物始于数据集,尽管官网提供了数据集供我们下载,但是在sklearn中提供了更方便方法让我们下载数据集。代码如下:

  1. import numpy as np
  2. from sklearn.datasets import fetch_openml
  3. # X为image数据,y为标签
  4. X, y = fetch_openml('mnist_784', version=1, return_X_y=True)

其中X,y中间既包含了训练集又包含了测试集。也就是说X或者y中有70,000条数据。 那么数据是什么呢?

在X中,每一条数据是一个长为\(28 \times 28=784\)的数组,数组的数据是图片的像素值。每一条y数据就是一个标签,代表这张图片表示哪一个数字(从0到9)。

然后我们将数据进行二值化,像素值大于0的置为1,并将数据保存到文件夹中:

  1. X[X > 0 ] = 1
  2. np.save("./Data/dataset",X)
  3. np.save("./Data/class",y)

然后在Data文件夹中就出现了以下两个文件:

我们取出dataset中间的一条数据,然后转成28*28的格式,如下所示:

数据集既可以使用上面的方法得到,也可以从我的Github上面进行下载(其中dataset数据集因为GitHub文件大小的限制所以进行了压缩,需要解压才能够使用)。

加载数据集

前面的步骤我们下载好了数据集,现在我们就可以来加载数据了。

  1. import numpy as np
  2. X = np.load("./Data/dataset.npy")
  3. y = np.load("./Data/class.npy")

取出X中的一条数据如下所示:

取出y中的一条数据,如下所示:

一切都很完美,但是这里有一个问题,在神经网络中,输出层实际上是这样的:

它并不是直接输出某一个结果,而是输出\(y_1,…,y_j,…,y_l\)结果(在MNIST中\(l=10\),因为只有10种数字)。以上面的5为例子,输出层并不是单纯的输出只输出一个数字,而是要输出10个值。那么如何将输出5变成输出10个数字呢?这里我们使用”one hot Encoding“。

One-Hot编码,又称为一位有效编码,主要是采用\(N\)位状态寄存器来对\(N\)个状态进行编码,每个状态都由他独立的寄存器位,并且在任意时候只有一位有效。

以下面的数据为例,每一行代表一条数据,每一列代表一个属性。其中第2个属性只需要3个状态码,因为他只有0,1,2三种属性。这样我们就可以使用100代表0,010代表1,001代表2。

那么这个数据编码后的数据长什么样呢?如下图:

现在我们就可以将前面加载的数据集标签\(y\)进行“one hot Encoding”。

代码如下:

  1. from sklearn.preprocessing import OneHotEncoder
  2. # False代表不生成稀疏矩阵
  3. onehot = OneHotEncoder(sparse = False)
  4. # 首先将y转成行长为7000,列长为1的矩阵,然后再进行转化。
  5. y = onehot.fit_transform(y.reshape(y.shape[0],1))

接着就是切割数据集了。将数据集切割成训练集和测试集。

  1. from sklearn.model_selection import train_test_split
  2. x_train,x_test,y_train,y_test = train_test_split(X,y,random_state=14)

在神经网络中,我们使用pybrain框架去构建一个神经网络。但是呢,对于pybrain库,他很与众不同,他要使用自己的数据集格式,因此,我们需要将数据转成它规定的格式。

  1. from pybrain.datasets import SupervisedDataSet
  2. train_data = SupervisedDataSet(x_train.shape[1],y.shape[1])
  3. test_data = SupervisedDataSet(x_test.shape[1],y.shape[1])
  4. for i in range(x_train.shape[0]):
  5. train_data.addSample(x_train[i],y_train[i])
  6. for i in range(x_test.shape[0]):
  7. test_data.addSample(x_test[i],y_test[i])

终于,数据集的加载就到这里结束了。接下来我们就可以开始构建一个神经网络了。

构建神经网络

首先我们来创建一个神经网络,网络中只含有输入层,输出层和一层隐层。

  1. from pybrain.tools.shortcuts import buildNetwork
  2. # X.shape[1]代表属性的个数,100代表隐层中神经元的个数,y.shape[1]代表输出
  3. net = buildNetwork(X.shape[1],100, y.shape[1], bias=True)

这里说有以下“bias”的作用。bias代表的是偏置神经元,bias = True代表偏置神经元激活,也就是在每一层都使用这个这个神经元。偏置神经元如下图,实际上也就是阈值,只不过换一种说法而已。

现在我们已经构建好了一个比较简单的神经网络,接下来我们就是使用BP算法去得到合适的权重值了。

反向传播(BP)算法

具体的算法步骤在上一篇博客已经介绍过了,很幸运的是在pybrain中间提供了BP算法的库供我们使用。这里就直接上代码吧。关于BackpropTrainer更加细节的使用可以看官网

  1. from pybrain.supervised.trainers import BackpropTrainer
  2. trainer = BackpropTrainer(net, train_data, learningrate=0.01,weightdecay=0.01)

这里面有几个参数稍微的说明下:

  • net:神经网络

  • train_data:训练的数据集

  • learningrate:学习率,也就是下面的\(\eta\),同样它可以使用lrdecay这个参数去控制衰减率,具体的就去看官网文档吧。

    \[\begin{equation}\begin{array}{l}
    \Delta w_{h j}=\eta g_{j} b_{h} \\
    \Delta \theta_{j}=-\eta g_{j} \\
    \Delta v_{i h}=\eta e_{h} x_{i} \\
    \Delta \gamma_{h}=-\eta e_{h} \\

    \end{array}\end{equation}
    \]

  • weightdecay:权重衰减,权重衰减也就是下面的\(\lambda\)

    \[\begin{equation}
    E=\lambda \frac{1}{m} \sum_{k=1}^{m} E_{k}+(1-\lambda) \sum_{i} w_{i}^{2} \\
    \lambda \in(0,1)
    \end{equation}
    \]

然后我们就可以开始训练了。

  1. trainer.trainEpochs(epochs=100)

epochs也就是训练集被训练遍历的次数。

接下载便是等待的时间了。等待训练集训练成完成。训练的时间跟训练集的大小,隐层神经元的个数,电脑的性能,步数等等有关。

切记切记,这一次的程序就不要在阿里云的学生机上面跑了,还是用自己的机器跑吧。尽管联想小新pro13 i5版本性能还可以,但是还是跑了一个世纪这么久,哎(耽误了我打游戏的时间)。

进行预测

通过前面的步骤以及等待一段时间后,我们就完成了模型的训练。然后我们就可以使用测试集进行预测。

  1. predictions = trainer.testOnClassData(dataset=test_data)

predictions的部分数据,代表着测试集预测的结果:

然后我们就可以开始验证准确度了,这里继续使用F1评估。这个已经在前面介绍过了,就不再介绍了。

F1验证

这里有个地方需要注意,因为之前的y_test数据我们使用one-hot encoding进行了编码,因此我们需要先将one-hot编码转成正常的形式。

  1. # 取每一行最大值的索引。
  2. y_test_arry = y_test.argmax(axis =1)

具体效果如下:

然后使用F1值进行验证。

  1. from sklearn.metrics import f1_score
  2. print("F-score: {0:.2f}".format(f1_score(predictions,y_test_arry,average='micro')))

然后结果如下:

结果只能说还行吧,不是特别的差,但是也不是特别的好。

总结

项目地址:Github。尽管上面的准确度不咋地,只有\(86\%\),但是也还行吧,毕竟也是使用了一层隐层,然后隐层也只有100个神经元。

如果电脑的性能不够的话,可是适当的减少步数和训练集的大小,以及隐层神经元的个数。

参考

数据挖掘入门系列教程(八)之使用神经网络(基于pybrain)识别数字手写集MNIST的更多相关文章

  1. 数据挖掘入门系列教程(四)之基于scikit-lean实现决策树

    目录 数据挖掘入门系列教程(四)之基于scikit-lean决策树处理Iris 加载数据集 数据特征 训练 随机森林 调参工程师 结尾 数据挖掘入门系列教程(四)之基于scikit-lean决策树处理 ...

  2. 数据挖掘入门系列教程(九)之基于sklearn的SVM使用

    目录 介绍 基于SVM对MINIST数据集进行分类 使用SVM SVM分析垃圾邮件 加载数据集 分词 构建词云 构建数据集 进行训练 交叉验证 炼丹术 总结 参考 介绍 在上一篇博客:数据挖掘入门系列 ...

  3. 数据挖掘入门系列教程(十点五)之DNN介绍及公式推导

    深度神经网络(DNN,Deep Neural Networks)简介 首先让我们先回想起在之前博客(数据挖掘入门系列教程(七点五)之神经网络介绍)中介绍的神经网络:为了解决M-P模型中无法处理XOR等 ...

  4. 数据挖掘入门系列教程(四点五)之Apriori算法

    目录 数据挖掘入门系列教程(四点五)之Apriori算法 频繁(项集)数据的评判标准 Apriori 算法流程 结尾 数据挖掘入门系列教程(四点五)之Apriori算法 Apriori(先验)算法关联 ...

  5. 数据挖掘入门系列教程(十一)之keras入门使用以及构建DNN网络识别MNIST

    简介 在上一篇博客:数据挖掘入门系列教程(十点五)之DNN介绍及公式推导中,详细的介绍了DNN,并对其进行了公式推导.本来这篇博客是准备直接介绍CNN的,但是想了一下,觉得还是使用keras构建一个D ...

  6. 数据挖掘入门系列教程(二)之分类问题OneR算法

    数据挖掘入门系列教程(二)之分类问题OneR算法 数据挖掘入门系列博客:https://www.cnblogs.com/xiaohuiduan/category/1661541.html 项目地址:G ...

  7. 数据挖掘入门系列教程(三)之scikit-learn框架基本使用(以K近邻算法为例)

    数据挖掘入门系列教程(三)之scikit-learn框架基本使用(以K近邻算法为例) 简介 scikit-learn 估计器 加载数据集 进行fit训练 设置参数 预处理 流水线 结尾 数据挖掘入门系 ...

  8. 数据挖掘入门系列教程(五)之Apriori算法Python实现

    数据挖掘入门系列教程(五)之Apriori算法Python实现 加载数据集 获得训练集 频繁项的生成 生成规则 获得support 获得confidence 获得Lift 进行验证 总结 参考 数据挖 ...

  9. 数据挖掘入门系列教程(十二)之使用keras构建CNN网络识别CIFAR10

    简介 在上一篇博客:数据挖掘入门系列教程(十一点五)之CNN网络介绍中,介绍了CNN的工作原理和工作流程,在这一篇博客,将具体的使用代码来说明如何使用keras构建一个CNN网络来对CIFAR-10数 ...

随机推荐

  1. 操作系统-IO管理和磁盘调度

    I/O设备 IO设备的类型 分为三类:人机交互类外部设备:打印机.显示器.鼠标.键盘等等.这类设备数据交换速度相对较慢,通常是以字节为单位进行数据交换的 存储设备:用于存储程序和数据的设备,如磁盘.磁 ...

  2. 7-41 jmu-python-最佳身高 (10 分)

    最佳的情侣身高差遵循着一个公式:(女方的身高)×1.09 =(男方的身高).下面就请你写个程序,为任意一位用户计算他/她的情侣的最佳身高. 输入格式: 输入第一行给出正整数N(≤10),为前来查询的用 ...

  3. day07深浅copy与流程控制

    目录:流程控制 0:补充(了解) 短路运算:偷懒原则,偷懒到哪个位置,就把当前位置的值返回 深浅copy 1.循环之while循环 循环的语法与基本使用 死循环与效率问题 循环的应用 退出循环的两种方 ...

  4. .Net Core 为 x86 和 x64 程序集编写 AnyCPU 包装

    前言 这几天研究了一下 vJoy 这个虚拟游戏手柄驱动,感觉挺好玩的.但是使用时发现一个问题,C# SDK 中的程序集被分为 x86 和 x64 两个版本,如果直接在 AnyCPU 平台编译运行就有隐 ...

  5. 搭建flutter开发

    最近入坑flutter,dart还没开始学,搭环境就干了我一天半,不容易,记录一下, 我们先立个目标,这是我已经配好的,我是真的有强迫症,需要打四个对勾,真的不容易,我们一个一先说一下每一个都代表什么 ...

  6. ASP.NET Core 中jwt授权认证的流程原理

    目录 1,快速实现授权验证 1.1 添加 JWT 服务配置 1.2 颁发 Token 1.3 添加 API访问 2,探究授权认证中间件 2.1 实现 Token 解析 2.2 实现校验认证 1,快速实 ...

  7. DOM解读

    DOM解读 DOM概念 - document object model:文档对象模型 操作文档的一套方法,document是一个对象,是dom的顶级对象,属于window的一个对象,并且可以说是最出色 ...

  8. redis作为消息队列的原理

    Redis队列功能介绍 List 转:https://blog.csdn.net/cestlavieqiang/article/details/84197736 常用命令: Blpop删除,并获得该列 ...

  9. Vue2.0 【第一季】第4节 v-text & v-html

    目录 Vue2.0 [第一季]第4节 v-text & v-html 第四节 v-text & v-html Vue2.0 [第一季]第4节 v-text & v-html 第 ...

  10. [项目分享]JSP+Servlet+JDBC实现的云端汽修后台管理系统

    本文存在视频版本,请知悉 项目简介 项目来源于:https://gitee.com/chenlinSir/CloudDemo-servlet 难度等级:简单 基于JSP+Servlet+Jdbc的云端 ...