传送门第一个看不懂的代码,好尴尬呀,看来学习的东西还有好多好多呢。
传送门这篇blog对于tensroflow下的RNN实现讲的挺好的
记录一下当前看得懂的部分:
用 zero padding 的方式可以使得输入time_step变化
forget_bias=1是指初始的 forget gate 全开
##############################################################################
# 这个是制造伪随机数, 用来控制每次运行时输出的随机数列一样
# 随机种子是为了结果和我视频中的一样, 所以就设置了
# set random seed for comparing the two result
calculations
tf.set_random_seed(1)
tf的输入是一个[batch_size,row,col],将一副图像转换为28个时刻,每个时刻输入28维度的向量
x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
y = tf.placeholder(tf.float32, [None, n_classes])
定义RNN结构
##############################################################################
#将batch的输入经过一个送入hidden layer
#将原始batch输入转换为[batch*step,input],每个时刻的input大小为batch*step
X = tf.reshape(X, [-1, n_inputs])
#将输入经过一个单层网络,变成一个[bacth*step,hidden],就是通过变换把input变成hidden
X_in = tf.matmul(X, weights['in']) + biases['in']
#再把它展开成[bacth,step,hidden]
X_in = tf.reshape(X_in, [-1, n_steps, n_hidden_units])
########################################################################
# 定义了一个cell,一个矩形框为一个cell,一个cell输入可以是多维度的
cell = tf.contrib.rnn.BasicLSTMCell(n_hidden_units)
#定义batchs size,将它的batch用于网络的建立
init_state = cell.zero_state(batch_size, dtype=tf.float32)
#不用定义step,直接根据X_in的shape绝对step
outputs, final_state = tf.nn.dynamic_rnn(cell, X_in, initial_state=init_state, time_major=False)
#将输出outputs输出[batch,step,hidden],变成[step,batch,hidden];
#再unstack就是使得outputs[-1]=last_step的[batch,hidden],可以直接下标访问
#[1,0,2] 是告诉 tf 要如何翻转现有的三维张量, 假设原有的张量是 [0,1,2] 的维度顺序, 使用 tf.transpose, 会将[0,1,2] 的0 和 1 维数据互换维度.
outputs = tf.unstack(tf.transpose(outputs, [1,0,2]))
# outputs[-1]=last_step的[batch,hidden]--->[batch,calss]
results = tf.matmul(outputs[-1], weights['out']) + biases['out'] # shape = (128, 10)
# 或者用final_state,final_state=[c_state, h_state],用final_state[1]就是最后一个时刻的输出值了
# output记录各个隐层的输出值
graph部分
##############################################################################
#调用RNN函数,得到pred为[batch,class]大小的矩阵
pred = RNN(x, weights, biases)
#最后的损失函数,里面内容丰富,pred经过一个softmax层,再计算实际值和输出值之间的交叉熵,再对batch取平均
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
#用adam算法来优化
train_op = tf.train.AdamOptimizer(0.001).minimize(cost)
#沿着行取最大,得到预测结果,判断两行是否相等,平均得到准确率,直接把预测graph定义到原始graph之下,不用额外定义变量。
correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
##############################################################################
session部分:
##############################################################################
#常规的喂数据的方法
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
batch_xs = batch_xs.reshape([batch_size, n_steps, n_inputs])
sess.run([train_op], feed_dict={
x: batch_xs,
y: batch_ys,
})
if step % 20 == 0:
print(sess.run(accuracy, feed_dict={
x: batch_xs,
y: batch_ys,
}))
##############################################################################
完整代码如下:
# View more python learning tutorial on my Youtube and Youku channel!!!
# Youtube video tutorial: https://www.youtube.com/channel/UCdyjiB5H8Pu7aDTNVXTTpcg
# Youku video tutorial: http://i.youku.com/pythontutorial
"""
This code is a modified version of the code from this link:
https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/3_NeuralNetworks/recurrent_network.py
His code is a very good one for RNN beginners. Feel free to check it out.
"""
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
# set random seed for comparing the two result calculations
tf.set_random_seed(1)
# this is data
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
# hyperparameters
lr = 0.001
training_iters = 100000
batch_size = 128
n_inputs = 28 # MNIST data input (img shape: 28*28)
n_steps = 28 # time steps
n_hidden_units = 128 # neurons in hidden layer
n_classes = 10 # MNIST classes (0-9 digits)
# tf Graph input
x = tf.placeholder(tf.float32, [None, n_steps, n_inputs])
y = tf.placeholder(tf.float32, [None, n_classes])
# Define weights
weights = {
# (28, 128)
'in': tf.Variable(tf.random_normal([n_inputs, n_hidden_units])),
# (128, 10)
'out': tf.Variable(tf.random_normal([n_hidden_units, n_classes]))
}
biases = {
# (128, )
'in': tf.Variable(tf.constant(0.1, shape=[n_hidden_units, ])),
# (10, )
'out': tf.Variable(tf.constant(0.1, shape=[n_classes, ]))
}
def RNN(X, weights, biases):
# hidden layer for input to cell
########################################
# transpose the inputs shape from
# X ==> (128 batch * 28 steps, 28 inputs)
X = tf.reshape(X, [-1, n_inputs])
# into hidden
# X_in = (128 batch * 28 steps, 128 hidden)
X_in = tf.matmul(X, weights['in']) + biases['in']
# X_in ==> (128 batch, 28 steps, 128 hidden)
X_in = tf.reshape(X_in, [-1, n_steps, n_hidden_units])
# cell
##########################################
# basic LSTM Cell.
cell = tf.contrib.rnn.BasicLSTMCell(n_hidden_units)
# lstm cell is divided into two parts (c_state, h_state)
init_state = cell.zero_state(batch_size, dtype=tf.float32)
# You have 2 options for following step.
# 1: tf.nn.rnn(cell, inputs);
# 2: tf.nn.dynamic_rnn(cell, inputs).
# If use option 1, you have to modified the shape of X_in, go and check out this:
# https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/3_NeuralNetworks/recurrent_network.py
# In here, we go for option 2.
# dynamic_rnn receive Tensor (batch, steps, inputs) or (steps, batch, inputs) as X_in.
# Make sure the time_major is changed accordingly.
outputs, final_state = tf.nn.dynamic_rnn(cell, X_in, initial_state=init_state, time_major=False)
# hidden layer for output as the final results
#############################################
# results = tf.matmul(final_state[1], weights['out']) + biases['out']
# # or
# unpack to list [(batch, outputs)..] * steps
if int((tf.__version__).split('.')[1]) < 12 and int((tf.__version__).split('.')[0]) < 1:
outputs = tf.unpack(tf.transpose(outputs, [1, 0, 2])) # states is the last outputs
else:
outputs = tf.unstack(tf.transpose(outputs, [1,0,2]))
results = tf.matmul(outputs[-1], weights['out']) + biases['out'] # shape = (128, 10)
return results
pred = RNN(x, weights, biases)
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
train_op = tf.train.AdamOptimizer(lr).minimize(cost)
correct_pred = tf.equal(tf.argmax(pred, 1), tf.argmax(y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, tf.float32))
with tf.Session() as sess:
# tf.initialize_all_variables() no long valid from
# 2017-03-02 if using tensorflow >= 0.12
if int((tf.__version__).split('.')[1]) < 12 and int((tf.__version__).split('.')[0]) < 1:
init = tf.initialize_all_variables()
else:
init = tf.global_variables_initializer()
sess.run(init)
step = 0
while step * batch_size < training_iters:
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
batch_xs = batch_xs.reshape([batch_size, n_steps, n_inputs])
sess.run([train_op], feed_dict={
x: batch_xs,
y: batch_ys,
})
if step % 20 == 0:
print(sess.run(accuracy, feed_dict={
x: batch_xs,
y: batch_ys,
}))
step += 1