Прогнозирование следующего слова на примере тензорного потока модели LSTM ptb
Я пытаюсь использовать тензор потокаМодель LSTM делать предсказания следующего слова.
Как описано в этомсвязанный вопрос (который не имеет принятого ответа) пример содержит псевдокод для извлечения вероятностей следующего слова:
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)
Я не понимаю, как интерпретировать вектор вероятностей. Я модифицировал__init__
функцияPTBModel
вptb_word_lm.py хранить вероятности и логиты:
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 ...
Затем напечатал некоторую информацию о них вrun_epoch
функция:
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)
Это производит вывод как это:
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
Я ожидалprobs
вектор, чтобы быть массивом вероятностей, с одним для каждого слова в словаре (например, с формой(1, vocab_size)
), что означает, что я мог получить предсказанное слово, используяnp.argmax(probs, 1)
как предложено в другом вопросе.
Однако первое измерение вектора фактически равно количеству шагов в развернутом LSTM (20, если используются небольшие настройки конфигурации), что я не уверен, что делать. Чтобы получить доступ к предсказанному слову, мне просто нужно использовать последнее значение (потому что это вывод последнего шага)? Или я что-то пропустил?
Я попытался понять, как прогнозы делаются и оцениваются, глядя на реализациюseq2seq.sequence_loss_by_example, который должен выполнить эту оценку, но это в конечном итоге вызываетgen_nn_ops._sparse_softmax_cross_entropy_with_logits
, который, кажется, не включен в репозиторий github, поэтому я не уверен, где еще искать.
Я довольно новичок в тензорном потоке и LSTM, поэтому любая помощь приветствуется!