我能够使用tensorflow教程训练语言模型,根据此处给出的代码,这些模型被保存为检查点文件。
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
我也有同样的问题,我想我找到了解决办法,但我不是专家,所以欢迎评论!
在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],...
从这里你应该可以获得概率论的所有概率。也许还有更好的方法。。。希望这个帮助!
您首先应该知道如何计算分数。由于马尔可夫假设,我们不需要计算太多(基于链式规则)。应该计算出以下几个单词的概率(为了方便起见,我们说一个)。然后关键是如何计算下一个单词的比率。
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个词汇长度的概率分布,你应该根据下一个单词的索引来选择一个)。
我用这种方法来计算分数(还不确定它是对是错,我遇到了和这个相同的问题):
pro += math.log(list(probab[0])[y[0]], 2)
PS:
为了节省时间,您可以在第一次训练网络时将变量保存在会话中每次你想自己测试时都要恢复它。
save_path=saver.save(会话,"./tmp/model.ech.%03d.ckpt"%(i+1))saver.restore(会话,"./tmp/model.ech.013.ckpt")#仅最后一个
还需要一个语句到ids的函数:
return[word_to_id[word]if word in word_to_id else word_to_id=[
"<unk>"
]for word in nltk.tokenize.word_tokenize(句子)]
希望这能对你有所帮助,并且足以解释你的问题。
vocb中应该有开始符号(SOS或其他)和结束符号(EOS或其他)符号,您可以获得结束符号的索引,然后在proba中获得相应的概率值。