Tensorflow, cómo acceder a todos los estados medios de un RNN, no solo el último estado

Entiendo que tf.nn.dynamic_rnn devuelve la salida de una celda RNN (por ejemplo, LSTM) en cada paso de tiempo, así como el estado final. ¿Cómo puedo acceder a los estados de las celdas en todos los pasos de tiempo, no solo el último? Por ejemplo, quiero poder promediar todos los estados ocultos y luego usarlos en la capa siguiente.

La siguiente es cómo defino una celda LSTM y luego la desenrollo usando tf.nn.dynamic_rnn . Pero esto solo da el estado de la última celda de la 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) 

Algo como esto debería funcionar.

 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) 

Esto utiliza estados concatenados, ya que no sé si puede almacenar un número arbitrario de estados de tupla. La variable de estados es de forma (batch_size, max_time_size, state_size).

Te dirijo a este hilo (lo más destacado de mí):

Puede escribir una variante del LSTMCell que devuelva ambos tensores de estado como parte de la salida, si necesita los estados c y h para cada paso de tiempo. Si solo necesita el estado h , esa es la salida de cada paso de tiempo .

Como @jasekp escribió en su comentario, la salida es realmente la parte h del estado. Luego, el método dynamic_rnn solo dynamic_rnn toda la parte h a lo largo del tiempo (consulte la cadena de documentos de _dynamic_rnn_loop en este archivo ):

 def _dynamic_rnn_loop(cell, inputs, initial_state, parallel_iterations, swap_memory, sequence_length=None, dtype=None): """Internal implementation of Dynamic RNN. [...] Returns: Tuple `(final_outputs, final_state)`. final_outputs: A `Tensor` of shape `[time, batch_size, cell.output_size]`. If `cell.output_size` is a (possibly nested) tuple of ints or `TensorShape` objects, then this returns a (possibly nsted) tuple of Tensors matching the corresponding shapes.