tf.nn.dynamic_rnn的输出outputs和state含义

2024-02-07 14:48

本文主要是介绍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含义的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/688054

相关文章

pytorch之torch.flatten()和torch.nn.Flatten()的用法

《pytorch之torch.flatten()和torch.nn.Flatten()的用法》:本文主要介绍pytorch之torch.flatten()和torch.nn.Flatten()的用... 目录torch.flatten()和torch.nn.Flatten()的用法下面举例说明总结torch

SpringBoot利用dynamic-datasource-spring-boot-starter解决多数据源问题

《SpringBoot利用dynamic-datasource-spring-boot-starter解决多数据源问题》dynamic-datasource-spring-boot-starter是一... 目录概要整体架构构想操作步骤创建数据源切换数据源后续问题小结概要自己闲暇时间想实现一个多租户平台,

python多种数据类型输出为Excel文件

《python多种数据类型输出为Excel文件》本文主要介绍了将Python中的列表、元组、字典和集合等数据类型输出到Excel文件中,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录一.列表List二.字典dict三.集合set四.元组tuplepython中的列表、元组、字典

Spring AI集成DeepSeek实现流式输出的操作方法

《SpringAI集成DeepSeek实现流式输出的操作方法》本文介绍了如何在SpringBoot中使用Sse(Server-SentEvents)技术实现流式输出,后端使用SpringMVC中的S... 目录一、后端代码二、前端代码三、运行项目小天有话说题外话参考资料前面一篇文章我们实现了《Spring

Rust格式化输出方式总结

《Rust格式化输出方式总结》Rust提供了强大的格式化输出功能,通过std::fmt模块和相关的宏来实现,主要的输出宏包括println!和format!,它们支持多种格式化占位符,如{}、{:?}... 目录Rust格式化输出方式基本的格式化输出格式化占位符Format 特性总结Rust格式化输出方式

使用TomCat,service输出台出现乱码的解决

《使用TomCat,service输出台出现乱码的解决》本文介绍了解决Tomcat服务输出台中文乱码问题的两种方法,第一种方法是修改`logging.properties`文件中的`prefix`和`... 目录使用TomCat,service输出台出现乱码问题1解决方案问题2解决方案总结使用TomCat,

C++中实现调试日志输出

《C++中实现调试日志输出》在C++编程中,调试日志对于定位问题和优化代码至关重要,本文将介绍几种常用的调试日志输出方法,并教你如何在日志中添加时间戳,希望对大家有所帮助... 目录1. 使用 #ifdef _DEBUG 宏2. 加入时间戳:精确到毫秒3.Windows 和 MFC 中的调试日志方法MFC

Python使用Colorama库美化终端输出的操作示例

《Python使用Colorama库美化终端输出的操作示例》在开发命令行工具或调试程序时,我们可能会希望通过颜色来区分重要信息,比如警告、错误、提示等,而Colorama是一个简单易用的Python库... 目录python Colorama 库详解:终端输出美化的神器1. Colorama 是什么?2.

C# dynamic类型使用详解

《C#dynamic类型使用详解》C#中的dynamic类型允许在运行时确定对象的类型和成员,跳过编译时类型检查,适用于处理未知类型的对象或与动态语言互操作,dynamic支持动态成员解析、添加和删... 目录简介dynamic 的定义dynamic 的使用动态类型赋值访问成员动态方法调用dynamic 的

顺序表之创建,判满,插入,输出

文章目录 🍊自我介绍🍊创建一个空的顺序表,为结构体在堆区分配空间🍊插入数据🍊输出数据🍊判断顺序表是否满了,满了返回值1,否则返回0🍊main函数 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以:点赞+关注+评论+收藏(一键四连)哦~ 🍊自我介绍   Hello,大家好,我是小珑也要变强(也是小珑),我是易编程·终身成长社群的一名“创始团队·嘉宾”