MNIST手写数字的识别
本节将学习机器学习的分类开发应用,即MNIST手写数字的识别。对此,我们通过建立一个两层神经网络的模型来用于识别图片里面的数字。
MNIST数据集介绍
MNIST是一个非常有名的手写体数字识别数据集,由60000个训练样本和10000个测试样本组成,每个样本都是一张28像素 × 28像素的灰度图像(1通道),各个像素的取值在0到255之间。每个图像数据都相应地标有“1”“2”“3”等标签,如下图所示。
更多MNIST数据集的详细介绍可参考:MNIST数据集介绍
- 下载数据集:
MNIST数据集下载网址:MNIST数据集下载
下载到本地后该数据集共有四个压缩文件,如下图所示,可根据需要移动到指定路径。
当然,也可以通过 tensorflow 来自动下载和安装这个数据集。
下载以后的数据集包括:
- Training set images[训练图集]: train-images-idx3-ubyte.gz (包含 60000 个样本)
- Training set labels[训练标签集]: train-labels-idx1-ubyte.gz (包含 60000 个标签)
- Test set images[测试图集]: t10k-images-idx3-ubyte.gz (包含 10000 个样本)
- Test set labels[测试标签集]: t10k-labels-idx1-ubyte.gz (包含 10000 个标签)
至此,数据的准备工作已完成。
环境搭建
-
-
环境说明
- 电脑系统:win10
- CPU: i5
-
显卡:
-
-
本文采用
- python 3.5.2 / anaconda 4.2.0
- tensorflow 1.2.1(CPU版本)
我们将在anaconda中集合的 jupyter notebook 中进行模型的训练。
模型训练
1.数据读取
tensorflow 提供了数据集读取的方法:
import tensorflow as tf
import tensorflow.examples.tutorials.mnist.input_data as input_data
mnist = input_data.read_data_sets("xxx", one_hot = True)
其中 “xxx” 是你存放数据集的路径,可通过数据集属性进行查看。
[tips]: 这个路径要自己手动输入才可以,不要忘了将路径中的’ \ ‘更换为’ / '。
在 jupyter 中运行之后结果为:
input_data.read_data_sets()
函数里面有两个参数:第一个为数据集所放的路径;第二个参数是one_hot (独热编码),设置为True,当然也可以把它设置为False,这两种情况下读进来的标签的数据格式是不一样的。当one_hot设置为True时,则对应的位置的值为1,其余都是0。
如果这个数字为3,就让下标为3的地方值为1,其他都为0。如果是8,就让下标为8的地方值为1,其他都为0。
[tips]: 如果是第一次读取MNIST数据集,在指定目录下不存在这个文件,那么它会自动去网上下载对应的文件,不过需要一定的等待时间;如果数据集已经存在了,那么它就会直接读取数据,速度会比较快。
2.模型构建
-
定义全连接层函数
不管有多少层,对于每一层的定义都可以通过这个函数来解决。
def fcn_layer(inputs,
input_dim,
output_dim,
activation=None):
W = tf.Variable(tf.truncated_normal([input_dim, output_dim], stddev=0.1))
b = tf.Variable(tf.zeros([output_dim]))
XWb = tf.matmul(inputs,W) + b
if activation is None:
outputs = XWb
else:
outputs = activation(XWb)
return outputs
定义了一个函数 fcn_layer(),它有四个参数:
参数 | 解释 |
---|---|
inputs | 这一层网络的输入数据 |
input_dim | 输入神经元的数量 |
output_dim | 输出神经元的数量 |
activation | 激活函数(缺省值为None) |
-
权重与偏置项定义:
-
- 权值W:它是TensorFlow的一个变量(tf.Variable),它的形状为输入的神经元数量以及输出的神经元数量,以截断的正态分布随机数来初始化,它的标准差为0.1。
-
- 偏置项b:以0来初始化偏置项b,它的形状为输出的神经元数量。
- 定义待输入数据的占位符
x = tf.placeholder(tf.float32, [None, 784],name = 'X' )
y = tf.placeholder(