Tensorflow中的实现
tensorflow支持RNN各种变体,可以从tf.contrib.rnn模块中找到这些变体,比如tf.contrib.rnn.GRUCell。
借助于tf.nn.dynamic_rnn 我们可以直接定义RNN网络
import tensorflow as tf
import numpy as np
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets('mnist/', one_hot=True)
learning_rate = 0.001
batch_size = 128
n_input = 28
n_steps = 28
n_hidden = 128
n_classes = 10
x = tf.placeholder(tf.float32, [None, n_steps,n_input]) # [batch_size, 时间步(句子长度), 每个字维度]
y = tf.placeholder(tf.float32, [None, n_classes])
output, _= tf.nn.dynamic_rnn(
tf.contrib.rnn.GRUCell(n_hidden),
x,
dtype=tf.float32,
sequence_length = batch_size*[n_input], # 告诉句子的实际长度,计算到该长度时不再计算
)
output.get_shape()
TensorShape([Dimension(None), Dimension(28), Dimension(128)])
index = tf.range(0, batch_size)*n_steps + (n_input - 1)
flat = tf.reshape(output,[-1,int(output.get_shape()[2])]) # 扁平化,第一维是batch*n_step。
last = tf.gather(flat,index) # 取出output
# 可理解为:将一张图片看成一个句子,每次取一条句子最后一个字输出的结果,代表一条句子代表的意思。
last.get_shape()
TensorShape([Dimension(128), Dimension(128)])
num_classes = int(y.get_shape()[1]) # 分类
weight = tf.Variable(tf.truncated_normal([n_hidden, num_classes], stddev=0.01))
bias = tf.Variable(tf.constant(0.1, shape=[num_classes]))
prediction = tf.nn.softmax(tf.matmul(last, weight) + bias)
prediction.get_shape()
TensorShape([Dimension(128), Dimension(10)])
cross_entropy = -tf.reduce_sum(y * tf.log(prediction))
optimizer = tf.train.AdamOptimizer(learning_rate,beta1=0.5)
grads = optimizer.compute_gradients(cross_entropy)
for i, (g, v)in enumerate(grads): # 梯度拆解,防止梯度过大
if g is not None:
grads[i] = (tf.clip_by_norm(g, 5), v) # clip gradients
train_op = optimizer.apply_gradients(grads)
D:\Code\Miniconda3\envs\tensorflow1.13-gpu\lib\site-packages\tensorflow\python\ops\gradients_impl.py:110: UserWarning: Converting sparse IndexedSlices to a dense Tensor of unknown shape. This may consume a large amount of memory.
"Converting sparse IndexedSlices to a dense Tensor of unknown shape. "
correct_pred = tf.equal(tf.argmax(prediction,1), tf.argmax(y,1))
accuracy = tf.reduce_mean(tf.cast(correct_pred,tf.float32))
correct_pred.get_shape()
TensorShape([Dimension(128)])
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
for step in range(1300):
batch_x, batch_y = mnist.train.next_batch(batch_size)
batch_x = batch_x.reshape((batch_size,n_steps,n_input))
sess.run(train_op,feed_dict={x: batch_x, y: batch_y})
if step % 50 == 0:
acc = sess.run(accuracy, feed_dict={x: batch_x,y: batch_y})
loss = sess.run(cross_entropy, feed_dict={x: batch_x, y: batch_y})
print("Iter " + str(step)+ ",Minibatch Loss= "+ "{:.6f}".format(loss)+ ",Training Accuracy= " + "{:.5f}".format(acc))
print("Optimization Finished!")
Iter 0,Minibatch Loss= 293.901520,Training Accuracy= 0.18750
Iter 50,Minibatch Loss= 176.685913,Training Accuracy= 0.57031
Iter 100,Minibatch Loss= 142.176193,Training Accuracy= 0.65625
Iter 150,Minibatch Loss= 104.617989,Training Accuracy= 0.71875
Iter 200,Minibatch Loss= 68.779808,Training Accuracy= 0.82031
Iter 250,Minibatch Loss= 66.591736,Training Accuracy= 0.89062
Iter 300,Minibatch Loss= 39.670883,Training Accuracy= 0.89062
Iter 350,Minibatch Loss= 34.930038,Training Accuracy= 0.93750
Iter 400,Minibatch Loss= 35.739891,Training Accuracy= 0.92188
Iter 450,Minibatch Loss= 37.315536,Training Accuracy= 0.90625
Iter 500,Minibatch Loss= 24.074083,Training Accuracy= 0.94531
Iter 550,Minibatch Loss= 16.719700,Training Accuracy= 0.96094
Iter 600,Minibatch Loss= 37.602249,Training Accuracy= 0.90625
Iter 650,Minibatch Loss= 25.909483,Training Accuracy= 0.93750
Iter 700,Minibatch Loss= 17.428286,Training Accuracy= 0.95312
Iter 750,Minibatch Loss= 6.029305,Training Accuracy= 1.00000
Iter 800,Minibatch Loss= 15.102160,Training Accuracy= 0.96875
Iter 850,Minibatch Loss= 12.893662,Training Accuracy= 0.96094
Iter 900,Minibatch Loss= 9.019846,Training Accuracy= 0.98438
Iter 950,Minibatch Loss= 8.083559,Training Accuracy= 0.98438
Iter 1000,Minibatch Loss= 6.361010,Training Accuracy= 0.99219
Iter 1050,Minibatch Loss= 7.768955,Training Accuracy= 0.97656
Iter 1100,Minibatch Loss= 9.339849,Training Accuracy= 0.98438
Iter 1150,Minibatch Loss= 4.386148,Training Accuracy= 0.98438
Iter 1200,Minibatch Loss= 3.035935,Training Accuracy= 0.99219
Iter 1250,Minibatch Loss= 3.397231,Training Accuracy= 0.99219
Optimization Finished!
test_x = mnist.test.images
test_x = test_x.reshape((-1,n_steps,n_input))
test_y = mnist.test.labels
acc = sess.run(accuracy, feed_dict={x: test_x[:128], y: test_y[:128]})
print(acc)
0.9765625