如何在Tensorflow.js中处理MNIST图像数据
作者:网友投稿 时间:2018-06-28 09:25
有人开玩笑说有 80% 的数据科学家在清理数据,剩下的 20% 在抱怨清理数据……在数据科学工作中,清理数据所占比例比外人想象的要多得多。一般而言,训练模型通常只占机器学习或数据科学家工作的一小部分(少于 10%)。
——Kaggle CEO Antony Goldbloom
对任何一个机器学习问题而言,数据处理都是很重要的一步。本文将采用 Tensorflow.js(0.11.1)的 MNIST 样例
(https://github.com/tensorflow/tfjs-examples/blob/master/mnist/data.js),逐行运行数据处理的代码。

MNIST 样例
18 import * as tf from '@tensorflow/tfjs';
19
20 const IMAGE_SIZE = 784;
21 const NUM_CLASSES = 10;
22 const NUM_DATASET_ELEMENTS = 65000;
23
24 const NUM_TRAIN_ELEMENTS = 55000;
25 const NUM_TEST_ELEMENTS = NUM_DATASET_ELEMENTS - NUM_TRAIN_ELEMENTS;
26
27 const MNIST_IMAGES_SPRITE_PATH =
28 'https://storage.googleapis.com/learnjs-data/model-builder/mnist_images.png';
29 const MNIST_LABELS_PATH =
30 'https://storage.googleapis.com/learnjs-data/model-builder/mnist_labels_uint8';`
首先,导入 TensorFlow(确保你在转译代码)并建立一些常量,包括:
IMAGE_SIZE:图像尺寸(28*28=784)
NUM_CLASSES:标签类别的数量(这个数字可以是 0~9,所以这里有 10 类)
NUM_DATASET_ELEMENTS:图像总数量(65000)
NUM_TRAIN_ELEMENTS:训练集中图像的数量(55000)
NUM_TEST_ELEMENTS:测试集中图像的数量(10000,亦称余数)
MNIST_IMAGES_SPRITE_PATH&MNIST_LABELS_PATH:图像和标签的路径
将这些图像级联为一个巨大的图像,如下图所示:

MNISTData
接下来,从第 38 行开始是 MnistData,该类别使用以下函数:
load:负责异步加载图像和标注数据;
nextTrainBatch:加载下一个训练批;
nextTestBatch:加载下一个测试批;
nextBatch:返回下一个批的通用函数,该函数的使用取决于是在训练集还是测试集。
本文属于入门文章,因此只采用 load 函数。
load
async load() {
// Make a request for the MNIST sprited image.
const img = new Image();
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
异步函数(async)是 Javascript 中相对较新的语言功能,因此你需要一个转译器。
Image 对象是表示内存中图像的本地 DOM 函数,在图像加载时提供可访问图像属性的回调。canvas 是 DOM 的另一个元素,该元素可以提供访问像素数组的简单方式,还可以通过上下文对其进行处理。
因为这两个都是 DOM 元素,所以如果用 Node.js(或 Web Worker)则无需访问这些元素。有关其他可替代的方法,请参见下文。
imgRequest
const imgRequest = new Promise((resolve, reject) => {
img.crossOrigin = '';
img.onload = () => {
imgimg.width = img.naturalWidth;
imgimg.height = img.naturalHeight;
该代码初始化了一个 new promise,图像加载成功后该 promise 结束。该示例没有明确处理误差状态。




