【问题标题】:Predicting the next word using the LSTM ptb model tensorflow example使用 LSTM ptb 模型 tensorflow 示例预测下一个单词
【发布时间】:2016-07-17 03:27:17
【问题描述】:

我正在尝试使用 tensorflow LSTM model 进行下一个单词预测。

正如related question(没有接受的答案)中所述,该示例包含用于提取下一个单词概率的伪代码:

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)

我对如何解释概率向量感到困惑。我修改了ptb_word_lm.pyPTBModel__init__函数来存储概率和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 ...

然后在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 中repo,所以我不知道还能去哪里看。

我对 tensorflow 和 LSTM 都很陌生,因此感谢您的帮助!

【问题讨论】:

  • 我仍在寻找如何使用 LSTM 预测单词的答案。我也在寻找工作代码来做到这一点。

标签: python tensorflow lstm


【解决方案1】:

我也在实现 seq2seq 模型。

所以让我试着用我的理解来解释:

LSTM 模型的输出是一个大小为 [batch_sizesize 的二维张量的列表(长度为 num_steps]。

代码行:

output = tf.reshape(tf.concat(1, outputs), [-1, size])

将产生一个新的输出,它是一个大小为 [batch_size x num_steps, size] 的 2D 张量.

对于您的情况,batch_size = 1 和 num_steps = 20 --> 输出形状为 [20, size]。

代码行:

logits = tf.nn.xw_plus_b(output, tf.get_variable("softmax_w", [size, vocab_size]), tf.get_variable("softmax_b", [vocab_size]))

output[batch_size x num_steps, size] x softmax_w[size, vocab_size] 将输出 logits 大小为 [batch_size x num_steps, vocab_size]。
对于您的情况,logits 大小为 [20, vocab_size] --> probs 张量与 logits 的大小相同 [20, vocab_size]。

代码行:

chosen_word = np.argmax(probs, 1)

会输出chosen_word张量[20,1],每个值是当前单词的下一个预测词索引。

代码行:

loss = seq2seq.sequence_loss_by_example([logits], [tf.reshape(self._targets, [-1])], [tf.ones([batch_size * num_steps])])

是为 batch_size 个序列计算 softmax 交叉熵损失。

【讨论】:

    【解决方案2】:

    output 张量包含每个时间步长的 LSTM 单元输出的串联(参见其定义here)。因此,您可以通过使用chosen_word[-1](或chosen_word[sequence_length - 1],如果序列已被填充以匹配展开的 LSTM)来找到下一个单词的预测。

    tf.nn.sparse_softmax_cross_entropy_with_logits() 操作以不同的名称记录在公共 API 中。由于技术原因,它调用了一个没有出现在 GitHub 存储库中的生成的包装器函数。该操作的实现是在 C++ 中,here

    【讨论】:

    • 为什么选择_word[-1]? selected_word 的大小为 batch_size*num_steps。模型是否为每一步预测一个词?似乎是这样。似乎它正在预测下一个 num_steps 单词。对吗?
    • @eugenerory:答案假设您只对要预测的最后一个词感兴趣,而不是中间词。
    猜你喜欢
    • 2016-02-19
    • 2016-10-23
    • 1970-01-01
    • 2017-04-08
    • 2017-12-10
    • 1970-01-01
    • 2018-01-16
    • 2019-07-07
    • 2017-09-14
    相关资源
    最近更新 更多