2.4.1 MNIST数据集的准备

HelloWorld是任何一种编程语言入门的基础程序,任何一位初学者在开始编程学习时,打印的第一句话往往就是HelloWorld。在深度学习编程中也有其特有的“HelloWorld”,一般指的是采用MNIST完成一项特定的深度学习项目。

对于好奇的读者来说,一定有一个疑问,MNIST究竟是什么?

实际上,MNIST是一个手写数字图片的数据集,它有60 000个训练样本集和10 000个测试样本集。打开后,MNIST数据集如图2-24所示。

图2-24 MNIST数据集

读者可直接使用本书配套源码中提供的MNIST数据集,保存在dataset文件夹中,如图2-25所示。

图2-25 本书配套源码中提供的MNIST数据集

之后使用NumPy数据库进行数据读取,代码如下:

     import numpy as np
     x_train = np.load("./dataset/mnist/x_train.npy")
     y_train_label = np.load("./dataset/mnist/y_train_label.npy")

读者也可以在百度搜索MNIST,直接下载train-images-idx3-ubyte.gz、train-labels-idx1-ubyte.gz等4个文件,如图2-26所示。

图2-26 MNIST文件中包含的数据集

下载这4个文件并解压缩。解压缩后可以发现这些文件并不是标准的图像格式,而是二进制格式,包括一个训练图片集、一个训练标签集、一个测试图片集以及一个测试标签集。其中训练图片集的内容如图2-27所示。

图2-27 MNIST文件的二进制表示(部分)

MNIST训练集内部的文件结构如图2-28所示。

图2-28 MNIST文件结构图

如图2-26所示是训练集的文件结构,其中有60 000个实例。也就是说这个文件包含60 000个标签内容,每个标签的值为一个0~9的数。这里我们先解析每个属性的含义。首先,该数据是以二进制格式存储的,我们读取的时候要以rb方式读取;其次,真正的数据只有[value]这一项,其他的[type]等只是用来描述的,并不真正在数据文件中。

也就是说,在读取真实数据之前,要读取4个32位整数。由[offset]可以看出,真正的像从0016开始,每个像素占用一个int 32位。因此,在读取像素之前,要读取4个32位整数,也就是magic number、number of images、number of rows和number of columns。

结合图2-26的文件结构和图2-25的原始二进制数据内容可以看到,图2-25起始的4字节数0000 0803对应图2-26中列表的第一行,类型是magic number(魔数),这个数字的作用为文件校验数,用来确认这个文件是不是MNIST里面的train-images-idx3-ubyte文件。而图2-25中的0000 ea60对应图2-26图列表的第二行,转化为十进制为60000,这是文件总的容量数。

下面依次对应。图2-25中从第8个字节开始有一个4字节数0000 001c十进制值为28,也就是表示每幅图片的行数。同样地,从第12个字节开始的0000 001c表示每幅图片的列数,值也为28。而从第16个字节开始则是依次每幅图片像素值的具体内容。

这里使用每784(28×28)字节代表一幅图片,如图2-29所示。

图2-29 每个手写体被分成28×28个像素