首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

TensorFlow实现识别手写数字识别

MNIST手写数字识别是机器学习领域的Hello Word任务,我们用这个任务来探索下TensorFlow。

MNIST 数据集

MNIST是在机器学习领域中的一个经典问题。该问题解决的是把28x28像素的灰度手写数字图片识别为相应的数字,其中数字的范围从0到9。

数据集组成:

data_sets.train 55000 组图片和标签, 用于训练。

data_sets.validation 5000 组图片和标签, 用于迭代验证训练的准确性。

data_sets.test10000 组图片和标签, 用于最终测试训练的准确性。

执行read_data_sets()函数将会返回一个DataSet实例,其中包含了以上三个数据集。

函数DataSet.next_batch()是用于获取以batch_size为大小的一个元组,其中包含了一组图片和标签,该元组会被用于当前的TensorFlow运算会话中。

我们在训练集上训练模型,在验证集上检验效果并决定何时完成训练,最后在测试集上评测模型的效果(准确率、召回率等)。

数据模型

每一张图片大小28像素*28像素,可以用二维数组来表示图片,空白的地方全部为0,有笔迹的地方根据颜色深浅有0到1之间的取值。我们把二维数组展开成一维数组,数组长度28x28 = 784,展开的方式不重要,只要所有图片的展开方式一致就行。有人可能会问,图片的空间结构信息不是很有价值么,为什么要丢弃呢?因为这个数据集的分类任务比较简单,不需要太复杂的模型,所以简化了问题,丢弃了空间结构。

softmax regression

我们使用softmax回归(softmax regression)模型作为训练手写算法的分类模型。MNIST的每一张图片都表示一个数字,从0到9。我们希望得到给定图片代表每个数字的概率。比如说,我们的模型可能推测一张包含9的图片代表数字9的概率是80%但是判断它是8的概率是5%(因为8和9都有上半部分的小圆),然后给予它代表其他数字的概率更小的值,最后取概率最大的那个数字作为模型输出结果。

我们对图片像素值进行加权求和。如果这个像素具有很强的证据说明这张图片不属于该类,那么相应的权值为负数,相反如果这个像素拥有有利的证据支持这张图片属于这个类,那么权值是正数。

softmax的过程就是计算一个exp函数,然后再进行归一化的过程。

判断为第i类的概率可由一下公式得到:

回归模型代码实现

import tensorflow as tfx = tf.placeholder("float", [None, 784])

这里的None表示此张量的第一个维度可以是任何长度的。

W = tf.Variable(tf.zeros([784,10]))b = tf.Variable(tf.zeros([10]))

一个Variable代表一个可修改的张量,存在在TensorFlow的用于描述交互性操作的图中。它们可以用于计算输入值,也可以在计算中被修改。

我们可以实现我们的模型啦。只需要一行代码

模型迭代训练

在机器学习,我们通常定义指标来表示一个模型是坏的,这个指标称为成本(cost)或损失(loss),然后尽量最小化这个指标。一个常见的cost函数是“交叉熵”(cross-entropy)。

y_ = tf.placeholder("float", [None,10])cross_entropy = -tf.reduce_sum(y_*tf.log(y))

我们要求TensorFlow用梯度下降算法(gradient descent algorithm)以0.01的学习速率最小化交叉熵。

train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy)

现在,我们已经设置好了我们的模型。在运行计算之前,我们需要添加一个操作来初始化我们创建的变量:

init = tf.initialize_all_variables()

现在我们可以在一个Session里面启动我们的模型,并且初始化变量:

sess = tf.Session()sess.run(init)

然后开始训练模型,这里我们让模型循环训练1000次!

该循环的每个步骤中,我们都会随机抓取训练数据中的100个批处理数据点,然后我们用这些数据点作为参数替换之前的占位符来运行train_step。

模型准确率评估

那么我们的模型性能如何呢?

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

correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))

这行代码会给我们一组布尔值。为了确定正确预测项的比例,我们可以把布尔值转换成浮点数,然后取平均值。例如,[True, False, True, True] 会变成 [1,0,1,1] ,取平均值后得到 0.75.

accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float"))

最后,我们计算所学习到的模型在测试数据集上面的正确率。

print sess.run(accuracy, feed_dict=)

这个最终结果值应该大约是91%。

这个结果好吗?嗯,并不太好。事实上,这个结果是很差的。这是因为我们仅仅使用了一个非常简单的模型。不过,做一些小小的改进,我们就可以得到97%的正确率。最好的模型甚至可以获得超过99.7%的准确率!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180604A080DB00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券