在上一个案例的基础上,利用相似的格式,训练识别MINST数据集的格式。
http://www.jianshu.com/p/73d6051bd611
其实训练很简单,就是用机器学习来识别手写数字。数据分为6w行的训练集和1w行的测试集。
每张图片包含28x28个像素,所以数组是[60000,784]。 像素的强度在0-1之间。
根据识别概率,将每次识别的概率第一名(比如某个数字,认为6的是0.7,认为是8的0.3,那就取6)与真实结果对比,得到准确率。
代码如下:
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
#载入数据集
mnist = input_data.read_data_sets("MNIST_data",one_hot=True)
#每个批次的大小.
batch_size = 10
#计算一共有多少个批次
n_batch = mnist.train.num_examples // batch_size
#定义两个placeholder
x = tf.placeholder(tf.float32,[None,784])
y = tf.placeholder(tf.float32,[None,10])
keep_prob = tf.placeholder(tf.float32)
#定义神经网络中间层
Weights_L1 = tf.Variable(tf.random_normal([784,10000]))
biases_L1 = tf.Variable(tf.zeros([10,10000]))
Wx_plus_b_L1 = tf.matmul(x,Weight_L1) + biases_L1
L1 = tf.nn.tanh(Wx_plus_b_L1)
#创建神经网络输出层
W = tf.Variable(tf.zeros([784,10]))
b = tf.Variable(tf.zeros([10]))
prediction = tf.nn.softmax(tf.matmul(x,W)+b)
。
预测与真实标签比较。这里可以用两类函数,二次代价或者交叉熵。
如果输出神经元是线性的,那么二次代价函数就是一种合适的选择。如果输出神经元是S函数,那么比较适合交叉熵代价函数。
实际运行结果都差不多,不过交叉熵快一些。
#二次代价函数
#loss = tf.reduce_mean(tf.square(y-prediction))
#交叉熵函数
loss = tf .reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels = y,logits = prediciton))
#使用梯度下降法
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(loss)
#初始化变量
init = tf.global_variables_initializer()
#结果存放在一个布尔型列表中
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))#argmax返回一维张量中最大的值所在的位置
#求准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
with tf.Session() as sess:
sess.run(init)
for epoch in range(5000):
for batch in range(n_batch):
batch_xs,batch_ys = mnist.train.next_batch(batch_size)
sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys})
acc = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels})
print("Iter " + str(epoch) + ",Testing Accuracy " + str(acc))
输出结果是0.93左右。还是没有达到老师要求的0.95,下一篇文章换MLP或者relu激活函数(然而还不会做!)
参考文章
http://s1nh.com/post/Tensorflow-MNIST/
https://zhuanlan.zhihu.com/p/25110150