"""
例1:循环神经网络实现mnist数据集手写体识别
"""
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
mnist = input_data.read_data_sets('MNIST_data/', one_hot=True)
# 定义参数
element_size = 28
time_steps = 28
num_classes = 10
batch_size = 128
hidden_layer_size = 128
# TensorBoard 保存路径
LOG_DIR = "logs/RNN_with_summeries"
# 为输入和标签创建占位符
_inputs = tf.placeholder(tf.float32, shape=[None, time_steps, element_size], name='inputs')
y = tf.placeholder(tf.float32, shape=[None, num_classes], name='labels')
# 从mnist数据集中取出batch_size=128个训练输入和标签
batch_x, batch_y = mnist.train.next_batch(batch_size)
# 将batch_size个784维向量reshape成(batch_size=128, time_steps=28, element_size=28)的形式
batch_x = batch_x.reshape((batch_size, time_steps, element_size))
# 这个辅助函数是官方文档上的,用于统计传入Variable的信息:mean, stddev, max, min, histogram
def variable_summaries(var):
with tf.name_scope('summaries'):
mean = tf.reduce_mean(var)
tf.summary.scalar('mean', mean)
with tf.name_scope('stddev'):
stddev = tf.sqrt(tf.reduce_mean(tf.square(var - mean)))
tf.summary.scalar('stddev', stddev)
tf.summary.scalar('max', tf.reduce_max(var))
tf.summary.scalar('min', tf.reduce_min(var))
tf.summary.histogram('histogram', var)
# 循环神经网络(Recurrent Neural Network)中输入和隐层的权重和偏置
with tf.name_scope('rnn_weights'):
with tf.name_scope("W_x"):
Wx = tf.Variable(tf.zeros([element_size, hidden_layer_size]))
variable_summaries(Wx)
with tf.name_scope("W_h"):
Wh = tf.Variable(tf.zeros([hidden_layer_size, hidden_layer_size]))
variable_summaries(Wh)
with tf.name_scope("Bias"):
b_rnn = tf.Variable(tf.zeros([hidden_layer_size]))
variable_summaries(b_rnn)
# 循环神经网络的状态更新公式 h_t = tanh(W_x*x_t + W_h*h_{t-1} + b)
def rnn_step(previous_hidden_state, x):
current_hidden_state = tf.tanh(
tf.matmul(previous_hidden_state, Wh) +
tf.matmul(x, Wx) + b_rnn)
return current_hidden_state
# 用tf.scan()函数处理输入
# 交换输入张量的前两维: (batch_size, time_steps, element_size) -> (time_steps, batch_size, element_size)
processed_input = tf.transpose(_inputs, perm=[1, 0, 2])
# 0初始化隐藏层参数
initial_hidden = tf.zeros([batch_size, hidden_layer_size])
# 获取所有时刻(t_1, t_2,..., t_28)的状态向量
all_hidden_states = tf.scan(rnn_step, processed_input, initializer=initial_hidden, name='states')
# 输出层的权重和偏置
with tf.name_scope('linear_layer_weights') as scope:
with tf.name_scope("W_linear"):
Wl = tf.Variable(tf.truncated_normal([hidden_layer_size, num_classes], mean=0, stddev=.01))
variable_summaries(Wl)
with tf.name_scope("Bias_linear"):
bl = tf.Variable(tf.truncated_normal([num_classes], mean=0, stddev=.01))
variable_summaries(bl)
# 对状态向量做线性变换
def get_linear_layer(hidden_state):
return tf.matmul(hidden_state, Wl) + bl
with tf.name_scope('linear_layer_weights') as scope:
# 迭代所有时间,对所有状态向量做线性变换
all_outputs = tf.map_fn(get_linear_layer, all_hidden_states)
# 取最后一个输出
output = all_outputs[-1]
tf.summary.histogram('outputs', output)
with tf.name_scope('cross_entropy'):
# 计算交叉熵
cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=output, labels=y))
tf.summary.scalar('cross_entropy', cross_entropy)
with tf.name_scope('train'):
# 使用优化器 RMSPropOptimizer
train_step = tf.train.RMSPropOptimizer(0.001, 0.9).minimize(cross_entropy)
with tf.name_scope('accuracy'):
# 计算精度
correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(output, 1))
accuracy = (tf.reduce_mean(tf.cast(correct_prediction, tf.float32)))*100
tf.summary.scalar('accuracy', accuracy)
# 合并所有summaries
merged = tf.summary.merge_all()
# 去一个较小的测试集
test_data = mnist.test.images[:batch_size].reshape((-1, time_steps, element_size))
test_label = mnist.test.labels[:batch_size]
with tf.Session() as sess:
# 输出summaries到日志文件夹 -- 供TensorBoard使用
train_writer = tf.summary.FileWriter(LOG_DIR + '/train', graph=tf.get_default_graph())
test_writer = tf.summary.FileWriter(LOG_DIR + '/test', graph=tf.get_default_graph())
sess.run(tf.global_variables_initializer())
for i in range(10001):
# 获取一批次数据
batch_x, batch_y = mnist.train.next_batch(batch_size)
# Reshape该批次数据
batch_x = batch_x.reshape((batch_size, time_steps, element_size))
summary, _ = sess.run([merged, train_step], feed_dict={_inputs: batch_x, y: batch_y})
# 添加到summaries
train_writer.add_summary(summary, i)
if i % 1000 == 0:
acc, loss, = sess.run([accuracy, cross_entropy], feed_dict={_inputs: batch_x, y: batch_y})
print("Iter " + str(i) + ", Minibatch Loss= " + \
"{:.6f}".format(loss) + ", Training Accuracy= " + \
"{:.5f}".format(acc))
if i % 10:
# 计算128条MNIST测试图片的精度,并添加到summaries
summary, acc = sess.run([merged, accuracy], feed_dict={_inputs: test_data, y: test_label})
test_writer.add_summary(summary, i)
test_acc = sess.run(accuracy, feed_dict={_inputs: test_data, y: test_label})
print("Test Accuracy:", test_acc)
Tensorflow之Tensorboard可视化案例
最新推荐文章于 2022-05-18 16:11:05 发布