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

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

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

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

下载数据集

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

import numpy as np
from sklearn.datasets import fetch_openml
# X为image数据,y为标签
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,并将数据保存到文件夹中:

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

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

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

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

加载数据集

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

import numpy as np
X = np.load("./Data/dataset.npy")
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”。

代码如下:

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

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

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

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

from pybrain.datasets import SupervisedDataSet

train_data = SupervisedDataSet(x_train.shape[1],y.shape[1])
test_data = SupervisedDataSet(x_test.shape[1],y.shape[1]) for i in range(x_train.shape[0]):
train_data.addSample(x_train[i],y_train[i])
for i in range(x_test.shape[0]):
test_data.addSample(x_test[i],y_test[i])

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

构建神经网络

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

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

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

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

反向传播(BP)算法

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

from pybrain.supervised.trainers import BackpropTrainer
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}
    \]

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

trainer.trainEpochs(epochs=100)

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

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

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

进行预测

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

predictions = trainer.testOnClassData(dataset=test_data)

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

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

F1验证

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

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

具体效果如下:

然后使用F1值进行验证。

from sklearn.metrics import f1_score
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. 快速上手百度大脑EasyDL专业版·物体检测模型(附代码)

    作者:才能我浪费991.    简介:1.1.    什么是EasyDL专业版EasyDL专业版是EasyDL在2019年10月下旬全新推出的针对AI初学者或者AI专业工程师的企业用户及开发者推出的A ...

  2. 7-29 jmu-python-不同进制数 (10 分)

    输入一个十进制整数,输出其对应的八进制数和十六进制数.要求采用print函数的格式控制进行输出,八进制数要加前缀0o,十六进制数要加前缀0x. 输入格式: 输入一个十进制整数,例如:10 输出格式: ...

  3. js中的内置方法的兼容写法

    1.如果浏览器不支持every属性,every的实现原理 if(Array.prototype.every===undefined){ Array.prototype.every=function(f ...

  4. Object-Oriented Programming Summary Ⅰ

    Part 0: 前言 令人闻风丧胆的OO还是来了.并没有像名字的外表一样可爱,简直就是恶魔. 疯狂压榨OS的时间,周末无法休息,互测狼人机制 虽然网上骂声很多,就算改进到9012年还是有很多不足的地方 ...

  5. Ubuntu中VMware tools的安装步骤

    按照下面的步骤,轻松解决!! 1.点击导航栏中的虚拟机,下面的安装VMware tools 2.点击桌面上的光盘,进入后,将tar.gz文件复制到桌面,然后右击提取到此处: 3.在桌面打开终端,cd到 ...

  6. 关于org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.atguigu.crud.dao.DepartmentMapper.insertSelective的错误

    今天我在使用mybatis逆向工程的时候,由于一个疏忽字打错了..结果花了一早上才把错误找全..广大小伙伴们一定要小心啊(能复制粘贴就别手打) 关于org.apache.ibatis.binding. ...

  7. Ubuntu系统下环境安装遇到依赖冲突问题

    问题场景:在ubuntu系统下使用docker拉了一个python3.6的镜像,要在该容器中安装vim结果总是报已安装某些依赖的版本不满足要求 解决方法: 1.安装aptitude apt-get i ...

  8. Airport Simulation (数据结构与算法 – 队列 / Queue 的应用)

    Airport Simulation 是数据结构与算法教材中用于演示Queue的一个小程序(大多数教师似乎会跳过这个练习).主程序会通过输入总的运行时间.队列里可以等待的最多飞机数量,平均每个时间单元 ...

  9. 【Weiss】【第04章】AVL树例程

    普通的二叉搜索树可能会由于数据不平均.删除产生高度差等原因,使树倾向于不平衡生长,导致操作慢于O(NlogN). 为应对此现象,将搜索.删除.插入的最坏时间也控制在O(NlogN)上,产生了平衡二叉树 ...

  10. 测试必知必会系列- Linux常用命令 - ps(重点)

    21篇测试必备的Linux常用命令,每天敲一篇,每次敲三遍,每月一循环,全都可记住!! https://www.cnblogs.com/poloyy/category/1672457.html 查看所 ...