将一个序列编码为一个向量。输入一批固定长度的特征向量序列(三维),输出整个序列的特征表示:
函数原型为:
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:单个rnn单元,RNNCell的实例,可以是rnn,LSTM等
input:输入,三维张量
time_major:输入和输出张量每一维的含义,默认为False,则认为输入的是[batch_size,max_time,input_size]的张量,当设置为True时,则认为输入的是[max_time,batch_size,input_size]的张量
initial_state:初始状态
sequence_length:如果当前时间步的index超过该序列的实际长度时,则该时间步不进行计算,RNN的state复制上一个时间步的,同时该时间步的输出全部为零。所以要想得到正确的符合序列本身长度的输出,还要经过一步tf.gather_nd(参见https://blog.csdn.net/Hello_word5/article/details/103464426)
返回值:一对(outputs,state)
实例(参考https://www.jianshu.com/p/f89c7f540f6e):
先看单层rnn的情况:
import tensorflow as tf
import numpy as np
n_steps=2
input_dim=3
hidden_dim=5
basic_cell=tf.contrib.rnn.BasicRNNCell(hidden_dim)
X=tf.placeholder(tf.float32,[None,n_steps,input_dim])
seq_length=tf.placeholder(tf.int32,[None])
outputs,states=tf.nn.dynamic_rnn(basic_cell,inputs=X,dtype=tf.float32,sequence_length=seq_length)
X_batch = np.array([
# step 0 step 1
[[0, 1, 2], [9, 8, 7]], # instance 1
[[3, 4, 5], [0, 0, 0]], # instance 2
[[6, 7, 8], [6, 5, 4]], # instance 3
[[9, 0, 1], [3, 2, 1]], # instance 4
])
seq_length_batch=np.array([2,1,2,2])#规定每个样本取得时间步数,虽然处理数据时我们pad了很多0,但这里算的其实是真实的序列长度
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
outputs,states=sess.run([outputs,states],feed_dict={X:X_batch,seq_length:seq_length_batch})
print("outputs.shape:", outputs.shape, "states.shape:", states.shape)
这里的输出为:outputs_val.shape: (4, 2, 5) states_val.shape: (4, 5)
上面的代码搭建的RNN网络如下图所示:
注意:state的值即是outputs的最后一步的值
下面再看多个隐藏层时的情形,这里以BasicLSTMCell做为基本的神经元
import tensorflow as tf
import numpy as np
n_steps=2
input_dim=3
hidden_dim=5
n_layers=3
# basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=hidden_dim)
layers=[tf.contrib.rnn.BasicLSTMCell(num_units=hidden_dim,activation=tf.nn.relu) for i in range(n_layers)]
multi_layer_cell=tf.contrib.rnn.MultiRNNCell(layers)
X=tf.placeholder(tf.float32,[None,n_steps,input_dim])
seq_length=tf.placeholder(tf.int32,[None])
outputs,states=tf.nn.dynamic_rnn(multi_layer_cell,inputs=X,dtype=tf.float32,sequence_length=seq_length)
X_batch = np.array([
# step 0 step 1
[[0, 1, 2], [9, 8, 7]], # instance 1
[[3, 4, 5], [0, 0, 0]], # instance 2
[[6, 7, 8], [6, 5, 4]], # instance 3
[[9, 0, 1], [3, 2, 1]], # instance 4
])
seq_length_batch=np.array([2,1,2,2])
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
outputs,states=sess.run([outputs,states],feed_dict={X:X_batch,seq_length:seq_length_batch})
print("outputs:", outputs, "states:", states)
这里的outputs的size还是(4, 2, 5),但state是个元组,元组中每个元素是个二元组(这个二元组中的每个元素的size是[batch_size,hidden_dim]),表示LSTM的两种输出状态(如果基本单元仍是RNN,则多层时的输出状态仍是元组,但元组中每个元组是一个张量)
此时构建的网络结构如下:
来源:CSDN
作者:YY.net
链接:https://blog.csdn.net/Hello_word5/article/details/103462954