深度学习入门—手写文字识别机
和求解机器学习问题的步骤(分成学习和推理两个阶段进行)一样, 使用神经网络解决问题时,也需要首先使用训练数据(学习数据)进 行权重参数的学习;进行推理时,使用刚才学习到的参数,对输入 数据进行分类。
¶mnist数据集
MNIST数据集是由0到9的数字图像构成的。训练图像有6万张, 测试图像有1万张,这些图像可以用于学习和推理。MNIST数据集的一般使用方法是,先用训练图像进行学习,再用学习到的模型度量能在多大程度上对测试图像进行正确的分类。
MNIST的图像数据是28像素 × 28像素的灰度图像(1通道),各个像素 的取值在0到255之间。每个图像数据都相应地标有“7”“2”“1”等标签。
下面代码简单地读出数据集
# coding: utf-8 |
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设置是否将标签保存为onehot表示(one-hotrepresentation)。
normalize
: 将图像的像素值正规化为0.0~1.0
one_hot_label
:one_hot_label
为True
的情况下,标签作为one-hot
数组返回
one-hot
数组是指[0,0,1,0,0,0,0,0,0,0]
这样的数组
flatten
: 是否将图像展开为一维数组Returns
导入数据集完成后,开始实现神经网络地推理处理。可以看出,每个图像有784个像素点,将每个图像作为一个输入点,也就是作为一个输入层地神经元,那么输入层的神经元一共有784个(只讨论一张图片),而输出层的为十个数字,分别表示该图片是0~9的概率,此外该神经网络还有两个中间层(隐藏层)第一个隐藏层有50个神经元,第二个隐藏层有100个神经元。其实这50和100可以设置成其他值。
¶下面定义三个函数
def get_data(): |
get_data
函数通过load_mnist
读取数据集并返回测试数据集。Init_network
函数读取pkl
文件并将其反序列化,这个文件中以字典变量的形式保存了权重和偏置参数predic
函数对输入进行分类
¶正规化/预处理
load_mnist
函数的参数normalize
设置成了True
。将normalize
设置成True
后,函数内部会进行转换,将图像的各个像 素值除以255,使得数据的值在0.0~1.0的范围内。像这样把数据限定到某 个范围内的处理称为正规化(normalization
)。
此外,对神经网络的输入数据进行某种既定的转换称为预处理(pre-processing
)。这里,作为对输入图像的 一种预处理,我们进行了正规化。
补充:序列化
pickle
提供了一个简单的持久化功能。可以将对象以文件的形式存放在磁盘上。pickle
模块只能在python
中使用,python
中几乎所有的数据类型(列表,字典,集合,类等)都可以用pickle来序列化,pickle.dump(obj, file[, protocol])
序列化对象,并将结果数据流写入到文件对象中。
参数protocol
是序列化模式,默认值为0,表示以文本的形式序列化。protocol
的值还可以是1或2,表示以二进制的形式序列化。
pickle.load(file)
反序列化对象。将文件中的数据解析为一个Python
对象。
现在利用这三个函数进行神经网络的推演
x, t = get_data() |
首先获得MNIST数据集,生成网络。接着,用for语句逐一取出保存 在x中的图像数据,用predict()
函数进行分类。predict()
函数以NumPy
数 组的形式输出各个标签对应的概率。比如输出[0.1, 0.3, 0.2, ..., 0.04]
的 数组,该数组表示“0”的概率为0.1,“1”的概率为0.3
用np.argmax(x)函数取出数组中的最大值的索引
比较神经网络所预 测的答案和正确解标签,将回答正确的概率作为识别精度。
输出结果Accuracy:0.9352
¶批处理
上面的代码中,每次for循环处理处理一张图片的数据,单张图片的神经网络推处理过程如下
输入一个由784个元素构成的一维数组,输出有10个元素的一维数组,这只是输入一张图片的处理流程,如果考虑多张图片打包输入,比如用predict()
函数一次性打包处理100张图片,这时可以把x的形状改为100X784,神经网络推理过程如下
输入数据的形状为 100 × 784,输出数据的形状为 100 × 10。这表示输入的100张图像的结果被一次性输出了。比如x[0]
和y[0]
中保存了第0张图像及其推理结果,x[1]
和y[1]
中保存了第1张图像及 其推理结果。
这种打包式的输入数据称为批(batch)。
x, t = get_data() |
首先是range()
函数。range()
函数若 指定为range(start, end)
,则会生成一个由start
到end-1
之间的整数构成的 列表。若像range(start, end, step)
这样指定3个整数,则生成的列表中的 下一个元素会增加step
指定的值
¶本章所学的内容
- 神经网络中的激活函数使用平滑变化的sigmoid函数或ReLU函数。
- 通过巧妙地使用NumPy多维数组,可以高效地实现神经网络。
- 机器学习的问题大体上可以分为回归问题和分类问题。
- 关于输出层的激活函数,回归问题中一般用恒等函数,分类问题中 一般用softmax函数。
- 分类问题中,输出层的神经元的数量设置为要分类的类别数。
- 输入数据的集合称为批。通过以批为单位进行推理处理,能够实现 高速的运算。
神经网络和上一章的感知机在信号的按层传递这一点上是相同的,但是,向下一个神经元发送信号时, 改变信号的激活函数有很大差异。神经网络中使用的是平滑变化的sigmoid 函数,而感知机中使用的是信号急剧变化的阶跃函数。这个差异对于神经网 络的学习非常重要
注:本文为斋藤康毅的《深度学习入门:基于Python的理论与实现》片段摘抄与学习笔记
