使用 LSTM 教程代码预测句子中的下一个单词?

Posted

技术标签:

【中文标题】使用 LSTM 教程代码预测句子中的下一个单词?【英文标题】:Use LSTM tutorial code to predict next word in a sentence? 【发布时间】:2018-02-17 21:13:20 【问题描述】:

我一直在尝试用https://www.tensorflow.org/tutorials/recurrent 理解示例代码 你可以在https://github.com/tensorflow/models/blob/master/tutorials/rnn/ptb/ptb_word_lm.py找到它

(使用张量流 1.3.0。)

我总结了(我认为是)我的问题的关键部分,如下:

 size = 200
 vocab_size = 10000
 layers = 2
 # input_.input_data is a 2D tensor [batch_size, num_steps] of
 #    word ids, from 1 to 10000

 cell = tf.contrib.rnn.MultiRNNCell(
    [tf.contrib.rnn.BasicLSTMCell(size) for _ in range(2)]
    )

 embedding = tf.get_variable(
      "embedding", [vocab_size, size], dtype=tf.float32)
 inputs = tf.nn.embedding_lookup(embedding, input_.input_data)

inputs = tf.unstack(inputs, num=num_steps, axis=1)
outputs, state = tf.contrib.rnn.static_rnn(
    cell, inputs, initial_state=self._initial_state)

output = tf.reshape(tf.stack(axis=1, values=outputs), [-1, size])
softmax_w = tf.get_variable(
    "softmax_w", [size, vocab_size], dtype=data_type())
softmax_b = tf.get_variable("softmax_b", [vocab_size], dtype=data_type())
logits = tf.matmul(output, softmax_w) + softmax_b

# Then calculate loss, do gradient descent, etc.

我最大的问题是在给定句子的前几个单词的情况下,如何使用生成的模型实际生成下一个单词建议?具体来说,我想流程是这样的,但我无法理解注释行的代码是什么:

prefix = ["What", "is", "your"]
state = #Zeroes
# Call static_rnn(cell) once for each word in prefix to initialize state
# Use final output to set a string, next_word
print(next_word)

我的子问题是:

为什么要使用随机(未初始化、未经训练)的词嵌入? 为什么要使用 softmax? 隐藏层是否必须与输入的维度相匹配(即 word2vec 嵌入的维度) 我如何/可以引入预训练的 word2vec 模型,而不是未初始化的模型?

(我把它们都当作一个问题来问,因为我怀疑它们都是相互关联的,并且与我的理解中的一些差距有关。)

我期望在这里看到的是加载现有的 word2vec 词嵌入集(例如,使用 gensim 的 KeyedVectors.load_word2vec_format()),在加载每个句子时将输入语料库中的每个词转换为该表示,然后 LSTM 会吐出一个相同维度的向量,我们会尝试找到最相似的单词(例如使用 gensim 的similar_by_vector(y, topn=1))。

使用 softmax 是否可以让我们免于相对较慢的 similar_by_vector(y, topn=1) 调用?


顺便说一句,对于我的问题Using pre-trained word2vec with LSTM for word generation 的预先存在的 word2vec 部分是相似的。然而,目前那里的答案并不是我想要的。我所希望的是一个简单的英语解释,它为我打开了灯,并填补了我理解中的任何空白。 Use pre-trained word2vec in lstm language model? 是另一个类似的问题。

更新: Predicting next word using the language model tensorflow example 和 Predicting the next word using the LSTM ptb model tensorflow example 是类似的问题。但是,两者都没有显示代码来实际获取句子的前几个单词,并打印出对下一个单词的预测。我尝试从第二个问题和https://***.com/a/39282697/841830(带有 github 分支)粘贴代码,但都无法在没有错误的情况下运行。我认为它们可能适用于早期版本的 TensorFlow?

另一个更新:另一个问题基本相同:Predicting Next Word of LSTM Model from Tensorflow Example 它链接到 Predicting next word using the language model tensorflow example(同样,那里的答案并不是我想要的)。

如果仍然不清楚,我正在尝试编写一个名为 getNextWord(model, sentencePrefix) 的高级函数,其中 model 是我从磁盘加载的先前构建的 LSTM,sentencePrefix 是一个字符串,例如“Open the”,它可能返回“pod”。然后我可能会用“Open the pod”来调用它,它会返回“bay”,等等。

一个示例(使用字符 RNN,并使用 mxnet)是https://github.com/zackchase/mxnet-the-straight-dope/blob/master/chapter05_recurrent-neural-networks/simple-rnn.ipynb 末尾附近显示的 sample() 函数 您可以在训练期间调用sample(),但您也可以在训练后调用它,并使用您想要的任何句子。

【问题讨论】:

不幸的是,截至我需要提供赏金时,没有一个答案对我有用;这就是为什么我暂时不勾选它的原因。我为似乎最接近回答我的关键问题的答案提供了赏金。 答案对您不起作用,因为所有语言模型实现都没有通用答案,每个实现都有点不同。我觉得这个问题应该选择问的层次,要么是直观理解,要么是具体的代码实现。并不是说我反对这个问题,但我确实投了赞成票。其实如果你对模型有一定的了解,并且熟练使用 Python,实现起来并不难。不过这需要时间,所以如果您在实现此特定语言模型后在此处发布您的解决方案,它对其他人将非常有用。 @THN 比这更客观一点。 “不起作用”是指我试图从每个建议的答案中实现getNextWord(model, sentencePrefix),但它们要么以抛出异常而告终,要么在解释中存在差距,而这正是问题的重点。如果/当我得到这个工作,我会自我回答。 (顺便说一句,感谢您第一个回答 - 它确实帮助我澄清了我的问题,从而找到了更多相关问题。) 你设法让它工作了吗?我正在解决同样的问题! @Caterpilaraoz 不,还没有。所以如果你掌握了它,请发布一些代码! 【参考方案1】:

有很多问题,我会试着澄清一些。

在给定句子的前几个单词的情况下,如何使用生成的模型实际生成下一个单词建议?

这里的重点是,next word generation实际上是词汇表中的词分类。所以你需要一个分类器,这就是为什么输出中有一个softmax。

原理是,在每个时间步,模型会根据最后一个词嵌入和前一个词的内部记忆来输出下一个词。 tf.contrib.rnn.static_rnn 自动组合输入到内存中,但是我们需要提供最后一个词的embedding,对下一个词进行分类。

我们可以使用预训练的 word2vec 模型,只需使用预训练的矩阵初始化 embedding 矩阵。我认为为了简单起见,本教程使用随机矩阵。内存大小与嵌入大小无关,您可以使用更大的内存大小来保留更多信息。

这些教程是高级教程。如果你想深入了解细节,我建议你看一下纯 python/numpy 的源代码。

【讨论】:

谢谢。我刚刚在我的问题中添加了一些伪代码:我希望得到一个能显示真实代码的答案,这样我就可以实际打印出答案了。 Re:“使用 softmax 进行词分类”:使用词嵌入,余弦相似度用于找到与我们的 300 维向量输入最近的词。我不明白为什么我们使用softmax,而不是那样做。是为了速度(如果是的话,是否需要权衡)、提供更简单的教程(例如不依赖 gensim)、更好的质量结果、这是训练 LSTM 的唯一方法,还是其他什么? @DarrenCook 词分类是获取下一个词的直接方式。当然还有其他方法,比如您关于嵌入相似性的建议,但不能保证它们会更好地工作,因为我没有看到更多使用的信息。更不用说计算梯度会很困难。这个答案只给出一个直觉,你可以在我认为的语言模型库中搜索代码。【参考方案2】:

主要问题

加载单词

加载自定义数据而不是使用测试集:

reader.py@ptb_raw_data

test_path = os.path.join(data_path, "ptb.test.txt")
test_data = _file_to_word_ids(test_path, word_to_id)  # change this line

test_data 应该包含单词 id(打印出 word_to_id 用于映射)。例如,它应该看起来像:[1, 52, 562, 246] ...

显示预测

我们需要在对sess.run的调用中返回FC层的输出(logits

ptb_word_lm.py@PTBModel.__init__

    logits = tf.reshape(logits, [self.batch_size, self.num_steps, vocab_size])
    self.top_word_id = tf.argmax(logits, axis=2)  # add this line

ptb_word_lm.py@run_epoch

  fetches = 
      "cost": model.cost,
      "final_state": model.final_state,
      "top_word_id": model.top_word_id # add this line
  

稍后在函数中,vals['top_word_id'] 将有一个整数数组,其中包含顶部单词的 ID。在word_to_id 中查找此内容以确定预测的单词。前段时间我用小模型做了这个,前 1 的准确率很低(20-30% iirc),尽管困惑是在标题中预测的。

子问题

为什么要使用随机(未初始化、未经训练)的词嵌入?

您必须询问作者,但在我看来,训练嵌入使这更像是一个独立的教程:它不是将嵌入视为黑匣子,而是展示了它的工作原理。

为什么要使用 softmax?

最终预测不是由与隐藏层输出的余弦相似度决定的。在 LSTM 之后有一个 FC 层,将嵌入状态转换为最终单词的 one-hot 编码。

这是神经网络中的操作和维度的草图:

word -> one hot code (1 x vocab_size) -> embedding (1 x hidden_size) -> LSTM -> FC layer (1 x vocab_size) -> softmax (1 x vocab_size)

隐藏层是否必须与输入的维度相匹配(即 word2vec 嵌入的维度)

从技术上讲,没有。如果您查看 LSTM 方程,您会注意到 x(输入)可以是任意大小,只要适当调整权重矩阵即可。

如何/我可以引入预训练的 word2vec 模型,而不是未初始化的模型?

我不知道,对不起。

【讨论】:

谢谢。我认为这可能是正确的,但它仍然没有回答我的关键问题:一旦我建立了一个模型,我想从磁盘加载它,给它一个字符串(句子中的前几个单词),并要求它建议句子中的下一个单词。我想多次这样做,每次使用不同的前缀字符串。 IE。我正在尝试编写一个带有签名的函数:getNextWord(model, sentencePrefix) 我按照您的指示进行操作,但是当我执行 print(vals['top_word_id']) 时,我看到了 [[1 2] [1 1] [0 2] ... [1 1]] 即我没有一个数字可以传递给word_to_id[]。 (我也没有看到如何使用这种方法指定句子前缀。) 当您打印vals['top_word_id'] 时,您使用的是test_config 还是eval_config? (检查变量num_steps)您应该使用后者,因为您正在评估模型。您可以通过在word_to_id 中查找sentencePrefix 中的单词来指定句子前缀。诚然,这种方法并不是编写代码的最简洁方式【参考方案3】:

我最大的问题是如何使用生成的模型在给定句子的前几个单词的情况下实际生成下一个单词建议?

即我正在尝试使用签名编写一个函数:getNextWord(model, sentencePrefix)

在我解释我的答案之前,先说一下您对# Call static_rnn(cell) once for each word in prefix to initialize state 的建议:请记住,static_rnn 不会返回一个像 numpy 数组这样的值,而是一个张量。您可以在 (1) 在会话中运行时将张量评估为一个值(会话保持计算图的状态,包括模型参数的值)和 (2) 使用计算所需的输入张量值。可以使用输入阅读器(本教程中的方法)或使用占位符(我将在下面使用)提供输入。

现在遵循实际答案: 本教程中的模型旨在从文件中读取输入数据。 @user3080953 的答案已经展示了如何使用您自己的文本文件,但据我了解,您需要更多地控制数据如何馈送到模型。为此,您需要定义自己的占位符,并在调用 session.run() 时将数据提供给这些占位符。

在下面的代码中,我对PTBModel 进行了子类化,并使其负责向模型显式提供数据。我介绍了一个特殊的PTBInteractiveInput,其接口类似于PTBInput,因此您可以重用PTBModel 中的功能。要训​​练您的模型,您仍然需要 PTBModel

class PTBInteractiveInput(object):
  def __init__(self, config):
    self.batch_size = 1
    self.num_steps = config.num_steps
    self.input_data = tf.placeholder(dtype=tf.int32, shape=[self.batch_size, self.num_steps])
    self.sequence_len = tf.placeholder(dtype=tf.int32, shape=[])
    self.targets = tf.placeholder(dtype=tf.int32, shape=[self.batch_size, self.num_steps])

class InteractivePTBModel(PTBModel):

  def __init__(self, config):
    input = PTBInteractiveInput(config)
    PTBModel.__init__(self, is_training=False, config=config, input_=input)
    output = self.logits[:, self._input.sequence_len - 1, :]
    self.top_word_id = tf.argmax(output, axis=2)

  def get_next(self, session, prefix):
    prefix_array, sequence_len = self._preprocess(prefix)
    feeds = 
      self._input.sequence_len: sequence_len,
      self._input.input_data: prefix_array,
    
    fetches = [self.top_word_id]
    result = session.run(fetches, feeds)
    self._postprocess(result)

  def _preprocess(self, prefix):
    num_steps = self._input.num_steps
    seq_len = len(prefix)
    if seq_len > num_steps:
      raise ValueError("Prefix to large for model.")
    prefix_ids = self._prefix_to_ids(prefix)
    num_items_to_pad = num_steps - seq_len
    prefix_ids.extend([0] * num_items_to_pad)
    prefix_array = np.array([prefix_ids], dtype=np.float32)
    return prefix_array, seq_len

  def _prefix_to_ids(self, prefix):
    # should convert your prefix to a list of ids
    pass

  def _postprocess(self, result):
    # convert ids back to strings
    pass

PTBModel__init__函数中你需要添加这一行:

self.logits = logits

为什么要使用随机(未初始化、未经训练)的词嵌入?

首先请注意,虽然嵌入在开始时是随机的,但它们将与网络的其余部分一起训练。您在训练后获得的嵌入将具有与您使用 word2vec 模型获得的嵌入相似的属性,例如,能够通过向量操作(国王 - 男人 + 女人 = 女王等)回答类比问题。对于语言建模(不需要带注释的训练数据)或神经机器翻译等训练数据,从头开始训练嵌入更为常见。

为什么要使用 softmax?

Softmax 是一个函数,可将相似度得分(logits)向量归一化为概率分布。您需要一个概率分布来训练具有交叉熵损失的模型并能够从模型中进行采样。请注意,如果您只对训练模型中最可能出现的单词感兴趣,则不需要 softmax,您可以直接使用 logits。

隐藏层是否必须与输入的维度相匹配(即 word2vec 嵌入的维度)

不,原则上它可以是任何值。然而,使用比嵌入维度更低的隐藏状态没有多大意义。

如何/我可以引入预训练的 word2vec 模型,而不是未初始化的模型?

这是一个使用给定 numpy 数组初始化嵌入的自包含示例。如果您希望嵌入在训练期间保持固定/恒定,请将trainable 设置为False

import tensorflow as tf
import numpy as np
vocab_size = 10000
size = 200
trainable=True
embedding_matrix = np.zeros([vocab_size, size]) # replace this with code to load your pretrained embedding
embedding = tf.get_variable("embedding",
                            initializer=tf.constant_initializer(embedding_matrix),
                            shape=[vocab_size, size],
                            dtype=tf.float32,
                            trainable=trainable)

【讨论】:

谢谢!我已将您的代码粘贴到 ptb_word_lm.py 的中间。如果我想测试它,比如说,让它在每个训练时期之后输出它的下一个单词建议作为测试前缀,我是否在 main 的顶部创建一个 InteractivePTBModel 实例(例如,在我进行配置之后),或者每次在循环中创建它(例如github.com/tensorflow/models/blob/master/tutorials/rnn/ptb/…) 我得到“RuntimeError: Graph is finalized and cannot be modified。” (在我第一次尝试在循环内创建实例时)。很长的错误信息,但我认为是self.input_data = tf.placeholder(dtype=tf.float32, shape=[self.batch_size, self.num_steps])触发的 每次初始化 InteractivePTBModel 时都会将新操作添加到计算图中。您收到的错误是由于您在 managed_session 内初始化图表,这不允许修改图表。您可以创建模型here,类似于创建验证和测试模型的方式。我希望这会有所帮助。 self.input_dataself.targets 似乎想要 in32 而不是 float32。不幸的是,修复这个问题只会让我遇到下一个错误(谈论形状必须是等阶和跨步切片)。我仍然只是尝试创建InteractivePTBModel 的对象,甚至还没有调用get_next()!你的代码对你有用吗? 你是对的,占位符当然需要是int32。我更新了我的答案。通过编辑,还应该修复等秩错误(我相信这是因为 self.self.sequence_len 被定义为向量而不是标量)。我现在没有时间测试代码。【参考方案4】:

你可以在答案末尾找到所有代码。


我认为您的大部分问题(为什么使用 Softmax、如何使用预训练嵌入层等)都已得到解答。但是,由于您仍在等待简洁的代码从种子生成生成文本,因此我在这里尝试报告我自己最终是如何做到的。

从官方的 Tensorflow 教程开始,我一直在苦苦挣扎,直到我可以轻松地从生成的模型中生成单词。幸运的是,在对您在问题中提到的几乎所有答案进行了一些回答之后,我对问题(和解决方案)有了更好的了解。这可能包含错误,但至少它会运行并生成一些文本...

在给定句子的前几个单词的情况下,如何使用生成的模型实际生成下一个单词建议?

我会将下一个单词建议包装在一个循环中,以生成一个完整的句子,但您很容易将其缩减为一个单词。

假设您遵循 tensorflow(撰写本文时为 v1.4)here 提供的当前教程,该教程将在训练后保存模型。

然后我们要做的就是从磁盘加载它,并编写一个函数,该函数接受这个模型和一些种子输入并返回生成的文本。


从保存的模型生成文本

我假设我们在一个新的 python 脚本中编写了所有这些代码。底部的整个脚本作为回顾,这里我解释了主要步骤。

必要的第一步

FLAGS = tf.flags.FLAGS
FLAGS.model = "medium" # or whatever size you used

现在,非常重要的是,我们创建字典以将 id 映射到单词,反之亦然(因此我们不必读取整数列表...)。

word_to_id = reader._build_vocab('../data/ptb.train.txt') # here we load the word -> id dictionnary ()
id_to_word = dict(zip(word_to_id.values(), word_to_id.keys())) # and transform it into id -> word dictionnary
_, _, test_data, _ = reader.ptb_raw_data('../data')

然后我们加载配置类,同时将num_stepsbatch_size 设置为1,因为我们希望一次采样1 个单词,而LSTM 一次也处理1 个单词.还即时创建输入实例:

eval_config = get_config()
eval_config.num_steps = 1
eval_config.batch_size = 1
model_input = PTBInput(eval_config, test_data)

构建图

要加载保存的模型(由教程中的Supervisor.saver 模块保存),我们首先需要重建图形(使用PTBModel 类很容易),它必须使用 与训练时相同的配置:

sess = tf.Session()
initializer = tf.random_uniform_initializer(-eval_config.init_scale, eval_config.init_scale)
# not sure but seems to need the same name for variable scope as when saved ....!!
with tf.variable_scope("Model", reuse=None, initializer=initializer):
    tf.global_variables_initializer()
    mtest = PTBModel(is_training=False, config=eval_config, input=model_input)

恢复保存的权重:

sess.run(tf.global_variables_initializer())
saver = tf.train.Saver()
saver.restore(sess, tf.train.latest_checkpoint('../Whatever_folder_you_saved_in')) # the path must point to the hierarchy where your 'checkpoint' file is

...从给定种子中采样单词:

首先,我们需要模型包含对 logits 输出的访问,或者更准确地说是整个词汇表的概率分布。 所以在ptb_lstm.py 文件中添加以下行:

# the line goes somewhere below the reshaping "logits = tf.reshape(logits, [self.batch_size, ..."
self.probas = tf.nn.softmax(logits, name="probas")

然后我们可以设计一些采样功能(您可以在这里随意使用任何您喜欢的东西,最好的方法是使用趋于平坦或锐化分布的温度进行采样),这是一个基本的随机抽样方法:

def sample_from_pmf(probas):
    t = np.cumsum(probas)
    s = np.sum(probas)
    return int(np.searchsorted(t, np.random.rand(1) * s))

最后是一个函数,它接受一个种子、你的模型、将单词映射到 id 的字典,反之亦然,作为输入和输出生成的文本字符串:

def generate_text(session, model, word_to_index, index_to_word, 
                  seed='</s>', n_sentences=10):
    sentence_cnt = 0
    input_seeds_id = [word_to_index[w] for w in seed.split()]
    state = session.run(model.initial_state)

    # Initiate network with seeds up to the before last word:
    for x in input_seeds_id[:-1]:
        feed_dict = model.initial_state: state,
                     model.input.input_data: [[x]]
        state = session.run([model.final_state], feed_dict)

    text = seed
    # Generate a new sample from previous, starting at last word in seed
    input_id = [[input_seeds_id[-1]]]
    while sentence_cnt < n_sentences:
        feed_dict = model.input.input_data: input_id,
                     model.initial_state: state
        probas, state = session.run([model.probas, model.final_state],
                                 feed_dict=feed_dict)
        sampled_word = sample_from_pmf(probas[0])
        if sampled_word == word_to_index['</s>']:
            text += '.\n'
            sentence_cnt += 1
        else:
            text += ' ' + index_to_word[sampled_word]
        input_wordid = [[sampled_word]]

    return text

TL;DR

不要忘记添加该行:

self.probas = tf.nn.softmax(logits, name='probas')

ptb_lstm.py 文件中,在PTBModel 类的__init__ 定义中,logits = tf.reshape(logits, [self.batch_size, self.num_steps, vocab_size]) 行之后的任意位置。

整个脚本,只需从您拥有reader.pyptb_lstm.py 的同一目录中运行它:

import reader
import numpy as np
import tensorflow as tf
from ptb_lstm import PTBModel, get_config, PTBInput

FLAGS = tf.flags.FLAGS
FLAGS.model = "medium"

def sample_from_pmf(probas):
    t = np.cumsum(probas)
    s = np.sum(probas)
    return int(np.searchsorted(t, np.random.rand(1) * s))

def generate_text(session, model, word_to_index, index_to_word, 
                  seed='</s>', n_sentences=10):
    sentence_cnt = 0
    input_seeds_id = [word_to_index[w] for w in seed.split()]
    state = session.run(model.initial_state)

    # Initiate network with seeds up to the before last word:
    for x in input_seeds_id[:-1]:
        feed_dict = model.initial_state: state,
                     model.input.input_data: [[x]]
        state = session.run([model.final_state], feed_dict)

    text = seed
    # Generate a new sample from previous, starting at last word in seed
    input_id = [[input_seeds_id[-1]]]
    while sentence_cnt < n_sentences:
        feed_dict = model.input.input_data: input_id,
                     model.initial_state: state
        probas, state = sess.run([model.probas, model.final_state],
                                 feed_dict=feed_dict)
        sampled_word = sample_from_pmf(probas[0])
        if sampled_word == word_to_index['</s>']:
            text += '.\n'
            sentence_cnt += 1
        else:
            text += ' ' + index_to_word[sampled_word]
        input_wordid = [[sampled_word]]

    print(text)

if __name__ == '__main__':

    word_to_id = reader._build_vocab('../data/ptb.train.txt') # here we load the word -> id dictionnary ()
    id_to_word = dict(zip(word_to_id.values(), word_to_id.keys())) # and transform it into id -> word dictionnary
    _, _, test_data, _ = reader.ptb_raw_data('../data')

    eval_config = get_config()
    eval_config.batch_size = 1
    eval_config.num_steps = 1
    model_input = PTBInput(eval_config, test_data, name=None)

    sess = tf.Session()
    initializer = tf.random_uniform_initializer(-eval_config.init_scale,
                                            eval_config.init_scale)
    with tf.variable_scope("Model", reuse=None, initializer=initializer):
        tf.global_variables_initializer()
        mtest = PTBModel(is_training=False, config=eval_config, 
                         input_=model_input)

    sess.run(tf.global_variables_initializer())

    saver = tf.train.Saver()
    saver.restore(sess, tf.train.latest_checkpoint('../models'))

    while True:
        print(generate_text(sess, mtest, word_to_id, id_to_word, seed="this sentence is"))
        try:
            raw_input('press Enter to continue ...\n')
        except KeyboardInterrupt:
            print('\b\bQuiting now...')
            break

更新

至于使用最近的 tensorflow(至少 1.6)恢复旧的检查点(对我来说是 6 个月前保存的模型,不确定当时使用的确切 TF 版本),它可能会引发关于未找到某些变量的错误(见评论)。 在这种情况下,您应该使用this script 更新您的检查点。

另外,请注意,对我来说,我必须进一步修改它,因为我注意到 saver.restore 函数试图读取 lstm_cell 变量,尽管我的变量已转换为 basic_lstm_cell 这也导致 NotFound Error .因此,一个简单的解决方法是在 checkpoint_convert.py 脚本的第 72-73 行中进行一个小改动,即删除新名称中的 basic_

检查检查点中包含的变量名称的一种便捷方法是(CKPT_FILE.index.data0000-1000 等之前的后缀):

reader = tf.train.NewCheckpointReader(CKPT_FILE)
reader.get_variable_to_shape_map()

这样您可以验证您确实拥有正确的名称(或旧检查点版本中的错误名称)。

【讨论】:

非常感谢,***.com/users/5303618/h-rev。代码看起来很有希望,但我无法让它工作。我收到以下错误。知道如何解决吗?文件“test.py”,第 64 行,在 mtest = PTBModel(is_training=False, config=eval_config, input_=model_input) ... ValueError: Variable Model/RNN/multi_rnn_cell/cell_0/basic_lstm_cell/kernel 不存在,或者不是用 tf.get_variable() 创建的。您的意思是在 VarScope 中设置 reuse=tf.AUTO_REUSE 吗? 在撰写本文时它有效,现在确实出现了同样的错误(使用 tensofrlow 1.6+)。如果您使用早期版本保存模型并使用最新版本恢复,则会出现问题。 LSTM 参数的命名约定已更改,例如cell_0/basic_lstm_cell/weights 变成了 cell_0/basic_lstm_cell/kernel。这就是为什么如果您尝试使用最近的 TF 恢复旧检查点(太糟糕了......),您将无法恢复它们。使用this script 更新您的检查点。 (请参阅答案中的更新) @NiklasHeidloff 你能解决这个问题吗?我面临同样的问题。我正在尝试在存储后立即使用检查点。所以至少在我的情况下,原因不可能是版本之间的差异。

以上是关于使用 LSTM 教程代码预测句子中的下一个单词?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Keras LSTM与word嵌入来预测单词id

深度学习(06)_循环神经网络RNN和LSTM_01

Pytorch LSTM实现中文单词预测(附完整训练代码)

Pytorch LSTM实现中文单词预测(附完整训练代码)

Pytorch LSTM实现中文单词预测(附完整训练代码)

如何使用带有词嵌入的 Keras LSTM 来预测词 id