深度学习入门:基于 Python 的理论与实现 (22):神经网络 3.6.1

阅读数:68 2019 年 11 月 13 日 15:23

深度学习入门:基于Python的理论与实现(22):神经网络 3.6.1

内容简介
本书是深度学习真正意义上的入门书,深入浅出地剖析了深度学习的原理和相关技术。书中使用 Python3,尽量不依赖外部库或工具,从基本的数学知识出发,带领读者从零创建一个经典的深度学习网络,使读者在此过程中逐步理解深度学习。书中不仅介绍了深度学习和神经网络的概念、特征等基础知识,对误差反向传播法、卷积神经网络等也有深入讲解,此外还介绍了深度学习相关的实用技巧,自动驾驶、图像生成、强化学习等方面的应用,以及为什么加深层可以提高识别精度等疑难的问题。
本书适合深度学习初学者阅读,也可作为高校教材使用。

(MNIST 数据集)

这里使用的数据集是 MNIST 手写数字图像集。MNIST 是机器学习领域最有名的数据集之一,被应用于从简单的实验到发表的论文研究等各种场合。实际上,在阅读图像识别或机器学习的论文时,MNIST 数据集经常作为实验用的数据出现。

MNIST 数据集是由 0 到 9 的数字图像构成的(图 3-24)。训练图像有 6 万张,测试图像有 1 万张,这些图像可以用于学习和推理。MNIST 数据集的一般使用方法是,先用训练图像进行学习,再用学习到的模型度量能在多大程度上对测试图像进行正确的分类。

深度学习入门:基于Python的理论与实现(22):神经网络 3.6.1

图 3-24 MNIST 图像数据集的例子

MNIST 的图像数据是 28 像素 × 28 像素的灰度图像(1 通道),各个像素的取值在 0 到 255 之间。每个图像数据都相应地标有“7”“2”“1”等标签。

本书提供了便利的 Python 脚本 mnist.py,该脚本支持从下载 MNIST 数据集到将这些数据转换成 NumPy 数组等处理(mnist.pydataset 目录下)。使用 mnist.py 时,当前目录必须是 ch01ch02ch03、…、ch08 目录中的一个。使用 mnist.py 中的 load_mnist() 函数,就可以按下述方式轻松读入 MNIST 数据。

复制代码
import sys, os
sys.path.append(os.pardir) # 为了导入父目录中的文件而进行的设定
from dataset.mnist import load_mnist
# 第一次调用会花费几分钟……
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True,
normalize=False)
# 输出各个数据的形状
print(x_train.shape) # (60000, 784)
print(t_train.shape) # (60000,)
print(x_test.shape) # (10000, 784)
print(t_test.shape) # (10000,)

首先,为了导入父目录中的文件,进行相应的设定 1。然后,导入 dataset/mnist.py 中的 load_mnist 函数。最后,使用 load_mnist 函数,读入 MNIST 数据集。第一次调用 load_mnist 函数时,因为要下载 MNIST 数据集,所以需要接入网络。第 2 次及以后的调用只需读入保存在本地的文件(pickle 文件)即可,因此处理所需的时间非常短。

1 观察本书源代码可知,上述代码在 mnist_show.py 文件中。mnist_show.py 文件的当前目录是 ch03,但包含 load_mnist() 函数的 mnist.py 文件在 dataset 目录下。因此,mnist_show.py 文件不能跨目录直接导入 mnist.py 文件。sys.path.append(os.pardir) 语句实际上是把父目录 deep-learning-from-scratch 加入到 sys.path(Python 的搜索模块的路径集)中,从而可以导入 deep-learning-from-scratch 下的任何目录(包括 dataset 目录)中的任何文件。——译者注

用来读入 MNIST 图像的文件在本书提供的源代码的 dataset 目录下。并且,我们假定了这个 MNIST 数据集只能从 ch01ch02ch03、…、ch08 目录中使用,因此,使用时需要从父目录(dataset 目录)中导入文件,为此需要添加 sys.path.append(os.pardir) 语句。

load_mnist 函数以“( 训练图像, 训练标签 ),( 测试图像, 测试标签 )”的形式返回读入的 MNIST 数据。此外,还可以像 load_mnist(normalize=True, flatten=True, one_hot_label=False) 这样,设置 3 个参数。第 1 个参数 normalize 设置是否将输入图像正规化为 0.0~1.0 的值。如果将该参数设置为 False,则输入图像的像素会保持原来的 0~255。第 2 个参数 flatten 设置是否展开输入图像(变成一维数组)。如果将该参数设置为 False,则输入图像为 1 × 28 × 28 的三维数组;若设置为 True,则输入图像会保存为由 784 个元素构成的一维数组。第 3 个参数 one_hot_label 设置是否将标签保存为 one-hot 表示(one-hot representation)。one-hot 表示是仅正确解标签为 1,其余皆为 0 的数组,就像 [0,0,1,0,0,0,0,0,0,0] 这样。当 one_hot_labelFalse 时,只是像 72 这样简单保存正确解标签;当 one_hot_labelTrue 时,标签则保存为 one-hot 表示。

Python 有 pickle 这个便利的功能。这个功能可以将程序运行中的对象保存为文件。如果加载保存过的 pickle 文件,可以立刻复原之前程序运行中的对象。用于读入 MNIST 数据集的 load_mnist() 函数内部也使用了 pickle 功能(在第 2 次及以后读入时)。利用 pickle 功能,可以高效地完成 MNIST 数据的准备工作。

现在,我们试着显示 MNIST 图像,同时也确认一下数据。图像的显示使用 PIL(Python Image Library)模块。执行下述代码后,训练图像的第一张就会显示出来,如图 3-25 所示(源代码在 ch03/mnist_show.py 中)。

复制代码
import sys, os
sys.path.append(os.pardir)
import numpy as np
from dataset.mnist import load_mnist
from PIL import Image
def img_show(img):
pil_img = Image.fromarray(np.uint8(img))
pil_img.show()
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=True,
normalize=False)
img = x_train[0]
label = t_train[0]
print(label) # 5
print(img.shape) # (784,)
img = img.reshape(28, 28) # 把图像的形状变成原来的尺寸
print(img.shape) # (28, 28)
img_show(img)

这里需要注意的是,flatten=True 时读入的图像是以一列(一维)NumPy 数组的形式保存的。因此,显示图像时,需要把它变为原来的 28 像素 × 28 像素的形状。可以通过 reshape() 方法的参数指定期望的形状,更改 NumPy 数组的形状。此外,还需要把保存为 NumPy 数组的图像数据转换为 PIL 用的数据对象,这个转换处理由 Image.fromarray() 来完成。

深度学习入门:基于Python的理论与实现(22):神经网络 3.6.1

** 图 3-25 显示 MNIST 图像

评论

发布