# 基于tensorflow+RNN的MNIST数据集手写数字分类

2018年9月25日笔记

RNN是recurrent neural network的简称，中文叫做循环神经网络。
MNIST是Mixed National Institue of Standards and Technology database的简称，中文叫做美国国家标准与技术研究所数据库

《基于tensorflow+DNN的MNIST数据集手写数字分类预测》文章链接：https://www.jianshu.com/p/9a4ae5655ca6

## 0.编程环境

tensorflow版本：1.6
tensorboard版本：1.6
python版本：3.6

## 3.下载并解压数据集

MNIST数据集下载链接: https://pan.baidu.com/s/1fPbgMqsEvk2WyM9hy5Em6w 密码: wa9p

image.png

## 4.完整代码

``````import warnings
warnings.filterwarnings('ignore')
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

tf.reset_default_graph()
learing_rate = 0.001
batch_size =100
n_steps = 28
n_inputs = 28
n_hidden_units = 128
n_classes = 10
X_holder = tf.placeholder(tf.float32)
Y_holder = tf.placeholder(tf.float32)

def RNN(X_holder):
reshape_X = tf.reshape(X_holder, [-1, n_steps, n_inputs])
lstm_cell = tf.nn.rnn_cell.BasicLSTMCell(n_hidden_units)
outputs, states = tf.nn.dynamic_rnn(lstm_cell, reshape_X, dtype=tf.float32)
cell_list = tf.unstack(tf.transpose(outputs, [1, 0, 2]))
last_cell = cell_list[-1]
Weights = tf.Variable(tf.truncated_normal([n_hidden_units, n_classes]))
biases = tf.Variable(tf.constant(0.1, shape=[n_classes]))
predict_Y = tf.matmul(last_cell, Weights) + biases
return predict_Y
predict_Y = RNN(X_holder)
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=predict_Y, labels=Y_holder))
train = optimizer.minimize(loss)

init = tf.global_variables_initializer()
session = tf.Session()
session.run(init)

isCorrect = tf.equal(tf.argmax(predict_Y, 1), tf.argmax(Y_holder, 1))
accuracy = tf.reduce_mean(tf.cast(isCorrect, tf.float32))
for i in range(1000):
X, Y = mnist.train.next_batch(batch_size)
session.run(train, feed_dict={X_holder:X, Y_holder:Y})
step = i + 1
if step % 100 == 0:
test_X, test_Y = mnist.train.next_batch(3000)
test_accuracy = session.run(accuracy, feed_dict={X_holder:test_X, Y_holder:test_Y})
print("step:%d test accuracy:%.4f" %(step, test_accuracy))
``````

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
step:100 test accuracy:0.8483
step:200 test accuracy:0.8987
step:300 test accuracy:0.9230
step:400 test accuracy:0.9437
step:500 test accuracy:0.9457
step:600 test accuracy:0.9513
step:700 test accuracy:0.9687
step:800 test accuracy:0.9660
step:900 test accuracy:0.9710
step:1000 test accuracy:0.9740

## 5.数据准备

``````import warnings
warnings.filterwarnings('ignore')
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data

tf.reset_default_graph()
learing_rate = 0.001
batch_size =100
n_steps = 28
n_inputs = 28
n_hidden_units = 128
n_classes = 10
X_holder = tf.placeholder(tf.float32)
Y_holder = tf.placeholder(tf.float32)
``````

## 6.搭建神经网络

tf.reshape https://www.tensorflow.org/api_docs/python/tf/manip/reshape
tf.nn.rnn_cell.LSTMCell https://www.tensorflow.org/api_docs/python/tf/nn/rnn_cell/BasicLSTMCell
tf.nn.dynamic_rnn https://www.tensorflow.org/api_docs/python/tf/nn/dynamic_rnn
tf.transpose https://www.tensorflow.org/api_docs/python/tf/transpose
tf.unstack https://www.tensorflow.org/api_docs/python/tf/unstack
tf.Variable https://www.tensorflow.org/api_docs/python/tf/Variable
tf.truncated_normal https://www.tensorflow.org/api_docs/python/tf/truncated_normal
tf.matmul https://www.tensorflow.org/api_docs/python/tf/matmul
tf.reduce_mean https://www.tensorflow.org/api_docs/python/tf/reduce_mean
tf.nn.softmax_cross_entropy_with_logits https://www.tensorflow.org/api_docs/python/tf/nn/softmax_cross_entropy_with_logits

``````reshape_X = tf.reshape(X_holder, [-1, n_steps, n_inputs])
lstm_cell = tf.nn.rnn_cell.LSTMCell(n_hidden_units)
outputs, state = tf.nn.dynamic_rnn(lstm_cell, reshape_X, dtype=tf.float32)
cell_list = tf.unstack(tf.transpose(outputs, [1, 0, 2]))
last_cell = cell_list[-1]
Weights = tf.Variable(tf.truncated_normal([n_hidden_units, n_classes]))
biases = tf.Variable(tf.constant(0.1, shape=[n_classes]))
predict_Y = tf.matmul(last_cell, Weights) + biases
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=predict_Y, labels=Y_holder))
train = optimizer.minimize(loss)
``````

## 7.参数初始化

image.png

``````init = tf.global_variables_initializer()
session = tf.Session()
session.run(init)
``````

## 8.模型训练

tf.equal方法可以比较两个向量的在每个元素上是否相同，返回结果为向量，向量中元素的数据类型为布尔bool；

``````isCorrect = tf.equal(tf.argmax(predict_Y, 1), tf.argmax(Y_holder, 1))
accuracy = tf.reduce_mean(tf.cast(isCorrect, tf.float32))
for i in range(1000):
X, Y = mnist.train.next_batch(batch_size)
session.run(train, feed_dict={X_holder:X, Y_holder:Y})
step = i + 1
if step % 100 == 0:
test_X, test_Y = mnist.test.next_batch(10000)
test_accuracy = session.run(accuracy, feed_dict={X_holder:test_X, Y_holder:test_Y})
print("step:%d test accuracy:%.4f" %(step, test_accuracy))
``````

step:100 test accuracy:0.8479
step:200 test accuracy:0.8986
step:300 test accuracy:0.9370
step:400 test accuracy:0.9421
step:500 test accuracy:0.9522
step:600 test accuracy:0.9581
step:700 test accuracy:0.9607
step:800 test accuracy:0.9650
step:900 test accuracy:0.9661
step:1000 test accuracy:0.9685

## 9.总结

1.本文是作者写的第9篇关于tensorflow编程的博客；
2.在mnist案例中，rnn模型最高可达到98.5%的准确率，cnn模型最高可达到99.2%的准确率，因为本文中的rnn模型只考虑的图像矩阵中每1行的关系，rnn模型可以提取空间特征。
3.理解第6章搭建神经网络的过程中，虽然代码只有11行，本文作者花费了2天将近10多个小时；
4.周莫烦前辈的视频当中关于此章的代码已经过时，并且github中的代码的模型准确率不超过90%，没有超过单隐藏层的DNN网络98%的准确率，这违背了RNN优于DNN的出发点。