tensorflow初学者日记3 手写体数字的识别

一、MNIST数据集

1、MNIST数据集的标签

是介于0-9的数字,把标签转化为one-hot-vectors,指除了一个数字是1之外其它的数字均为0,比如标签3([0,0,0,1,0,0,0,0,0])

每张图片的相素点为28*28,按相素点,将每一个相素点转化成0-1的数字,最黑的地方为1,白色的地方为0。将照片数组转化成向量。所以大小为784,即要构建神经网络的话,有784个输入,10个输出

2、Softmax函数

又称归一化指数函数。它是二分类函数sigmoid在多分类上的推广,目的是将多分类的结果以概率的形式展现出来。在最后选取输出结点的时候,我们就可以选取概率最大(也就是值对应最大的)结点,作为我们的预测目标!

之所以选择Softmax,很大程度是因为Softmax中使用了指数,这样可以让大的值更大,让小的更小,增加了区分对比度,学习效率更高。第二个是因为softmax是连续可导的,消除了拐点,这个特性在机器学习的梯度下降法等地方非常必要。

二、实战

分析思路

  • 1、获取mnist数据集,对应的图片转化成一维,对应的标签转换成另一维度,获得数据测试集、训练集
  • 2、因为训练集太大了,全部用来训练的话非常浪费,考虑一下随机抽取其中的部分数据进行训练
  • 3、构建神经网络,输入x为照片,输出y为标签,定义偏置值和权值,激活函数得到预测值,最小化代价函数,训练得到最小化代价函数
  • 4、评估模型,用训练好的神经网络来处理测试集,对比结果得到正确率,打印显示正确率

涉及知识

1、下载下来的数据集被分成两部分:60000行的训练数据集(mnist.train)和10000行的测试数据集(mnist.test)

2、每一个MNIST数据单元有两部分组成:一张包含手写数字的图片和一个对应的标签。把这些图片设为“xs”,把这些标签设为“ys”。训练数据集和测试数据集都包含xs和ys,比如训练数据集的图片是 mnist.train.images ,训练数据集的标签是 mnist.train.labels。

3、每一张图片包含28X28个像素点。我们把这个数组展开成一个向量,长度是 28x28 = 784,因此,在MNIST训练数据集中,mnist.train.images 是一个形状为 [60000, 784] 的张量,第一个维度数字用来索引图片,第二个维度数字用来索引每张图片中的像素点。在此张量里的每一个元素,都表示某张图片里的某个像素的强度值,值介于0和1之间。

4、相对应的MNIST数据集的标签是介于0到9的数字,用来描述给定图片里表示的数字。为了用于这个教程,我们使标签数据是"one-hot vectors"。 一个one-hot向量除了某一位的数字是1以外其余各维度数字都是0。所以在此教程中,数字n将表示成一个只有在第n维度(从0开始)数字为1的10维向量。比如,标签0将表示成([1,0,0,0,0,0,0,0,0,0,0])。因此, mnist.train.labels 是一个 [60000, 10] 的数字矩阵

5、在机器学习,我们通常定义指标来表示一个模型是坏的,这个指标称为成本(cost)或损失(loss),然后尽量最小化这个指标。

6、找出那些预测正确的标签。tf.argmax 是一个非常有用的函数,它能给出某个tensor对象在某一维上的其数据最大值所在的索引值。由于标签向量是由0,1组成,因此最大值1所在的索引位置就是类别标签,比如tf.argmax(y,1)返回的是模型对于任一输入x预测到的标签值,而 tf.argmax(y_,1) 代表正确的标签,我们可以用 tf.equal 来检测我们的预测是否真实标签匹配(索引位置一样表示匹配)。


import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data    #一份python源代码,用于自动下载和安装mnist数据集
mnist = input_data.read_data_sets('MNIST_data',one_hot = True)
batch_size = 100
n_batch = mnist.train.num_examples // batch_size

x = tf.placeholder(tf.float32,[None,784])			#在TensorFlow运行计算时输入值,能够输入任意数量的MNIST图像,每一张图展平成784维的向量。用2维的浮点数张量来表示这些图,这个张量的形状是[None,784 ]。(这里的None表示此张量的第一个维度可以是任何长度的。)
y = tf.placeholder(tf.float32,[None,10])

W = tf.Variable(tf.zeros([784,10]))					#W的维度是[784,10],因为我们想要用784维的图片向量乘以它以得到一个10维的证据值向量,每一位对应不同数字类
b = tf.Variable(tf.zeros([10]))						#b的形状是[10],我们可以直接把它加到输出上面。
prediction = tf.nn.softmax(tf.matmul(x,W) + b)
loss = tf.reduce_mean(tf.square(y - prediction))
train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)

init = tf.global_variables_initializer()

correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))			#上行代码给我们一组布尔值。为了确定正确预测项的比例,可以把布尔值转换成浮点数,然后取平均值

with tf.Session() as sess:
    sess.run(init)
    for epoch in range(21):							#训练模型,让模型循环训练21次					
        for batch in range(n_batch):				
            batch_xs,batch_ys = mnist.train.next_batch(batch_size)			#循环的每个步骤中,随机抓取训练数据中的100个批处理数据点,
            sess.run(train_step,feed_dict = {x:batch_xs,y:batch_ys})		#用这些数据点作为参数替换之前的占位符来运行train_step。
        
        acc = sess.run(accuracy,feed_dict =   {x:mnist.test.images,y:mnist.test.labels})		#计算所学习到的模型在测试数据集上面的正确率
        print('周期' + str(epoch) + ',准确率' + str(acc))

运行:
Extracting MNIST_data\train-images-idx3-ubyte.gz
Extracting MNIST_data\train-labels-idx1-ubyte.gz
Extracting MNIST_data\t10k-images-idx3-ubyte.gz
Extracting MNIST_data\t10k-labels-idx1-ubyte.gz
周期0,准确率0.8322
周期1,准确率0.8697
周期2,准确率0.8816
周期3,准确率0.888
周期4,准确率0.8943
周期5,准确率0.8973
周期6,准确率0.8999
周期7,准确率0.9019
周期8,准确率0.9039
周期9,准确率0.9046
周期10,准确率0.9058
周期11,准确率0.9068
周期12,准确率0.9083
周期13,准确率0.9083
周期14,准确率0.9098
周期15,准确率0.9109
周期16,准确率0.9114
周期17,准确率0.9129
周期18,准确率0.9127
周期19,准确率0.9131
周期20,准确率0.9139

正确率为91%,远远不够,思考如何提高正确率

发布了70 篇原创文章 · 获赞 5 · 访问量 3530

猜你喜欢

转载自blog.csdn.net/qq_42647903/article/details/99972503