Mnist数据集是数万张手写的由0到9的数字,并且经过了预处理,表现为黑白色的大小为28×28的图片;其中由白到黑的渐变程度被表现为数字上的从0到1,即某点的颜色越接近纯黑色,数值越接近1。
图一
下面进入代码部分(笔者系统为win10):
import tensorflow as tf #导入tensorflowprint(tf.__version__) #导入成功后可以用此代码查看tensorflow的版本
1. 将Mnist数据集导入:
from tensorflow.examples.tutorials.mnist import input_datamnist = input_data.read_data_sets('./downloads/', one_hot=True)#若电脑上不存在mnist数据集的压缩文件,在运行如上代码后,会自动下载在你指定的文件夹下#笔者指定的文件夹名为downloads,若文件夹不存在也会自动创建。
使用上述代码导入Mnist的话,可能会出现大量的WARNING,这似乎是由于Tensorflow的版本等原因导致的,但数据集仍然可以成功导入。
另外,笔者在第一次使用上述代码时,出现了
“No module named 'tensorflow.examples.tutorials'"这样的错误,这是因为下载的tensorflow下的examples文件夹内不存在tutorials文件夹及其所含内容。具体解决方法可以在CSDN上自行搜索。
可以使用如下代码对数据集中的训练集部分(train)进行查看:
print(mnist.train.images.shape) print(mnist.train.labels.shape)x = mnist.train.imagesy = mnist.train.labels #将训练集图片和标签分别赋值给x和y
运行后分别得到(55000,784) 和 (55000,10)两个结果。其中55000分别代表训练集中共有55000个图片和55000个对应的手写数字的准确值(注:正常情况下似乎应该有60000个,但是由于上面提到的问题,可能我所下载到的数据集内只有55000个);784=28×28,上面提到该数据集利用由0到1的小数来作为特征对手写数字进行描述,因此每张图片都有784个特征数值,表现为1行、784列的行列式(或numpy数组);同样的,10代表1行、10列的行列式,为准确值的标签。
2. 训练模型的配置:
model = tf.keras.Sequential() #建立模型框架model.add(tf.keras.layers.Dense(10, input_shape=(784,))) #在模型框架中添加一个Dense层#Dense层即为y = wx+b,其中10为输出函数的维数,784为输入函数的维数print(model.weights) #查看w和bmodel.summary() #使用这行代码可以对w偶们搭建的模型的各层进行概览
Sequential(顺序模型)为Keras内包含的模型之一。
图二
图二为查看w和b所得的结果。可以看出,w的shape为784行10列的行列式,b的shape为1行10列的行列式。
图三
图三为我们搭建的以sequential为基础的模型概览,其中包含一个Dense层,None处代表的是数据的数量;10为输出数据的维数;Param为参数数量,7850=(784×10)+(1×10)。
#利用compile的方式配置学习过程# optimizer为优化器,用于找到最优解的计算方法,adam这个算法为常用方法之一。# loss为损失函数,mse为均方误差。另外还有mae(平均绝对误差)、msle(均方对数误差)等
model.compile(optimizer='adam', loss='mse')
train_ = model.fit(x, y, epochs=10) #利用fit的方式以x和y为基础进行迭代,epochs为训练次数
4. 数据预测及准确率
model.predict(x) #利用模型对x进行预测 array = model.predict(x) #将预测赋值给变量array
这里对标签如何体现手写数字的正确值作解释:
以第一个标签为例,输入下列代码,该代码得到的是第一个标签
print(mnist.train.labels[0])
可以得到 [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.] 这样一个结果,该标签中的最大值显而易见为1;而最大值1在这串数字中的索引为7,也就是说这个手写数字(图一)为7。准确率的计算就是利用了准确标签与预测标签的最大值索引。
#tf.equal(x, y)可以检测x和y是否相等,相等则会返回一个True#tf.cast(x, dtype, name=None)可以对x进行数据转换,True会转换为1,False会转换为0#tf.reduce_mean()可以求均值right_pred = tf.equal(tf.argmax(array, 1), tf.argmax(y, 1))accu_rate = tf.reduce_mean(tf.cast(right_pred, tf.float32))#预测正确会得到1,错误会得到0,将所有的0和1相加再求均值,得到的就是准确率print(accu_pred)
测试集的图片和标签分别为mnist.test.images和mnist.test.labels,可以分别赋值并按照上述方法进行预测。
另外,损失函数的不同,结果的正确率一般也不同;比如在这里,使用msle的正确率大约为64%,而使用mse的正确率约为85%;但是在使用mse预测之后的基础上,将mse改为msle再次 预测,正确率可以提升到92%左右。
5. 数据集的可视化
import matplotlib.pyplot as pltimport osos.environ['TF_CPP_MIN_LOG_LEVEL']='2'import numpy as npimage = mnist.train.images[0] # 中括号内的数字表示第几张图片,0为第一张print('true label: ', tf.argmax(y[0])) # 打印真实值print(tf.argmax(array[0])) # 打印预测值image = image.reshape(28, 28)plt.imshow(image,cmap='binary')plt.show()