这里不介绍RNN与RNN的特殊情形LSTM,因为内容过多。
一、相关函数介绍
1、创建Cell:
tf.nn.rnn_cell.BasicRNNCell(num_units)
- num_units:创建的神经元个数。
2、创建由 RNNCellcell
指定的递归神经网络,执行inputs
的完全动态展开(即对单个Cell执行动态展开):
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:RNNCell的一个实例.。
- inputs:RNN输入.如果time_major == False(默认),则是一个shape为[batch_size, max_time, ...]的Tensor,或者这些元素的嵌套元组.如果time_major == True,则是一个shape为[max_time, batch_size, ...]的Tensor,或这些元素的嵌套元组.这也可能是满足此属性的Tensors(可能是嵌套的)元组.前两个维度必须匹配所有输入,否则秩和其他形状组件可能不同.在这种情况下,在每个时间步输入到cell将复制这些元组的结构,时间维度(从中获取时间)除外.在每个时间步输入到个cell将是一个Tensor或(可能是嵌套的)Tensors元组,每个元素都有维度[batch_size, ...]。
- sequence_length:(可选)大小为[batch_size]的int32/int64的向量.超过批处理元素的序列长度时用于复制状态和零输出.所以它更多的是正确性而不是性能.。
- initial_state:(可选)RNN的初始状态.如果cell.state_size是整数,则必须是具有适当类型和shape为[batch_size, cell.state_size]的Tensor.如果cell.state_size是一个元组,则应该是张量元组,在cell.state_size中为s设置shape[batch_size, s]。
- dtype:(可选)初始状态和预期输出的数据类型.如果未提供initial_state或RNN状态具有异构dtype,则是必需的。
- parallel_iterations:(默认值:32).并行运行的迭代次数.适用于那些没有任何时间依赖性并且可以并行运行的操作.该参数用于交换空间的时间.远大于1的值会使用更多内存但占用更少时间,而较小值使用较少内存但计算时间较长。
- swap_memory:透明地交换推理中产生的张量,但是需要从GPU到CPU的支持.这允许训练通常不适合单个GPU的RNN,具有非常小的(或没有)性能损失。
- time_major:inputs和outputsTensor的形状格式.如果是true,则这些 Tensors的shape必须为[max_time, batch_size, depth].如果是false,则这些Tensors的shape必须为[batch_size, max_time, depth].使用time_major = True更有效,因为它避免了RNN计算开始和结束时的转置.但是,大多数TensorFlow数据都是batch-major,因此默认情况下,此函数接受输入并以batch-major形式发出输出。
- scope:用于创建子图的VariableScope;默认为“rnn”.
注意:这里要注意传入的参数inputs的shape。函数返回结果为一个tuple:(outputs, state)。
outputs:
- 对应Cell的输出h(非Cell状态细胞状态C),记录的是所有批次所有序列所有神经元的输出。
- 如果time_major == False(默认),这将是shape为
[batch_size, max_time, cell.output_size]
的Tensor。
如果time_major == True,这将是shape为[max_time, batch_size, cell.output_size]
的Tensor。cell。batch_size:批次数;max_time:序列集的序列个数,cell.output_size即循环网络神经元的个数,由inputs的神经元个数决定。
假设我们有时间序列的循环神经网络,100批次,50个时间点,100个神经元,则默认shape情况下根据batch_size、max_time切片可以得到特定批次、特定时间点的cell.output_size神经元的输出,如outoputs[0,24,99]表示1批次25时间点的数据传入后Cell的输出h(x)。
state:
- 记录最后一个序列传入之后计算得到的输出,一般情况下state的形状为 [batch_size, cell.output_size ]。
- 但当输入的cell为BasicLSTMCell时,state的形状为[2,batch_size, cell.output_size ],其中2也对应着LSTM中的cell state和hidden state。如,state[0]:表示最后一个序列传入后的Cell_state,即最后一个序列传入后的细胞状态。state[1]:表示最后一个序列传后的hidden_state,即最后一个序列传后的Cell的输出。
更具体的可以查看:https://blog.csdn.net/u010960155/article/details/81707498
二、代码示例
import tensorflow as tf from tensorflow.examples.tutorials.mnist import input_data # 读取数据 mnist = input_data.read_data_sets('MNIST_data/', one_hot=True) # 由于mnist数据是28*28的数据,所以可以看成28个序列,每个序列为1*28的数据,这样就构造了一个序列数据 n_input = 1 * 28 # 输入序列集中列数据属性数 max_time = 28 # 每次输入序列数据的序列个数 lstm_size = 100 # lstm的隐藏层的神经元个数为100 n_class=10 #手写字最终分为0-9一共10类 batch_size = 50 # 批次个数为50 n_batch = mnist.train.num_examples // batch_size # 计算有几个批次 #输入与标签占位符 x=tf.placeholder(tf.float32,[None,784]) y=tf.placeholder(tf.float32,[None,10]) #权重与偏置,这里是最后估计值的y'=Wh+b weights = tf.Variable(tf.random_normal([lstm_size, n_class])) biases = tf.Variable(tf.constant(0.1),[n_class]) #定义一个RNN网络 def RNN(x,weights,biases): #输入x转化为固定形式数据 inputs=tf.reshape(x,[-1,max_time,n_input]) #定义基本的lstm的cell lstm_cell=tf.contrib.rnn.BasicLSTMCell(lstm_size) #定义动态的rnn网络 outputs,final_state=tf.nn.dynamic_rnn(cell=lstm_cell,inputs=inputs,dtype=tf.float32,time_major=False) #计算估计值,这里不用激活函数,因为loss函数会调用softmax进行处理 result=tf.matmul(final_state[1],weights)+biases return result #计算拟合值 prediction=RNN(x,weights,biases) #定义交叉熵损失函数 cross_entropy=tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=prediction) #使用Adam梯度下降法训练模型 train=tf.train.AdamOptimizer(0.001,0.9,0.999).minimize(cross_entropy) # 初始化 init = tf.global_variables_initializer() # 结果存放在bool型列表汇总 correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(prediction, 1)) # 计算准确度,并加入到总结指令 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) with tf.Session() as sess: sess.run(init) # 训练20代 for epoch in range(20): # 每代对数据进行一轮minibatch for batch in range(n_batch): batch_x, batch_y = mnist.train.next_batch(batch_size) # 每个循环读取batch_size大小批次的数据 sess.run(train, feed_dict={x: batch_x, y: batch_y}) acc = sess.run(accuracy, feed_dict={x: mnist.test.images, y: mnist.test.labels}) # 用测试数据计算准确度 if batch % 99 == 0: print('第%d代%d批次,准确率为%.6f' % (epoch + 1, batch + 1, acc))