距离上一次写tensorflow学习笔记已经有一段的时间了,原因不是期间中断了学习,而是tensorflow的学习曲线说实话还是相对陡峭的,如果没有对框架有自己个人的部分理解,难以输出有用的学习笔记(对其他学习者和自己)。但是这一期间我还是更新了几篇在学习tensorlfow以及它对应的可视化遇到的一些问题,以及对应的解决方案。具体可以看看我的其他文章,相信这也是这些问题的最新解决方案,对你或许有所帮助。
本文我将分享tensorflow最入门的mnist数据集的应用:手写数字的识别。这一部分我是将相关的知识都学习以后才分享的,但是这一次只是分享最简单的系统识别方案,所谓简单,就是实现的系统最后的准确率为92%,不带可视化,实战中少量的知识方便理解。
本文将分为这几个部分:
- 数据部分
- 代码部分(附有详细解释)
- 你需要做到的部分
一 、数据部分
先来介绍我们使用的MNIST数据集(当然数据不需要你理解,甚至不用管它,你只先需要知道有这样的一回事):
MNIST数据集是NIST数据集的子集,包含下面的四个文件:
- train-labels-idx1-ubyte.gz :训练集标记文件
- train-images-idx3-ubyte.gz:训练集图片文件
- t10k-labels-idx1-ubyte.gz :测试集标记文件
- t10k-images-idx3-ubyte.gz :测试集图片文件
可以看到,整个MNIST数据分为两部分:训练集与测试集
字面意思理解就是:用于训练模型的数据与用于测试模型的数据。
这一部分你需要理解的是:
- 每张图片是28x28像素的格式,可以理解为一张28x28的二维表,每一个像素由0-1的数字组成来说明它的颜色深浅(图片为黑白)也就是说,每一张图片表示为数据的形式: 一维:784 , 二维28x28
理解了它是什么,并不代表理解了它为什么是这样,这个暂时难以理解,任何事情都需要一点时间。
二、 代码部分
代码部分我会分为:模块化解释 与 代码集合(注意: 代码中所有单行注释都是解释下一行的代码)。
加载MNIST数据
tensorflow已经很贴心的将MNIST数据加入了源码之中,这一部分代码如下:
#下面这一句就是导入MNIST数据集
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
#加载上面下载的数据“MNIST”指的是我们项目所在的路径
mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
one_hot 标记是值一个长度为n的数组,只有一个元素是1.0,其余元素是0.0,使用one_Hot的直接原因是,我们使用0-9个类别的输出层是softmax层,它的输出是一个概率分布,要求输入的标记也应该以概率分布的形式出现,进而可以计算交叉熵 。
构建回归模型
直接上代码:
#定义回归模型
x = tf.placeholder(tf.float32,[None,784])
w = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
y = tf.matmul(x,w) + b
#定义损失函数和优化器
y_ = tf.placeholder(tf.float32,[None,10])#输入的真是值的占位符
#我们用tf.nn.softmax_cross_entropy_with_logits来计算预测值与真是值y_的差值,并取均值
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=y,labels=y_))
#可以看作损失函数,损失函数最小,预测值就越接近真实值
#注意:tf.nn.softmax_cross_entropy_with_logits在tensorflow1.0以上的版本需要这样处理数据:logits=y, labels=y_
#采用SGD(tensorflow封装好的梯度下降法)作为优化器,学习率为0.5(也就是参数改变的快慢)
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
说到底,我们训练的目的就是找到一个合适的weight权值以及biases(不管是一维数据还是二维数据)。所以,你可以注意到w 与 b 都是Variable ,而我们需要输入的x 与 y_(注意y_与y不同着重区分)是placeholder(英文意思:占位符)
构建评估模型
模型构建完成后我们需要一定的评估系统来测试模型的准确率
#评估训练好的模型
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1))#计算预测值和真实值
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))#布尔型转化为浮点数,并且取平均值,得到准确率
#计算模型在测试集上的准确率
开始训练模型
我们已经设置好了所需要的所有模型,tensorflow中所有的变量都需要进行初始化,所以,在训练之前我们需要开启会话并且初始化我们创建的变量。
#这里使用InteractiveSession()来创建交互式上下文的tensorflow会话
#与常规会话不同的是,交互式的会话称为默认会话
#方法(如tf.Tensor.eval和tf.Operation.run()都可以使用改会话来运行操作(op))
sess = tf.InteractiveSession()
init = tf.global_variables_initializer()
sess.run(init)
然后循环训练模型1000次每10次输出模型训练结果,每次循环抓取训练数据中100个数据点,代替之前的占位符。
#Train
for i in range(1001):
bath_xs,bath_ys = mnist.train.next_batch(100)
sess.run(train_step,feed_dict={x:bath_xs,y_:bath_ys})
if i %10 == 0:
acc = sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels})
print("Iter " + str(i) + ",Testing Accuracy " + str(acc))
print('训练完成')
以上就是代码部分所有的内容,接下来我会将代码部分汇总,确保各位复制粘贴以后可以运行参考,上代码:
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
#加载数据
mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
#定义回归模型
x = tf.placeholder(tf.float32,[None,784])
w = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
y = tf.matmul(x,w) + b
#定义损失函数和优化器
y_ = tf.placeholder(tf.float32,[None,10])#输入的真是值的占位符
#我们用tf.nn.softmax_cross_entropy_with_logits来计算预测值与真是值y_的差值,并取均值
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=y,labels=y_))#可以看作损失函数
#注意:tf.nn.softmax_cross_entropy_with_logits在1.0以上的版本需要这样处理数据:logits=y,labels=y_
#采用SGD作为优化器
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
#这里使用InteractiveSession()来创建交互式上下文的tensorflow会话
#与常规会话不同的是,交互式的会话称为默认会话
#方法(如tf.Tensor.eval和tf.Operation.run()都可以使用改会话来运行操作(op))
sess = tf.InteractiveSession()
#评估训练好的模型
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(y_,1))#计算预测值和真实值
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))#布尔型转化为浮点数,并且取平均值,得到准确率
#计算模型在测试集上的准确率
init = tf.global_variables_initializer()
sess.run(init)
#Train
for i in range(1001):
bath_xs,bath_ys = mnist.train.next_batch(100)
sess.run(train_step,feed_dict={x:bath_xs,y_:bath_ys})
if i %10 == 0:
acc = sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels})
print("Iter " + str(i) + ",Testing Accuracy " + str(acc))
print('训练完成')
三、 你需要做到的部分
注意,如果你无法理解这里面的一些点。没有关系,正如我上面说的tensorflow的学习曲线非常陡峭。所以,如果你能够做到一下几点就非常好了,剩下的不能理解的,正如我所说的,不要放弃,然后交给时间。
- 保证代码能在你的机器上正常运行
- 知道MNIST数据集是怎么一回事
- 对tensorflow保持信心,不懂的点立即去问(面向google、csdn、github的学习方法)。
最后,我希望大家有问题可以私信问我,我会很愿意帮你解答,毕竟,这就是在以一种很有效率的方式帮助我的学习,加深我对它的理解。
希望本文对你有所帮助,接下来我会更新加入tensorboard可视化的文章以及优化部分模块,将识别准确率提升到99%以上的文章。