本文主要是介绍tf.nn.dynamic_rnn的输出outputs和state含义,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
写在最前面:个人总结:
tf.nn.dynamic_rnn的返回值有两个:outputs和state
outputs:RNN/LSTM/GRU 的每个time_step都有一个输出,outputs把每个timestep的输出增加一个维度,并沿时间顺序在该维度串联。outputs.shape=[batch_size, max_time, hidden_size],要想取某个time_step的输出,只需要用对应的索引即可:output_timestep_k = outputs[:,k,:]
state:记录RNN/LSTM/GRU的最后一个time_step的cell状态,以LSTM为例子,state=(c,h),c代表最后一个step的Ct,h代表最后一个step的ht. 其中ht与outputs[:,-1,:]相等,是同一个东西。
---------------------------------------------------------------------------------------------------------------------------------------------------
以下是转载的具体内容,原文链接:https://blog.csdn.net/u010960155/article/details/81707498
-----------------------------------------------------------------------------------------------------------------------------------------------------
一、 tf.nn.dynamic_rnn的输出
tf.nn.dynamic_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)
tf.nn.dynamic_rnn的返回值有两个:outputs和state
为了描述输出的形状,先介绍几个变量,batch_size是输入的这批数据的数量,max_time就是这批数据中序列的最长长度,如果输入的三个句子,那max_time对应的就是最长句子的单词数量,cell.output_size其实就是rnn cell中神经元的个数。
outputs. outputs是一个tensor
如果time_major==True,outputs形状为 [max_time, batch_size, cell.output_size ](要求rnn输入与rnn输出形状保持一致)
如果time_major==False(默认),outputs形状为 [ batch_size, max_time, cell.output_size ]
state. state是一个tensor。state是最终的状态,也就是序列中最后一个cell输出的状态。一般情况下state的形状为 [batch_size, cell.output_size ],但当输入的cell为BasicLSTMCell时,state的形状为[2,batch_size, cell.output_size ],其中2也对应着LSTM中的cell state和hidden state
那为什么state输出形状会有变化呢?state和output又有什么关系呢?
二、state含义
对于第一问题“state”形状为什么会发生变化呢?
我们以LSTM和GRU分别为tf.nn.dynamic_rnn的输入cell类型为例,当cell为LSTM,state形状为[2,batch_size, cell.output_size ];当cell为GRU时,state形状为[batch_size, cell.output_size ]。其原因是因为LSTM和GRU的结构本身不同,如下面两个图所示,这是LSTM的cell结构,每个cell会有两个输出:Ct 和 ht,上面这个图是输出Ct,代表哪些信息应该被记住哪些应该被遗忘; 下面这个图是输出ht,代表这个cell的最终输出,LSTM的state是由Ct 和 ht组成的。
当cell为GRU时,state就只有一个了,原因是GRU将Ct 和 ht进行了简化,将其合并成了ht,如下图所示,GRU将遗忘门和输入门合并成了更新门,另外cell不在有细胞状态cell state,只有hidden state。
对于第二个问题outputs和state有什么关系?
结论上来说,如果cell为LSTM,那 state是个tuple,分别代表Ct 和 ht,其中 ht与outputs中的对应的最后一个时刻的输出相等,假设state形状为[ 2,batch_size, cell.output_size ],outputs形状为 [ batch_size, max_time, cell.output_size ],那么state[ 1, batch_size, : ] == outputs[ batch_size, -1, : ];如果cell为GRU,那么同理,state其实就是 ht,state ==outputs[ -1 ]
三、实验
我们写点代码来具体感觉下outputs和state是什么,代码如下
import tensorflow as tfimport numpy as npdef dynamic_rnn(rnn_type='lstm'):# 创建输入数据,3代表batch size,6代表输入序列的最大步长(max time),8代表每个序列的维度X = np.random.randn(3, 6, 4)# 第二个输入的实际长度为4X[1, 4:] = 0#记录三个输入的实际步长X_lengths = [6, 4, 6]rnn_hidden_size = 5if rnn_type == 'lstm':cell = tf.contrib.rnn.BasicLSTMCell(num_units=rnn_hidden_size, state_is_tuple=True)else:cell = tf.contrib.rnn.GRUCell(num_units=rnn_hidden_size)outputs, last_states = tf.nn.dynamic_rnn(cell=cell,dtype=tf.float64,sequence_length=X_lengths,inputs=X)with tf.Session() as session:session.run(tf.global_variables_initializer())o1, s1 = session.run([outputs, last_states])print(np.shape(o1))print(o1)print(np.shape(s1))print(s1)if __name__ == '__main__':dynamic_rnn(rnn_type='lstm')
实验一:cell类型为LSTM,我们看看输出是什么样子,如下图所示,输入的形状为 [ 3, 6, 4 ],经过tf.nn.dynamic_rnn后outputs的形状为 [ 3, 6, 5 ],state形状为 [ 2, 3, 5 ],其中state第一部分为c,代表cell state;第二部分为h,代表hidden state。可以看到hidden state 与 对应的outputs的最后一行是相等的。另外需要注意的是输入一共有三个序列,但第二个序列的长度只有4,可以看到outputs中对应的两行值都为0,所以hidden state对应的是最后一个不为0的部分。tf.nn.dynamic_rnn通过设置sequence_length来实现这一逻辑。
(3, 6, 5)[[[ 0.0146346 -0.04717453 -0.06930042 -0.06065602 0.02456717][-0.05580321 0.08770171 -0.04574306 -0.01652854 -0.04319528][ 0.09087799 0.03535907 -0.06974291 -0.03757408 -0.15553619][ 0.10003044 0.10654698 0.21004055 0.13792148 -0.05587583][ 0.13547596 -0.014292 -0.0211154 -0.10857875 0.04461256][ 0.00417564 -0.01985144 0.00050634 -0.13238986 0.14323784]][[ 0.04893576 0.14289175 0.17957205 0.09093887 -0.0507192 ][ 0.17696126 0.09929577 0.21185635 0.20386451 0.11664373][ 0.15658667 0.03952745 -0.03425637 0.00773833 -0.03546742][-0.14002582 -0.18578786 -0.08373584 -0.25964601 0.04090167][ 0. 0. 0. 0. 0. ][ 0. 0. 0. 0. 0. ]][[ 0.18564152 0.01531695 0.13752453 0.17188506 0.19555427][ 0.13703949 0.14272294 0.21313036 0.07417354 0.0477547 ][ 0.23021792 0.04455495 0.10204565 0.17159792 0.34148467][ 0.0386402 0.0387848 0.02134559 0.00110381 0.08414687][ 0.01386241 -0.02629686 -0.0733538 -0.03194245 0.13606553][ 0.01859433 -0.00585316 -0.04007138 0.03811594 0.21708331]]](2, 3, 5)LSTMStateTuple(c=array([[ 0.00909146, -0.03747076, 0.0008946 , -0.23459786, 0.29565899],[-0.18409266, -0.30463044, -0.28033809, -0.49032542, 0.12597639],[ 0.04494702, -0.01359631, -0.06706629, 0.06766361, 0.40794032]]), h=array([[ 0.00417564, -0.01985144, 0.00050634, -0.13238986, 0.14323784],[-0.14002582, -0.18578786, -0.08373584, -0.25964601, 0.04090167],[ 0.01859433, -0.00585316, -0.04007138, 0.03811594, 0.21708331]]))
实验二:cell类型为GRU,我们看看输出是什么样子,如下图所示,输入的形状为 [ 3, 6, 4 ],经过tf.nn.dynamic_rnn后outputs的形状为 [ 3, 6, 5 ],state形状为 [ 3, 5 ]。可以看到 state 与 对应的outputs的最后一行是相等的。
(3, 6, 5)
[[[-0.05190962 -0.13519617 0.02045928 -0.0821183 0.28337528][ 0.0201574 0.03779418 -0.05092804 0.02958051 0.12232347][ 0.14884441 -0.26075898 0.1821795 -0.03454954 0.18424161][-0.13854156 -0.26565378 0.09567164 -0.03960079 0.14000589][-0.2605973 -0.39901657 0.12495693 -0.19295695 0.52423598][-0.21596414 -0.63051687 0.20837501 -0.31775378 0.77519457]][[-0.1979659 -0.30253523 0.0248779 -0.17981144 0.41815343][ 0.34481129 -0.05256187 0.1643036 0.00739746 0.27384158][ 0.49703664 0.22241165 0.27344766 0.00093435 0.09854949][ 0.23312444 0.156997 0.25482553 0.0138156 -0.02302272][ 0. 0. 0. 0. 0. ][ 0. 0. 0. 0. 0. ]][[-0.06401732 0.08605342 -0.03936866 -0.02287695 0.16947652][-0.1775206 -0.2801672 -0.0387468 -0.20264583 0.58125297][ 0.39408762 -0.44066425 0.25826641 -0.18851604 0.36172166][ 0.0536013 -0.29902928 0.08891931 -0.03930039 0.0743423 ][ 0.02304702 -0.0612499 0.09113458 -0.05169013 0.29876455][-0.06711324 0.014125 -0.05856332 -0.05632359 -0.00390189]]]
(3, 5)
[[-0.21596414 -0.63051687 0.20837501 -0.31775378 0.77519457][ 0.23312444 0.156997 0.25482553 0.0138156 -0.02302272][-0.06711324 0.014125 -0.05856332 -0.05632359 -0.00390189]]
这篇关于tf.nn.dynamic_rnn的输出outputs和state含义的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!