Python Tensorflow,如何访问RNN的所有中间状态,而不仅仅是最后一个状态

Python Tensorflow,如何访问RNN的所有中间状态,而不仅仅是最后一个状态,python,tensorflow,Python,Tensorflow,我的理解是tf.nn.dynamic\u rnn返回rnn单元(例如LSTM)在每个时间步的输出以及最终状态。如何在所有时间步(而不仅仅是最后一步)中访问单元状态?例如,我希望能够平均所有隐藏状态,然后在后续层中使用它 下面是我如何定义一个LSTM单元格,然后使用tf.nn.dynamic\u rnn展开它。但这只给出了LSTM的最后一个单元状态 import tensorflow as tf import numpy as np # [batch-size, sequence-length,

我的理解是
tf.nn.dynamic\u rnn
返回rnn单元(例如LSTM)在每个时间步的输出以及最终状态。如何在所有时间步(而不仅仅是最后一步)中访问单元状态?例如,我希望能够平均所有隐藏状态,然后在后续层中使用它

下面是我如何定义一个LSTM单元格,然后使用
tf.nn.dynamic\u rnn
展开它。但这只给出了LSTM的最后一个单元状态

import tensorflow as tf
import numpy as np

# [batch-size, sequence-length, dimensions] 
X = np.random.randn(2, 10, 8)
X[1,6:] = 0
X_lengths = [10, 6]

cell = tf.contrib.rnn.LSTMCell(num_units=64, state_is_tuple=True)

outputs, last_state = tf.nn.dynamic_rnn(
    cell=cell,
    dtype=tf.float64,
    sequence_length=X_lengths,
    inputs=X)
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())                                 
out, last = sess.run([outputs, last_state], feed_dict=None)
我想向您指出这一点(我的重点):

如果每个时间步都需要c和h状态,则可以编写一个LSTMCell变量,将两个状态张量作为输出的一部分返回。如果只需要h状态,则这是每个时间步的输出

正如@jasekp在其评论中所写,输出实际上是状态的
h
部分。然后
dynamic\u rnn
方法将只在一段时间内堆叠所有
h
部分(请参阅中
\u dynamic\u rnn\u loop
的字符串doc):


这样的办法应该行得通

import tensorflow as tf
import numpy as np


class CustomRNN(tf.contrib.rnn.LSTMCell):
    def __init__(self, *args, **kwargs):
        kwargs['state_is_tuple'] = False # force the use of a concatenated state.
        returns = super(CustomRNN, self).__init__(*args, **kwargs) # create an lstm cell
        self._output_size = self._state_size # change the output size to the state size
        return returns
    def __call__(self, inputs, state):
        output, next_state = super(CustomRNN, self).__call__(inputs, state)
        return next_state, next_state # return two copies of the state, instead of the output and the state

X = np.random.randn(2, 10, 8)
X[1,6:] = 0
X_lengths = [10, 10]

cell = CustomRNN(num_units=64)

outputs, last_states = tf.nn.dynamic_rnn(
    cell=cell,
    dtype=tf.float64,
    sequence_length=X_lengths,
    inputs=X)

sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())                                 
states, last_state = sess.run([outputs, last_states], feed_dict=None)

这使用连接状态,因为我不知道是否可以存储任意数量的元组状态。states变量的形状为(批大小、最大时间大小、状态大小)。

没有理由需要访问不属于输出的内部状态。如果这是您的用例,我希望定义一个与LSTM相同但输出其完整状态的RNN。看看这个QA:或者这个LSTMCell只是一个单元格,如果我没有弄错的话,它将返回状态和输出。我认为
tf.nn.dynamic\u rnn
的展开部分只返回最后一步。所以,我需要修改它?奇怪的是,目前还没有更高级别的解决方案。您能详细说明一下CustomRNN代码如何返回中间状态吗?我正在努力理解你的代码!LSTM状态是输出(m)和隐藏状态(c)的组合。此代码获取输出(m)并将其替换为串联状态(c+m)。不考虑批量大小,输出是[(c1+m1),(c2+m2),…]的列表,而不是[m1,m2,…]。因此,这将用隐藏状态(c)替换实际输出(m),对不对(
返回下一个\u状态,下一个\u状态
而不是
返回m,新的\u状态
)?在哪里连接输出和隐藏状态(
m+c
)?
new\u state
对于LSTM是(c+m),因此返回
new\u state,new\u state
将用(c+m)替换输出m。请参见实现中的。
import tensorflow as tf
import numpy as np


class CustomRNN(tf.contrib.rnn.LSTMCell):
    def __init__(self, *args, **kwargs):
        kwargs['state_is_tuple'] = False # force the use of a concatenated state.
        returns = super(CustomRNN, self).__init__(*args, **kwargs) # create an lstm cell
        self._output_size = self._state_size # change the output size to the state size
        return returns
    def __call__(self, inputs, state):
        output, next_state = super(CustomRNN, self).__call__(inputs, state)
        return next_state, next_state # return two copies of the state, instead of the output and the state

X = np.random.randn(2, 10, 8)
X[1,6:] = 0
X_lengths = [10, 10]

cell = CustomRNN(num_units=64)

outputs, last_states = tf.nn.dynamic_rnn(
    cell=cell,
    dtype=tf.float64,
    sequence_length=X_lengths,
    inputs=X)

sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())                                 
states, last_state = sess.run([outputs, last_states], feed_dict=None)