关于tf.nn.dynamic_rnn
tf.nn.dynamic_rnn 函数是tensorflow封装的用来实现递归神经网络(RNN)的函数。
tf.nn.dynamic_rnn(
cell,
inputs,
sequence_length=None,
initial_state=None,
dtype=None,
parallel_iterations=None,
swap_memory=False,
time_major=False,
scope=None
)
重要参数介绍:
- cell:LSTM、GRU等的记忆单元。cell参数代表一个LSTM或GRU的记忆单元,也就是一个cell。例如,cell = tf.nn.rnn_cell.LSTMCell((num_units),其中,num_units表示rnn cell中神经元个数,也就是下文的cell.output_size。返回一个LSTM或GRU cell,作为参数传入。
- inputs:输入的训练或测试数据,一般格式为[batch_size, max_time, embed_size],其中batch_size是输入的这批数据的数量,max_time就是这批数据中序列的最长长度,embed_size表示嵌入的词向量的维度。
- sequence_length:是一个list,假设你输入了三句话,且三句话的长度分别是5,10,25,那么sequence_length=[5,10,25]。
- initial_state: (可选)RNN的初始state(状态)。如果cell.state_size(一层的RNNCell)是一个整数,那么它必须是一个具有适当类型和形状的张量[batch_size,cell.state_size]。如果cell.state_size是一个元组(多层的RNNCell,如MultiRNNCell),那么它应该是一个张量元组,每个元素的形状为[batch_size,s] for s in cell.state_size
- time_major:决定了输出tensor的格式,如果为True, 张量的形状必须为 [max_time, batch_size,cell.output_size]。如果为False, tensor的形状必须为[batch_size, max_time, cell.output_size],cell.output_size表示rnn cell中神经元个数。
返回值:元组(outputs, states)
- outputs:RNN的最后一层的输出,是一个tensor
如果为time_major== False,则shape [batch_size,max_time,cell.output_size]。如果为time_major== True,则shape: [max_time,batch_size,cell.output_size]。 - state: RNN最后时间步的state,如果cell.state_size是一个整数(一般是单层的RNNCell),则state的shape:[batch_size,cell.state_size]。如果它是一个元组(一般这里是 多层的RNNCell),那么它将是一个具有相应形状的元组。注意:如果若RNNCell是 LSTMCells,则state将为每层cell的LSTMStateTuple的元组Tuple(LSTMStateTuple,LSTMStateTuple,LSTMStateTuple)
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
from tensorflow .examples .tutorials .mnist import input_data
mnist=input_data .read_data_sets ('data/',one_hot= True)
trainimgs, trainlabels, testimgs, testlabels \
= mnist.train.images, mnist.train.labels, mnist.test.images, mnist.test.labels
ntrain, ntest, dim, nclasses \
= trainimgs.shape[0], testimgs.shape[0], trainimgs.shape[1], trainlabels.shape[1]
print ("MNIST loaded")
training_epochs = 10
batch_size = 32
display_step = 1
diminput=28
dimhidden=128
dimoutput=nclasses
nsteps=28#把输入拆分为28个小部分
weights={
'hidden':tf.Variable(tf.random_normal([diminput ,dimhidden ])),
'out':tf.Variable(tf.random_normal([dimhidden,dimoutput]))
}
biases={
'hidden':tf.Variable(tf.random_normal([dimhidden])),
'out':tf.Variable(tf.random_normal([dimoutput]))
}
def _RNN(_X,_W,_b,_nsteps,):
#_X的格式为:[bitchsize,h,w]
#_X=tf.transpose(_X,[1,0,2])#将第一维度和第二维度交换-无用
'''
tf.transpose(input, [dimension_1, dimenaion_2,..,dimension_n])
这个函数主要适用于交换输入张量的不同维度用的,如果输入张量是二维,就相当是转置。
dimension_n是整数,如果张量是三维,就是用0,1,2来表示。这个列表里的每个数对应相应的维度。
如果是[2,1,0],就把输入张量的第三维度和第一维度交换。
'''
_X=tf.reshape(_X,[-1,diminput])#(batchsize*28,28)
_H=tf.matmul(_X,_W['hidden'])+_b['hidden']#(batchsize*28,128)
_H=tf.reshape(_H,[-1,_nsteps,dimhidden])#(batchsize,28,128)
#算隐层时,是按照整体去算,算完之后因为要进行RNN训练——分切片进行
# _Hsplit=tf.split(_H,_nsteps,0)
''''
tf.split(dimension, num_split, input):
dimension的意思就是输入张量的哪一个维度,如果是0就表示对第0维度进行切割。
num_split就是切割的数量,如果是2就表示输入张量被切成2份,每一份是一个列表。
'''
#输入数据的格式的问题
lstm_cell=tf.nn.rnn_cell.BasicLSTMCell(dimhidden,forget_bias=1.0,state_is_tuple=True)#重点
init_state = lstm_cell.zero_state(batch_size, dtype=tf.float32)
# dynamic_rnn 接收张量(batch, steps, inputs)或者(steps, batch, inputs)作为X_in
outputs, final_state=tf.nn.dynamic_rnn(lstm_cell,_H ,initial_state=init_state,time_major=False)#重点
'''
tf.nn.rnn_cell.BasicLSTMCell(n_hidden, forget_bias=1.0, state_is_tuple=True):
n_hidden表示神经元的个数,
forget_bias就是LSTM门的忘记系数,如果等于1,就是不会忘记任何信息。如果等于0,就都忘记。
state_is_tuple默认就是True,官方建议用True,就是表示返回的状态用一个元祖表示。
'''
_O=tf.matmul(final_state[1],_W['out'])+_b['out']
return{
'X': _X, 'H': _H, 'O': _O
}
print('NEtwork ready')
learning_rate = 0.001
x = tf.placeholder("float", [None, nsteps, diminput])
y = tf.placeholder("float", [None, dimoutput])
myrnn = _RNN(x, weights, biases, nsteps)
pred = myrnn['O']
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=y))
optm = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost) # Adam Optimizer
accr = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(pred,1), tf.argmax(y,1)), tf.float32))
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)
print ("Start optimization")
for epoch in range(training_epochs):
avg_cost = 0.
#total_batch = int(mnist.train.num_examples/batch_size)
total_batch = 100
# Loop over all batches
for i in range(total_batch):
batch_xs, batch_ys = mnist.train.next_batch(batch_size)
batch_xs = batch_xs.reshape((batch_size, nsteps, diminput))
# Fit training using batch data
feeds = {x: batch_xs, y: batch_ys}
sess.run(optm, feed_dict=feeds)
# Compute average loss
avg_cost += sess.run(cost, feed_dict=feeds) / total_batch
# Display logs per epoch step
if epoch % display_step == 0:
print("Epoch: %03d/%03d cost: %.9f" % (epoch, training_epochs, avg_cost))
feeds = {x: batch_xs, y: batch_ys}
train_acc = sess.run(accr, feed_dict=feeds)
print(" Training accuracy: %.3f" % (train_acc))
'''
testimgs = testimgs.reshape((ntest, nsteps, diminput))
feeds = {x: testimgs, y: testlabels}
test_acc = sess.run(accr, feed_dict=feeds)
print(" Test accuracy: %.3f" % (test_acc))
'''
print("Optimization Finished.")