手写数字数据集_Python神经网络编程:手写数字的数据集MNIST

本文介绍了使用Python和神经网络识别手写数字的MNIST数据集,包括数据的获取、预处理、训练和测试。通过调整学习率和网络形状,提高了识别准确率,最终达到了97.62%的准确度。
摘要由CSDN通过智能技术生成

d4078cbe17c458a99ef3a8fe491b4af2.png

识别人的笔迹这个问题相对复杂,也非常模糊,因此这是一种检验人工智能的理想挑战。这不像进行大量数字相乘那样明确清晰。

让计算机准确区分图像中包含的内容,有时也称之为图像识别问题。科学家对这个问题进行了几十年的研究,直到最近,才取得了一些比较好的进展,如神经网络这样的方法则是构成这些飞跃的重要部分。

为了让你对图像识别究竟有多难有一个感性认识,举个例子,人类有时候对图像中包含的内容有不同意见。人们很容易对手写字符实际上是什么产生分歧意见,特别对于书写者非常匆忙或粗心大意时写下的手写字符,更是如此。看一看下面的手写数字,这是个4还是9?

8f64f1cad022ed031357054ace91d7ae.png

人工智能研究者使用一套流行的手写数字图片来测试他们的最新思想和算法。这套图片众所周知,非常流行,这意味着我们很容易与其他研究者比较,检验我们最近关于图像识别的疯狂想法究竟有多优秀。

这个数据集称为手写数字的MNIST数据库。从受人尊敬的神经网络研究员Yann LeCun的网站http://yann.lecun.com/exdb/mnist/,可以得到这个数据集。

这个网页也列出了在学习和正确识别这些手写字符方面,这些新旧想法的表现如何。我们将会多次提到这个列表,看看比起专业人士我们的想法表现如何!MNIST数据库的格式不容易使用,因此其他人已经创建了相对简单的数据文件格式,参见 http://pjreddie.com/projects/mnist-in-csv/,这对我们非常有帮助。

这些文件称为CSV文件,这意味着纯文本中的每一个值都是由逗号分隔的。你可以轻松地在任何文本编辑器中查看这些数值,大部分的电子表格和数据分析软件也兼容CSV文件,它们是非常通用的标准。

这个网站提供了两个CSV文件:

  • 训练集http://www.pjreddie.com/media/files/mnist_train.csv
  • 测试集 http://www.pjreddie.com/media/files/mnist_test.csv

顾名思义,训练集是用来训练神经网络的60 000个标记样本集。标记是指输入与期望的输出匹配,也就是答案应该是多少。

可以使用较小的只有10 000个样本的测试集来测试我们的想法或算法工作的好坏程度。由于这也包含了正确的标记,因此可以观察神经网络是否得到正确的答案。

将训练和测试数据集分开的想法,是为了确保可以使用神经网络之前没有见过的数据进行再次测试。否则,我们就可以采用欺骗手段,让神经网络简单地记忆训练数据,得到一个完美、但是有欺骗性的得分。在整个机器学习领域,将测试数据与训练数据分开是一种很常见的想法。

让我们来一窥这些文件。下面显示的是加载到文本编辑器中的MNIST测试集的一部分。

d67e8b1392660908171ec89cf69d60f6.png

哇!这看起来好像出事了!就像在20世纪80年代的电影中一样,计算机被黑客攻击了。

其实一切都很好。我们很容易看到,文本编辑器显示很长的文本,这些行由使用逗号分隔的数字组成。这些行非常长,以至于它们折行了好几次。对我们有帮助的是,这个文本编辑器在边缘显示了实际的行号,可以看到完整的4行数据以及第5行的一部分数据。

在文本中,这些记录或这些行的内容很容易理解:

  • 第一个值是标签,即书写者实际希望表示的数字,如“7”或“9”。这是我们希望神经网络学习得到的正确答案。
  • 随后的值,由逗号分隔,是手写体数字的像素值。像素数组的尺寸是28 乘以28,因此在标签后有784个值。如果想知道这是否有784个值,可以一个一个地数一下。

因此,第一个记录表示数字“5”,就是所显示的第一个值,这行文本的其余部分是某人的手写数字5的像素值。第二个记录表示数字“0”,第三个记录表示数字“4”,第四个记录表示“1”,第五个表示“9”。你可以从MNIST数据文件中挑选任一行,第一个数字告诉你接下来图像数据的标签是什么。

但是,从这个长达784个值的列表中,人们很难看出这些数字组成了某人手写数字5的图片。我们会将这些数字绘制为图像,让读者确认这784个值真的是手写数字的像素值。

在深入研究进行这样操作之前,我们应该下载MNIST数据集中的一个较小的子集。MNIST数据的数据文件是相当大的,而较小的子集意味着我们可以实验、尝试和开发代码,而不会由于大量的数据集而拖慢计算机的速度,因此小数据集还是大有裨益的。一旦确定了乐于使用的算法和代码,我们就可以使用完整的数据集。

以下是MNIST数据集中较小子集的链接,也是以CSV格式存储的:

  • MNIST测试数据集中的10条记录——https://raw.githubusercontent.com/ makeyourownneuralnetwork/makeyourownneuralnetwork/master/mnist_dataset/ mnist_test_10.csv
  • MNIST训练数据集中的100条记录——https://raw.githubusercontent.com/ makeyourownneuralnetwork/makeyourownneuralnetwork/master/mnist_dataset/ mnist_train_100.csv

如果浏览器显示的是数据而不是自动下载,可以使用“File → Save As ...”手动保存文件,或在浏览器上进行等效操作。

将数据文件保存到方便操作的位置。我将数据文件保存在名为“mnist_ dataset”的文件夹中,这个文件夹就在IPython的Notebook文件旁边,如下面的屏幕截图所示。如果IPython的Notebook文件和数据文件散落在计算机的各个地方,那就会变得很混乱。

5097ad36b4e33b277e3b92cc5f7926df.png

在使用数据做任何事情之前,比如绘图或使用数据训练神经网络,我们需要找到一种方式来用Python代码得到这些数据。

在Python中,打开文件并获取其中的内容是一件非常容易的事情。先来演示一下这个操作,然后再做出解释。看看下面的代码:

data_file = open("mnist_dataset/mnist_train_100.csv", 'r') 
data_list = data_file.readlines() 
data_file.close()

这里只有3行代码。让我们一一进行讨论。

第一行使用open()函数打开一个文件。传递给函数的第一个参数是文件的名称。其实,这不仅仅是文件名“mnist_train_100.csv”,这是整个路径,其中包括了文件所在的目录。第二个参数是可选的,它只是告诉Python我们希望如何处理文件。“r”告诉Python以只读的方式而不是可写的方式打开文件。这样可以避免任何更改数据或删除数据的意外。如果试图写入文件、修改文件,Python将阻止并生成一条错误消息。

变量data_file是什么?open()函数创建了此文件的一个文件句柄、一个引用,我们将这个句柄分配给命名为data_file的变量。现在已经打开了文件,任何进一步的操作,如读取文件,都将通过句柄完成。

下一行代码很简单。使用与文件句柄data_file相关的readlines()函数,将文件中的所有行读入变量data_list。这个变量包含了一个列表,列表中的一项是表示文件中一行的字符串。在列表中,可以跳到特定的条目,类似地,也可以跳到文件中特定的行,这样这个列表就有用多了。因此data_list [0] 是第一条记录,data_list [9]是第十条记录,以此类推。

顺便说一句,由于readlines()会将整个文件读取到内存中,因此你可能会听到别人告诉你不要使用这种方法。他们会告诉你,一次读取一行,对这行进行所需要进行的操作,然后移动到下一行。他们都没有错,不要将整个文件读入内存中,而是一次在一行上工作,这更有效率。但是,我们的文件不是很大,如果使用readlines(),那么代码相对容易一些,对我们而言,在学习Python时简单和清晰是很重要的。

最后一行代码关闭文件。在用完如文件这样的资源后,关闭和清理文件是一种很好的做法。如果不这样做,文件依然开着,这可能会造成问题。什么问题呢?有些程序可能不希望写入处在打开状态的文件,以免导致不一致。这就像是两个人试图在同一张纸上写信!有时候,计算机可能会锁定文件,防止发生这种冲突。如果使用完文件不清理,那么你就有一堆锁定的文件。最起码应该关闭文件,让计算机释放用于保存文件的部分内存。

创建一个新的空的Notebook,试试这段代码,当打印出列表的元素时,观察发生了什么。下图显示了这种操作的结果。

326c6bd01272587a705e09e46e153501.png

可以看到,列表的长度为100 。Python的len()函数告诉我们列表的大小。

还可以看到第一条记录data_list [0]的内容。第一个数字是“5”,这是标签,并且其余的784个数字是构成图像像素的颜色值。如果你仔细观察,可以发现这些颜色值似乎介于0和255之间。

你可能希望看看其他记录,看看在其他记录中是否也是这样的。你会发现,颜色值确实落到了0到255的范围内。

先前,我们确实看到了如何使用imshow()函数绘制数字矩形数组。在这里,我们要做的事情是相同的,但是需要将使用逗号分隔的数字列表转换成合适的数组。要达到这个目标,需要进行以下的步骤:

  • 将由逗号分隔,长的文本字符串值,拆分成单个值,在逗号处进行分割。
  • 忽略第一个值,这是标签,将剩余的28 × 28 = 784个值转换成28列28行的数组。
  • 绘制数组!
  • </
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值