Ternsorflow 学习:003-MNIST入门有关概念

前言

当我们开始学习编程的时候,第一件事往往是学习打印“HelloWorld”。就好比编 程入门有 HelloWorld,机器学习入门有 MNIST。

MNIST 是一个入门级的计算机视觉数据集,它包含各种手写数字图片,以及每一张图片对应的标签(标签用于告诉我们这个是数字几)。MNIST是在机器学习领域中的一个经典问题。该问题解决的是把28x28像素的灰度手写数字图片识别为相应的数字,其中数字的范围从0到9。

在此教程中,我们通过将训练一个机器学习模型用于预测图片里面的数字,介绍下如何使用TensorFlow。所以,我们这里会从一个很简单的数学模型开始,它叫做 SoftmaxRegression。

对应这个教程的实现代码很短,而且真正有意思的内容只包含在三行代码里面。但是,去理解包含在这些代码里面的设计思想是非常重的:TensorFlow 工作流程和机器学习的基本概念。因此,这个教程会很详细地介绍这些代码的实现原理。

准备数据

官方的下载方式:下载并执行input_data.py
input_data.py 文件中, maybe_download() 函数可以确保这些训练数据下载到本地文件夹中。

由于下载不方便,这篇文章的例程片段可以在-这里-下载。下载后运行里面的py即可完成数据的下载,其他部分仍需要读者自行完成。
为了独立学习的必要,本人独立提供一份input_data.py,供读者自行使用:🔗

Yann LeCun's MNIST page 也提供了训练集与测试集数据的下载。(下载以后放到指定的目录中,再在py代码调用的时候指定放置数据的目录)

文件 内容
train-images-idx3-ubyte.gz 训练集图片 - 55000 张 训练图片, 5000 张 验证图片
train-labels-idx1-ubyte.gz 训练集图片对应的数字标签
t10k-images-idx3-ubyte.gz 测试集图片 - 10000 张 图片
t10k-labels-idx1-ubyte.gz 测试集图片对应的数字标签

解压 与 重构

这些文件本身并没有使用标准的图片格式储存,需要使用input_data.py文件中extract_images()extract_labels()函数来手动解压。

我们在这里使用自己整理的项目,测试下载的数据

假定:input_data.py 位于 mnist包 中;下载的数据位于 mnist-datasets目录中;运行下列代码:

from mnist import input_data

mnist = input_data.read_data_sets("mnist-datasets/", one_hot=True)
# 每个子集都由两部分组成:图片部分(images)和标签部分(labels), 
# 访问MNIST训练集
print(mnist.train.images.shape)
print(mnist.train.labels.shape)
# 访问MNIST测试集
print(mnist.test.images.shape)
print(mnist.test.labels.shape)
# 访问MNIST验证集
print(mnist.validation.images.shape)
print(mnist.validation.labels.shape)
#       output
#           (55000, 784)
#           (55000, 10)
#           (10000, 784)
#           (10000, 10)
#           (5000, 784)
#           (5000, 10)

图片数据将被解压成2维的tensor:[image index, pixel index] 其中每一项表示某一图片中特定像素的强度值, 范围从 [0, 255][-0.5, 0.5]

"image index"代表数据集中图片的编号, 从0到数据集的上限值。
"pixel index"代表该图片中像素点得个数, 从0到图片的像素上限值。

train-*开头的文件中包括60000个样本,其中分割出55000个样本作为训练集,其余的5000个样本作为验证集。因为所有数据集中28x28像素的灰度图片的尺寸为784,所以训练集输出的tensor格式为[55000, 784]

数字标签数据被解压称1维的tensor: [image index],它定义了每个样本数值的类别分类。对于训练集的标签来说,这个数据规模就是:[55000]
如果想在spyder编辑器中查看具体数值,可以将这些数据提取为变量来查看,如:

val_data=mnist.validation.images
val_label=mnist.validation.labels
print(val_data)
print(val_label)

数据集 对象

底层的源码将会执行下载、解压、重构图片和标签数据来组成以下的数据集对象:

数据集 目的
data_sets.train 55000 组 图片和标签, 用于训练。
data_sets.validation 5000 组 图片和标签, 用于迭代验证训练的准确性。
data_sets.test 10000 组 图片和标签, 用于最终测试训练的准确性。

执行read_data_sets()函数将会返回一个DataSet实例,其中包含了以上三个数据集。函数DataSet.next_batch()是用于获取以batch_size为大小的一个元组,其中包含了一组图片和标签,该元组会被用于当前的TensorFlow运算会话中。

# images_feed, labels_feed = mnist.next_batch(FLAGS.batch_size)
# 例如?(有点奇怪,因为接口调用不太一样,先不管,有机会再来搞清楚)
images_feed, labels_feed = mnist.train.next_batch(100)
print(images_feed)
print(labels_feed)

MNIST数据集

下载下来的数据集被分成两部分:60000行的训练数据集(mnist.train)和10000行的测试数据集(mnist.test)。
这样的切分很重要,在机器学习模型设计时必须有一个单独的测试数据集不用于训练而是用来评估这个模型的性能,从而更加容易把设计的模型推广到其他数据集上(泛化)。
每一张图片包含28像素 x 28像素。我们可以用一个数字数组来表示这张图片:

img

我们把这个数组展开成一个向量,长度是 28x28 = 784。如何展开这个数组(数字间的顺序)不重要,只要保持各个图片采用相同的方式展开。
从这个角度来看,MNIST数据集的图片就是在784维向量空间里面的点, 并且拥有比较复杂的结构 (提醒: 此类数据的可视化是计算密集型的)。

展平图片的数字数组会丢失图片的二维结构信息。这显然是不理想的,最优秀的计算机视觉方法会挖掘并利用这些结构信息,我们会在后续教程中介绍。但是在这个教程中我们忽略这些结构,所介绍的简单数学模型:softmax回归(softmax regression),不会利用这些结构信息。

因此,在MNIST训练数据集中,mnist.train.images 是一个形状为 [60000, 784] 的张量,第一个维度数字用来索引图片,第二个维度数字用来索引每张图片中的像素点。在此张量里的每一个元素,都表示某张图片里的某个像素的强度值,值介于0和1之间。

img

相对应的MNIST数据集的标签是介于0到9的数字,用来描述给定图片里表示的数字。为了用于这个教程,我们使标签数据是"one-hot(独热编码) vectors"。

独热编码:代表存储数据的有效位中,只有一位为1,其余都为0;在这里代表一个one-hot向量除了某一位的数字是1以外其余各维度数字都是0。

所以在此教程中,数字n将表示成一个只有在第n维度(从0开始)数字为1的10维向量。

比如,标签0将表示成([1,0,0,0,0,0,0,0,0,0,0])。因此, mnist.train.labels 是一个 [60000, 10] 的数字矩阵。

img

理解了这些数据集分析概念以后,现在,我们准备好可以开始构建我们的模型。

posted @ 2020-01-04 20:12  schips  阅读(443)  评论(0编辑  收藏  举报