python tensorflow lstm recurrent-neural-network stateful

python - basic lstm cell tensorflow



TensorFlow: recuerde el estado LSTM para el próximo lote(LSTM con estado) (2)

Dado un modelo LSTM entrenado, quiero realizar inferencia para seq_length = 1 únicos, es decir, seq_length = 1 en el ejemplo a continuación. Después de cada paso de tiempo, los estados LSTM internos (memoria y ocultos) deben recordarse para el próximo ''lote''. Para el comienzo de la inferencia, los estados LSTM internos init_c, init_h se calculan dada la entrada. Estos se almacenan en un objeto LSTMStateTuple que se pasa al LSTM. Durante el entrenamiento, este estado se actualiza cada paso de tiempo. Sin embargo, por inferencia, quiero que el state se guarde entre lotes, es decir, los estados iniciales solo deben calcularse al principio y después de eso, los estados LSTM deben guardarse después de cada ''lote'' (n = 1).

Encontré esta pregunta relacionada con StackOverflow: Tensorflow, ¿la mejor manera de guardar el estado en RNN? . Sin embargo, esto solo funciona si state_is_tuple=False , pero TensorFlow pronto desaprobará este comportamiento (consulte rnn_cell.py ). Keras parece tener un buen envoltorio para hacer posibles LSTM con estado, pero no sé la mejor manera de lograr esto en TensorFlow. Este problema en el TensorFlow GitHub también está relacionado con mi pregunta: https://github.com/tensorflow/tensorflow/issues/2838

¿Alguien buenas sugerencias para construir un modelo LSTM con estado?

inputs = tf.placeholder(tf.float32, shape=[None, seq_length, 84, 84], name="inputs") targets = tf.placeholder(tf.float32, shape=[None, seq_length], name="targets") num_lstm_layers = 2 with tf.variable_scope("LSTM") as scope: lstm_cell = tf.nn.rnn_cell.LSTMCell(512, initializer=initializer, state_is_tuple=True) self.lstm = tf.nn.rnn_cell.MultiRNNCell([lstm_cell] * num_lstm_layers, state_is_tuple=True) init_c = # compute initial LSTM memory state using contents in placeholder ''inputs'' init_h = # compute initial LSTM hidden state using contents in placeholder ''inputs'' self.state = [tf.nn.rnn_cell.LSTMStateTuple(init_c, init_h)] * num_lstm_layers outputs = [] for step in range(seq_length): if step != 0: scope.reuse_variables() # CNN features, as input for LSTM x_t = # ... # LSTM step through time output, self.state = self.lstm(x_t, self.state) outputs.append(output)


Descubrí que era más fácil guardar todo el estado para todas las capas en un marcador de posición.

init_state = np.zeros((num_layers, 2, batch_size, state_size)) ... state_placeholder = tf.placeholder(tf.float32, [num_layers, 2, batch_size, state_size])

Luego, descomprímalo y cree una tupla de LSTMStateTuples antes de usar la API nativa de tensorflow RNN.

l = tf.unpack(state_placeholder, axis=0) rnn_tuple_state = tuple( [tf.nn.rnn_cell.LSTMStateTuple(l[idx][0], l[idx][1]) for idx in range(num_layers)] )

RNN pasa en la API:

cell = tf.nn.rnn_cell.LSTMCell(state_size, state_is_tuple=True) cell = tf.nn.rnn_cell.MultiRNNCell([cell]*num_layers, state_is_tuple=True) outputs, state = tf.nn.dynamic_rnn(cell, x_input_batch, initial_state=rnn_tuple_state)

La variable de state se alimentará al siguiente lote como marcador de posición.


Tensorflow, ¿la mejor manera de guardar el estado en RNN? En realidad fue mi pregunta original. El siguiente código es cómo uso las tuplas de estado.

with tf.variable_scope(''decoder'') as scope: rnn_cell = tf.nn.rnn_cell.MultiRNNCell / ([ tf.nn.rnn_cell.LSTMCell(512, num_proj = 256, state_is_tuple = True), tf.nn.rnn_cell.LSTMCell(512, num_proj = WORD_VEC_SIZE, state_is_tuple = True) ], state_is_tuple = True) state = [[tf.zeros((BATCH_SIZE, sz)) for sz in sz_outer] for sz_outer in rnn_cell.state_size] for t in range(TIME_STEPS): if t: last = y_[t - 1] if TRAINING else y[t - 1] else: last = tf.zeros((BATCH_SIZE, WORD_VEC_SIZE)) y[t] = tf.concat(1, (y[t], last)) y[t], state = rnn_cell(y[t], state) scope.reuse_variables()

En lugar de usar tf.nn.rnn_cell.LSTMStateTuple , simplemente creo una lista de listas que funciona bien. En este ejemplo no estoy salvando el estado. Sin embargo, podría haber hecho fácilmente el estado de las variables y simplemente utilizar asignar para guardar los valores.