您的位置:首页 > 其它

tensorflow 手写数据识别

2019-03-28 23:04 48 查看

手写数字识别

MNIST数据集(修改的国家标准与技术研究所——Modified National Institute of Standards and Technology),是一个大型的包含手写数字图片的数据集。该数据集由0-9手写数字图片组成,共10个类别。每张图片的大小为28 * 28。

[code]import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import matplotlib.pyplot as plt

下载数据集

调用read_data_sets,可以下载mnist数据集到指定的目录,如果目录不存在,可自定创建。
如果数据已经下载,则直接从文件中提取数据。

说明:

  • 如果因为网络原因,导致下载不成功,可以去MNIST官网进行下载。
[code]# 通过指定的路径(第1个参数)获取(加载)手写数字数据集。如果指定的路径中文件
# 不存在,则会进行下载。(下载速度可能非常慢)。
# 如果文件已经存在,则直接使用。
mnist = input_data.read_data_sets("data/", one_hot=True)

MNIST数据集查看

MNIST数据集共有70000张图像,其中训练集60000张,测试集10000张。训练集分为55000张训练图像与5000张验证图像。
MNIST图像为单通道。

[code]display(mnist.train.images.shape)
display(mnist.train.labels.shape)
mnist.train.labels[0]

显示指定的图像

可以通过matplotlib库显示指定的图像。

[code]plt.imshow(mnist.train.images[1].reshape((28, 28)), cmap="gray")

实现

我们使用单层神经网络来实现该任务。使用softmax激活函数。
图像的每个像素可以看做一个特征,而每个像素点对应着一个权重,来衡量该像素点对目标的影响大小。

[code]# 定义输入。
X = tf.placeholder(dtype=tf.float32, shape=[None, 784])
y = tf.placeholder(dtype=tf.float32, shape=[None, 10])

# W = tf.Variable(tf.random_normal(shape=[784, 10], stddev=0.1))
# 对于单层的神经网络,权重初始化不那么重要,但是对于多层神经网络,权重的初始化就比较重要了。
W = tf.Variable(tf.zeros(shape=[784, 10]))
b = tf.Variable(tf.zeros(shape=[1, 10]))
# 计算净输入。(logits值)
z = tf.matmul(X, W) + b
#  多分类,使用softmax。传递logits值,返回属于每个类别的概率。
a = tf.nn.softmax(z)
# 定义交叉熵损失函数。
loss = -tf.reduce_sum(y * tf.log(a))
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
# tf.argmax(y, axis=1) 求真实的类别的索引。
# tf.argmax(a, axis=1) 求预测的类别的索引。
# correct是一个布尔类型的张量。
correct = tf.equal(tf.argmax(y, axis=1), tf.argmax(a, axis=1))
# 计算准确率。
rate = tf.reduce_mean(tf.cast(correct, tf.float32))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(1, 3001):
batch_X, batch_y = mnist.train.next_batch(100)
sess.run(train_step, feed_dict={X: batch_X, y: batch_y})
if i % 500 == 0:
# 传入测试数据,查看测试集上的准确率。
print(sess.run(rate, feed_dict={X: mnist.test.images, y: mnist.test.labels}))

改进

采用中间加入一隐藏层(多层神经网络)来实现,查看准确率是否改善。

[code]X = tf.placeholder(dtype=tf.float32, shape=[None, 784])
y = tf.placeholder(dtype=tf.float32, shape=[None, 10])
# 如果将权重初始化为0,则准确率非常低。10%左右。
# W = tf.Variable(tf.zeros(shape=[784, 256]))
# 如果标准差设置不当,准确率也非常低。
# W = tf.Variable(tf.random_normal(shape=[784, 256], stddev=0.05))
# 使用标准正态分布,标准差0.05,准确率为97%左右。
# W = tf.Variable(tf.random_normal(shape=[784, 256], stddev=0.05))
# 也可以使用截断正态分布,准确率与标准正态分布差不多。使用截断正态分布时,标准差设置为0.1不会出现问题。
W = tf.Variable(tf.truncated_normal(shape=[784, 256], stddev=0.1))
b = tf.Variable(tf.zeros(shape=[1, 256]))
z = tf.matmul(X, W) + b
# 使用Relu激活函数。a是当前层神经元的输出值,会作为下一层神经元的输入值。
a = tf.nn.relu(z)
# W2 = tf.Variable(tf.random_normal(shape=[256, 10], stddev=0.05))
W2 = tf.Variable(tf.truncated_normal(shape=[256, 10], stddev=0.1))
b2 = tf.Variable(tf.zeros(shape=[1, 10]))
z2 = tf.matmul(a, W2) + b2
a2 = tf.nn.softmax(z2)
loss = -tf.reduce_sum(y * tf.log(a2))
# 这里不再计算softmax,再计算交叉熵,而是直接用tf.nn.softmax_cross_entropy_with_logits直接计算。
# 但是,使用该方法后,准确率有所下降。
# loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=z2, labels=y))
train_step = tf.train.GradientDescentOptimizer(0.01).minimize(loss)
correct = tf.equal(tf.argmax(y, axis=1), tf.argmax(a2, axis=1))
# correct = tf.equal(tf.argmax(y, axis=1), tf.argmax(z2, axis=1))
rate = tf.reduce_mean(tf.cast(correct, tf.float32))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for i in range(1, 3001):
batch_X, batch_y = mnist.train.next_batch(100)
sess.run(train_step, feed_dict={X: batch_X, y: batch_y})
if i % 500 == 0:
print(sess.run(rate, feed_dict={X: mnist.test.images, y: mnist.test.labels}))

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: