Logo
Section 1 / 5

数据优先

熟悉一个著名的数据集 MNIST。

导入

数据优先

熟悉一个著名的数据集 MNIST。

关于数据

是时候从简单的披萨相关示例,迈向图像识别了。我们将要做一些神奇的事情——在接下来的几节课内,我们就会拥有一个能够对图像进行分类的程序。

在本章及下一章中,我们将把二分类模型应用于 MNIST 数据集。MNIST 是一个手写数字数据库。几年前,在机器学习系统尚无法处理更复杂数据集的时代,人工智能研究者常用 MNIST 作为算法性能的基准测试。这将是我们首次接触计算机视觉,因此让我们循序渐进:先从识别单个 MNIST 数字开始,更通用的字符识别则留到下一章。

在将数据输入机器学习系统之前,我们需要先深入了解这些数据本身。本节将介绍关于 MNIST 所需了解的一切内容。

认识 MNIST

MNIST 是专为监督学习而整理的一组带标签图像数据集。其名称意为“修改版 NIST”(Modified NIST),因为它源自美国国家标准与技术研究院(NIST)早期数据的重新整理版本。MNIST 包含大量手写数字图像,并附有对应的数值标签。以下是几个随机选取的样本及其标签:

...
Random MNIST characters with their labels

每个数字图像由 28×28 的灰度像素构成,每个像素用一个字节表示。在 MNIST 的灰度体系中,0 表示“纯白背景”,255 表示“纯黑前景”。以下是一个放大后的数字示例:

...
A sample of MNIST digit '5'

以现代机器学习的标准来看,MNIST 并不算庞大,但也绝非微小。它总共包含 70,000 个样本,均匀划分为 0 到 9 每个数字各 7,000 个。这些数字来自真实书写场景,因此风格多样、差异明显。

...
Few samples of MNIST digit '5'

其中一些“5”的写法甚至难以辨认,看起来几乎像杂乱的涂鸦。如果我们能编写出一个程序准确识别这些数字,那无疑可以算作一次成功。

像 MNIST 这样的数据集对机器学习社区极为宝贵。尽管机器学习本身效率很高,但收集、标注、清洗和预处理数据往往需要大量繁琐工作。MNIST 的维护者已经为我们完成了这些任务:他们收集图像,标注类别,统一尺寸、旋转角度和中心位置,并转换为一致的灰度标准。我们可以直接将这些数据输入学习程序,无需额外处理。

MNIST 将图像和标签分别存储在不同的文件中。虽然已有许多库支持读取该数据,但由于格式较为简单,自行实现一个文件读取器也是合理的选择。

MNIST 由四个文件组成:其中两个文件分别包含 60,000 张训练图像及其对应标签;另外两个文件则包含预留的 10,000 张测试图像及标签。

你可能会疑惑:为何不能用同一组数据既做训练又做测试?这个问题需要一段简要说明。

训练与测试

回顾一下我们此前测试学习程序的方式:首先使用带标签的样例进行训练,然后用相同的样例生成预测结果数组,并将其与真实标签对比。预测结果越接近真实值,模型表现越好。这种方法在学习基础知识时效果不错,但在实际项目中会失效。原因如下:

  • 假设你正在和朋友讨论 MNIST。朋友提出打赌:他能写出一个系统,仅通过一轮训练就能实现 100% 准确率的分类。这听起来像是稳输的赌局,但他其实很容易赢。你知道他是怎么做到的吗?
  • 他的 train() 函数根本不进行学习,只是把训练样本存入一个字典(一种将键映射到值的数据结构,根据编程背景不同,也可能称为“map”、“hashtable”等)。在这个字典中,图像是键,标签是值。当后续请求分类某张图像时,程序只需在字典中查找该图像并返回对应的标签。就这样,仅用一次训练迭代就实现了完美预测,甚至根本没实现任何机器学习算法!
  • 此时你有理由抱怨朋友作弊了。他的系统并未真正“学习”,而是单纯“记忆”了所有图像和标签。一旦遇到未曾见过的新图像,系统只能沉默以对。与真正的学习系统不同,它无法将已有知识推广到新数据上。
  • 更关键的是:许多机器学习系统天生具有记忆训练数据的倾向,这种现象被称为过拟合(overfitting)。当一个系统在熟悉的数据上表现很好,而在新数据上表现变差时,我们就认为它出现了过拟合。这样的系统可能在训练期间见过的图像上分类非常准确,但面对新图像时却令人失望。
  • 本课程后续将详细探讨过拟合问题,并介绍几种缓解其影响的技术。目前最重要的一点是:永远不要用训练数据来测试模型。否则,由于过拟合的存在,你可能会得到过于乐观的评估结果。正确的做法是在训练前就预留一部分样本用于测试,并在整个训练过程中保持不变,直到训练完成后再使用。

现在我们已经了解了 MNIST 的组织方式,以及为何要将其划分为独立的训练集和测试集。掌握这些知识后,就可以继续前进了。

让我们开始开发

我们自己的 MNIST 库