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.