Predecir la siguiente palabra usando el ejemplo de tensorflow del modelo LSTM ptb

Estoy tratando de usar el tensorflowModelo LSTM para hacer predicciones de la siguiente palabra.

Como se describe en estepregunta relacionada (que no tiene respuesta aceptada) el ejemplo contiene pseudocódigo para extraer las probabilidades de la siguiente palabra:

lstm = rnn_cell.BasicLSTMCell(lstm_size)
# Initial state of the LSTM memory.
state = tf.zeros([batch_size, lstm.state_size])

loss = 0.0
for current_batch_of_words in words_in_dataset:
  # The value of state is updated after processing each batch of words.
  output, state = lstm(current_batch_of_words, state)

  # The LSTM output can be used to make next word predictions
  logits = tf.matmul(output, softmax_w) + softmax_b
  probabilities = tf.nn.softmax(logits)
  loss += loss_function(probabilities, target_words)

Estoy confundido acerca de cómo interpretar el vector de probabilidades. Modifiqué el__init__ función de laPTBModel enptb_word_lm.py para almacenar las probabilidades y logits:

class PTBModel(object):
  """The PTB model."""

  def __init__(self, is_training, config):
    # General definition of LSTM (unrolled)
    # identical to tensorflow example ...     
    # omitted for brevity ...


    # computing the logits (also from example code)
    logits = tf.nn.xw_plus_b(output,
                             tf.get_variable("softmax_w", [size, vocab_size]),
                             tf.get_variable("softmax_b", [vocab_size]))
    loss = seq2seq.sequence_loss_by_example([logits],
                                            [tf.reshape(self._targets, [-1])],
                                            [tf.ones([batch_size * num_steps])],
                                            vocab_size)
    self._cost = cost = tf.reduce_sum(loss) / batch_size
    self._final_state = states[-1]

    # my addition: storing the probabilities and logits
    self.probabilities = tf.nn.softmax(logits)
    self.logits = logits

    # more model definition ...

Luego imprimí alguna información sobre ellos en elrun_epoch función:

def run_epoch(session, m, data, eval_op, verbose=True):
  """Runs the model on the given data."""
  # first part of function unchanged from example

  for step, (x, y) in enumerate(reader.ptb_iterator(data, m.batch_size,
                                                    m.num_steps)):
    # evaluate proobability and logit tensors too:
    cost, state, probs, logits, _ = session.run([m.cost, m.final_state, m.probabilities, m.logits, eval_op],
                                 {m.input_data: x,
                                  m.targets: y,
                                  m.initial_state: state})
    costs += cost
    iters += m.num_steps

    if verbose and step % (epoch_size // 10) == 10:
      print("%.3f perplexity: %.3f speed: %.0f wps, n_iters: %s" %
            (step * 1.0 / epoch_size, np.exp(costs / iters),
             iters * m.batch_size / (time.time() - start_time), iters))
      chosen_word = np.argmax(probs, 1)
      print("Probabilities shape: %s, Logits shape: %s" % 
            (probs.shape, logits.shape) )
      print(chosen_word)
      print("Batch size: %s, Num steps: %s" % (m.batch_size, m.num_steps))

  return np.exp(costs / iters)

Esto produce resultados como este:

0.000 perplexity: 741.577 speed: 230 wps, n_iters: 220
(20, 10000) (20, 10000)
[ 14   1   6 589   1   5   0  87   6   5   3   5   2   2   2   2   6   2  6   1]
Batch size: 1, Num steps: 20

Esperaba elprobs vector para ser un conjunto de probabilidades, con una para cada palabra en el vocabulario (por ejemplo, con forma(1, vocab_size)), lo que significa que podría obtener la palabra predicha usandonp.argmax(probs, 1) como se sugiere en la otra pregunta.

Sin embargo, la primera dimensión del vector es en realidad igual al número de pasos en el LSTM desenrollado (20 si se usan las configuraciones de configuración pequeñas), con lo que no estoy seguro de qué hacer. Para acceder a la palabra predicha, ¿solo necesito usar el último valor (porque es la salida del paso final)? ¿O hay algo más que me estoy perdiendo?

Traté de entender cómo se hacen y evalúan las predicciones al observar la implementación deseq2seq.sequence_loss_by_example, que debe realizar esta evaluación, pero esto termina llamandogen_nn_ops._sparse_softmax_cross_entropy_with_logits, que no parece estar incluido en el repositorio de github, por lo que no estoy seguro de dónde buscar.

Soy bastante nuevo tanto en tensorflow como en LSTM, por lo que agradezco cualquier ayuda.

Respuestas a la pregunta(2)

Su respuesta a la pregunta