转自:https://blog.csdn.net/simple_the_best/article/details/75267863

MNIST 数据集已经是一个被”嚼烂”了的数据集, 很多教程都会对它”下手”, 几乎成为一个 “典范”. 不过有些人可能对它还不是很了解, 下面来介绍一下.

MNIST 数据集可在 http://yann.lecun.com/exdb/mnist/ 获取, 它包含了四个部分:

  • Training set images: train-images-idx3-ubyte.gz (9.9 MB, 解压后 47 MB, 包含 60,000 个样本)
  • Training set labels: train-labels-idx1-ubyte.gz (29 KB, 解压后 60 KB, 包含 60,000 个标签)
  • Test set images: t10k-images-idx3-ubyte.gz (1.6 MB, 解压后 7.8 MB, 包含 10,000 个样本)
  • Test set labels: t10k-labels-idx1-ubyte.gz (5KB, 解压后 10 KB, 包含 10,000 个标签)

MNIST 数据集来自美国国家标准与技术研究所, National Institute of Standards and Technology (NIST). 训练集 (training set) 由来自 250 个不同人手写的数字构成, 其中 50% 是高中学生, 50% 来自人口普查局 (the Census Bureau) 的工作人员. 测试集(test set) 也是同样比例的手写数字数据.

不妨新建一个文件夹 – mnist, 将数据集下载到 mnist 以后, 解压即可:

图片是以字节的形式进行存储, 我们需要把它们读取到 NumPy array 中, 以便训练和测试算法.

import os
import struct
import numpy as np def load_mnist(path, kind='train'):
"""Load MNIST data from `path`"""
labels_path = os.path.join(path,
'%s-labels-idx1-ubyte'
% kind)
images_path = os.path.join(path,
'%s-images-idx3-ubyte'
% kind)
with open(labels_path, 'rb') as lbpath:
magic, n = struct.unpack('>II',
lbpath.read(8))
labels = np.fromfile(lbpath,
dtype=np.uint8) with open(images_path, 'rb') as imgpath:
magic, num, rows, cols = struct.unpack('>IIII',
imgpath.read(16))
images = np.fromfile(imgpath,
dtype=np.uint8).reshape(len(labels), 784) return images, labels

load_mnist 函数返回两个数组, 第一个是一个 n x m 维的 NumPy array(images), 这里的 n 是样本数(行数), m 是特征数(列数). 训练数据集包含 60,000 个样本, 测试数据集包含 10,000 样本. 在 MNIST 数据集中的每张图片由 28 x 28 个像素点构成, 每个像素点用一个灰度值表示. 在这里, 我们将 28 x 28 的像素展开为一个一维的行向量, 这些行向量就是图片数组里的行(每行 784 个值, 或者说每行就是代表了一张图片). load_mnist 函数返回的第二个数组(labels) 包含了相应的目标变量, 也就是手写数字的类标签(整数 0-9).

第一次见的话, 可能会觉得我们读取图片的方式有点奇怪:

magic, n = struct.unpack('>II', lbpath.read(8))
labels = np.fromfile(lbpath, dtype=np.uint8)

为了理解这两行代码, 我们先来看一下 MNIST 网站上对数据集的介绍:

TRAINING SET LABEL FILE (train-labels-idx1-ubyte):

[offset] [type]          [value]          [description]
0000 32 bit integer 0x00000801(2049) magic number (MSB first)
0004 32 bit integer 60000 number of items
0008 unsigned byte ?? label
0009 unsigned byte ?? label
........
xxxx unsigned byte ?? label
The labels values are 0 to 9.

通过使用上面两行代码, 我们首先读入 magic number, 它是一个文件协议的描述, 也是在我们调用 fromfile 方法将字节读入 NumPy array 之前在文件缓冲中的 item 数(n). 作为参数值传入 struct.unpack 的 >II 有两个部分:

  • >: 这是指大端(用来定义字节是如何存储的); 如果你还不知道什么是大端和小端, Endianness 是一个非常好的解释. (关于大小端, 更多内容可见<<深入理解计算机系统 – 2.1 节信息存储>>)
  • I: 这是指一个无符号整数.

通过执行下面的代码, 我们将会从刚刚解压 MNIST 数据集后的 mnist 目录下加载 60,000 个训练样本和 10,000 个测试样本.

为了了解 MNIST 中的图片看起来到底是个啥, 让我们来对它们进行可视化处理. 从 feature matrix 中将 784-像素值 的向量 reshape 为之前的 28*28 的形状, 然后通过 matplotlib 的 imshow 函数进行绘制:

import matplotlib.pyplot as plt

fig, ax = plt.subplots(
nrows=2,
ncols=5,
sharex=True,
sharey=True, ) ax = ax.flatten()
for i in range(10):
img = X_train[y_train == i][0].reshape(28, 28)
ax[i].imshow(img, cmap='Greys', interpolation='nearest') ax[0].set_xticks([])
ax[0].set_yticks([])
plt.tight_layout()
plt.show()

我们现在应该可以看到一个 2*5 的图片, 里面分别是 0-9 单个数字的图片.

此外, 我们还可以绘制某一数字的多个样本图片, 来看一下这些手写样本到底有多不同:

fig, ax = plt.subplots(
nrows=5,
ncols=5,
sharex=True,
sharey=True, ) ax = ax.flatten()
for i in range(25):
img = X_train[y_train == 7][i].reshape(28, 28)
ax[i].imshow(img, cmap='Greys', interpolation='nearest') ax[0].set_xticks([])
ax[0].set_yticks([])
plt.tight_layout()
plt.show()

执行上面的代码后, 我们应该看到数字 7 的 25 个不同形态:

另外, 我们也可以选择将 MNIST 图片数据和标签保存为 CSV 文件, 这样就可以在不支持特殊的字节格式的程序中打开数据集. 但是, 有一点要说明, CSV 的文件格式将会占用更多的磁盘空间, 如下所示:

  • train_img.csv: 109.5 MB
  • train_labels.csv: 120 KB
  • test_img.csv: 18.3 MB
  • test_labels: 20 KB

如果我们打算保存这些 CSV 文件, 在将 MNIST 数据集加载入 NumPy array 以后, 我们应该执行下列代码:

np.savetxt('train_img.csv', X_train,
fmt='%i', delimiter=',')
np.savetxt('train_labels.csv', y_train,
fmt='%i', delimiter=',')
np.savetxt('test_img.csv', X_test,
fmt='%i', delimiter=',')
np.savetxt('test_labels.csv', y_test,
fmt='%i', delimiter=',')

一旦将数据集保存为 CSV 文件, 我们也可以用 NumPy 的 genfromtxt 函数重新将它们加载入程序中:

X_train = np.genfromtxt('train_img.csv',
dtype=int, delimiter=',')
y_train = np.genfromtxt('train_labels.csv',
dtype=int, delimiter=',')
X_test = np.genfromtxt('test_img.csv',
dtype=int, delimiter=',')
y_test = np.genfromtxt('test_labels.csv',
dtype=int, delimiter=',')

不过, 从 CSV 文件中加载 MNIST 数据将会显著发给更长的时间, 因此如果可能的话, 还是建议你维持数据集原有的字节格式.

详解 MNIST 数据集的更多相关文章

  1. BI之SSAS完整实战教程5 -- 详解多维数据集结构

    之前简单介绍过多维数据集(Cube)的结构. 原来计划将Cube结构这部分内容打散,在实验中穿插讲解, 考虑到结构之间不同的部分都有联系,如果打散了将反而不好理解,还是直接一次性全部讲完. 本篇我们将 ...

  2. 全网最详细的大数据集群环境下多个不同版本的Cloudera Hue之间的界面对比(图文详解)

    不多说,直接上干货! 为什么要写这么一篇博文呢? 是因为啊,对于Hue不同版本之间,其实,差异还是相对来说有点大的,具体,大家在使用的时候亲身体会就知道了,比如一些提示和界面. 安装Hue后的一些功能 ...

  3. 全网最详细的大数据集群环境下如何正确安装并配置多个不同版本的Cloudera Hue(图文详解)

    不多说,直接上干货! 为什么要写这么一篇博文呢? 是因为啊,对于Hue不同版本之间,其实,差异还是相对来说有点大的,具体,大家在使用的时候亲身体会就知道了,比如一些提示和界面. 全网最详细的大数据集群 ...

  4. Ubuntu14.04下Ambari安装搭建部署大数据集群(图文分五大步详解)(博主强烈推荐)

    不多说,直接上干货! 写在前面的话 (1) 最近一段时间,因担任我团队实验室的大数据环境集群真实物理机器工作,至此,本人秉持负责.认真和细心的态度,先分别在虚拟机上模拟搭建ambari(基于CentO ...

  5. Ubuntu14.04下Cloudera安装搭建部署大数据集群(图文分五大步详解)(博主强烈推荐)(在线或离线)

    第一步: Cloudera Manager安装之Cloudera Manager安装前准备(Ubuntu14.04)(一) 第二步: Cloudera Manager安装之时间服务器和时间客户端(Ub ...

  6. 关于在真实物理机器上用cloudermanger或ambari搭建大数据集群注意事项总结、经验和感悟心得(图文详解)

    写在前面的话 (1) 最近一段时间,因担任我团队实验室的大数据环境集群真实物理机器工作,至此,本人秉持负责.认真和细心的态度,先分别在虚拟机上模拟搭建ambari(基于CentOS6.5版本)和clo ...

  7. snort + barnyard2如何正确读取snort.unified2格式的数据集并且入库MySQL(图文详解)

    不多说,直接上干货! 为什么,要写这篇论文? 是因为,目前科研的我,正值研三,致力于网络安全.大数据.机器学习研究领域! 论文方向的需要,同时不局限于真实物理环境机器实验室的攻防环境.也不局限于真实物 ...

  8. Oracle创建表语句(Create table)语法详解及示例、、 C# 调用Oracle 存储过程返回数据集 实例

    Oracle创建表语句(Create table)语法详解及示例 2010-06-28 13:59:13|  分类: Oracle PL/SQL|字号 订阅 创建表(Create table)语法详解 ...

  9. TextCNN 代码详解(附测试数据集以及GitHub 地址)

    前言:本篇是TextCNN系列的第三篇,分享TextCNN的优化经验 前两篇可见: 文本分类算法TextCNN原理详解(一) 一.textCNN 整体框架 1. 模型架构 图一:textCNN 模型结 ...

随机推荐

  1. 前端框架 vue 和 react 的区别

    前言:最近需要使用 react,以前用过 vue,故来总结两者的区别. 首先React与vue有几点相同之处 1.都使用了Virtual DOM 2.提供了响应式(Reactive)和组件化(Comp ...

  2. 最全Vue开发环境搭建

    前言 一直想去学Vue,不过一直找不到一个契机.然公司手机端用到了跨平台开发apicloud,里边涉及到Vue组件化开发,例如header和footer的封装,以及apicloud自定义的frame等 ...

  3. MQ与Webservice的区别

    Webservice 和MQ(MessageQueue)都是解决跨平台通信的常用手段,两者有哪些区别呢? 个人认为最本质的区别在于 Webservice近乎实时通信,而MQ却通常是延时通信. 什么意思 ...

  4. linux 上传下载 以及SCP命令

    1. scp 用法 scp就是用来在服务器和本地之间传文件的linux命令还有其他的方法,比如装ftp服务器 copy 本地的档案到远程的机器上 scp /Desktop/test.conf 用户名@ ...

  5. java Date 当天时间戳处理

    1. 代码 private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; private static Date ...

  6. CSS响应式:根据分辨率加载不同CSS的几个方法,亲测可用

    有时候你需要把同一个页面在手机和pc同时打开,其中有一个办法就是判断不同分辨路加载不同的css 小编总结了几种分别加载css的方法: 1.比较复杂的使用js判断加载不同css (亲测可用) 但是这种方 ...

  7. webapi 后台跳转 后台输出html和script

    1.跳转 [HttpGet]public HttpResponseMessage LinkTo(){ HttpResponseMessage resp = new HttpResponseMessag ...

  8. 【node】fs模块,文件和目录的操作

    检查文件是否存在,查询文件信息 fs.stat() fs.stat('./server.js', function (err, stat) { if (stat && stat.isF ...

  9. java变量常量

    1. java 变量遵循先声明,再赋值,后使用的原则. 一个变量可以只声明,不赋值,没有问题(只是这个变量没有实际意义,但完全没有问题).但如果想要使用它,那么就一定要给它赋值,而大多数时候我们又不知 ...

  10. 深入浅出React的一些细节——State

    (来源于: https://facebook.github.io/react/docs/state-and-lifecycle.html 翻译by:@TimRChen) Using State Cor ...