使用RNN张量流语言模型来预测测试句子的概率

时间:2015-12-08 10:50:57

标签: python machine-learning nlp tensorflow linguistics

我能够使用tensorflow tutorials训练语言模型,模型根据code given here保存为检查点文件。

save_path = saver.save(sess, "/tmp/model.epoch.%03d.ckpt" % (i + 1))

现在我需要恢复检查点并在以下代码中使用它:

    def run_epoch(session, m, data, eval_op, verbose=False):
  """Runs the model on the given data."""
  epoch_size = ((len(data) // m.batch_size) - 1) // m.num_steps
  start_time = time.time()
  costs = 0.0
  iters = 0
  state = m.initial_state.eval()
  for step, (x, y) in enumerate(reader.ptb_iterator(data, m.batch_size,
                                                    m.num_steps)):
    cost, state, _ = session.run([m.cost, m.final_state, 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" %
            (step * 1.0 / epoch_size, np.exp(costs / iters),
             iters * m.batch_size / (time.time() - start_time)))

  return np.exp(costs / iters)

我无法找到任何编码测试句子的方法,也无法从训练有素的检查点模型中获得句子概率输出。

教程提到以下代码:

 probabilities = tf.nn.softmax(logits)

但它是用于训练,我无法弄清楚如何获得实际概率。 我应该理想地得到类似的东西:

>>getprob('this is a temp sentence')
>>0.322

3 个答案:

答案 0 :(得分:4)

我有同样的问题,我认为我找到了解决方法,但我不是专家,所以欢迎评论!

在PTBModel类中,您需要添加以下行:

    self._proba = tf.nn.softmax(logits)

在此循环之前(或之内):

    if not is_training:
        return

并添加此属性:

      @property
      def proba(self):
          return self._proba

现在在run_epoch函数中,您可以使用以下内容获取概率:

    cost, state, proba, _ = session.run([m.cost, m.final_state, m.proba, eval_op],...

从这里你应该可以通过proba访问所有概率。可能有更好的方法...... 希望这有帮助!

答案 1 :(得分:1)

您首先应该知道如何计算分数。由于马尔可夫假设,我们不需要计算太多(基于链规则)。应该解决的只是以下几个词的概率(为方便起见,我们说一个)。然后关键变成如何计算下一个单词的比率。

probab = session.run(myours.proba], feed_dict) # only the input is needed

你应该创建一个名为myours的模型,如@ Romain的回答中描述的那样(我的只是一个补充)。并创建自己的ptb_iterator以仅产生x(首先应该使用raw_input或其他来在循环中获取您的单词)。

for i in range(epoch_size):                   
    x = data[:, i*num_steps:(i+1)*num_steps]  
    yield x # the old one with y is better, use y to locate the probability of the coming word 

现在您有可能完成语言模型可以执行的所有操作。例如,预测下一个单词。

list(probab[0]).index(max(probab[0])) #  an id_to_word dict should be created

对于n字句,您将获得n-1个分数(更准确地说是词汇长度的n-1概率分布,并且您应该根据即将出现的词的索引选择一个)。

我用这种方式来计算得分(不确定是否正确或错误,我遇到与this one相同的问题):

pro += math.log(list(probab[0])[y[0]], 2)

PS:

  1. 为了节省您的时间,您可以在第一次训练网络时将变量保存在会话中 每次想要自己进行测试时都要恢复它。

    save_path = saver.save(session,“。/ tmp / mode.epoch。%03d.ckpt”%(i + 1)) saver.restore(session,“。/ tmp / model.epoch.013.ckpt”)#only last one

  2. 还需要一个句子到ids功能:

    返回[word_to_id [word]如果word_to_id中的单词,则为word_to_id ["<unk>"]中的单词,用于nltk.tokenize.word_tokenize(句子)中的单词]

  3. 希望这有助于解释您的问题并且足够解释。

答案 2 :(得分:0)

词汇表中应该有开始符号(SOS或其他)和结束符号(EOS或其他),您可以获取结束符号的索引,然后在proba中获取相应的概率值。