如何开发词级神经语言模型并用它来生成文本

一个语言模型可以根据序列中已观察到的单词来预测序列中下一个单词的概率。

神经网络模型是开发统计语言模型的首选方法,因为它们可以使用分布式表示,其中具有相似含义的不同单词具有相似的表示,并且在进行预测时可以使用大量最近观察到的单词的上下文。

在本教程中,您将了解如何使用Python中的深度学习开发统计语言模型。

完成本教程后,您将了解:

  • 如何为开发基于单词的语言模型准备文本。
  • 如何设计和拟合带有学习到的嵌入层和LSTM隐藏层的神经网络语言模型。
  • 如何使用学习到的语言模型生成具有与源文本相似统计特性的新文本。

立即开始您的项目,阅读我的新书《自然语言处理深度学习》,其中包含分步教程和所有示例的Python源代码文件。

让我们开始吧。

  • 更新于2018年4月:模型描述中的类型已修复
  • 更新于2020年5月:模型期望中的拼写错误已修复。
How to Develop a Word-Level Neural Language Model and Use it to Generate Text

如何开发词级神经语言模型并用它来生成文本
照片由Carlo Raso拍摄,部分权利保留。

教程概述

本教程分为4个部分,它们是:

  1. 柏拉图的《理想国》
  2. 数据准备
  3. 训练语言模型
  4. 使用语言模型

柏拉图的《理想国》

《理想国》是古希腊哲学家柏拉图最著名的著作。

它被组织成一次关于城邦秩序和正义的对话(例如,谈话)。

全书文本均可在公共领域免费获取。您可以在Project Gutenberg网站上以多种格式找到它。

您可以在此处下载整本书(或多本书)的ASCII文本版本

下载书籍文本并将其以文件名“republic.txt”保存在当前工作目录中。

在文本编辑器中打开文件,并删除开头和结尾的附加内容。这包括书本开头的信息、长篇分析和结尾的许可信息。

文本应以以下内容开头:

第一卷。

昨天我和阿里斯顿的儿子格劳康一起去了比雷埃夫斯,

并以以下内容结尾:


我们两人都将在这一生和我们所描述的一千年朝圣中一切安好。

这是干净数据文件的直接链接

将清理后的版本另存为当前工作目录中的“republic_clean.txt”。文件应包含约15,802行文本。

现在我们可以从这些文本中开发一个语言模型了。

需要深度学习处理文本数据的帮助吗?

立即参加我的免费7天电子邮件速成课程(附代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

数据准备

我们将从准备数据开始。

第一步是查看数据。

回顾文本

在编辑器中打开文本,然后查看文本数据。

例如,这是第一段对话:

第一卷。

昨天我和阿里斯顿的儿子格劳康一起去了比雷埃夫斯,
我可以向女神(色雷斯人
阿耳忒弥斯)祈祷;而且我还想看看他们将如何
庆祝这个新颖的节日。我对居民们的游行感到很高兴;
但色雷斯人的游行同样,
如果不是更美的话。当我们完成了祈祷并观看了
景观后,我们转向城市的方向;就在那一刻
塞法洛斯的儿子波勒马尔科斯碰巧从远处看见我们,
当时我们正要回家,并告诉他的仆人去
跑过来叫我们等他。那仆人抓住了我的斗篷
后面,说:波勒马尔科斯要你等一下。

我转过身,问他他的主人在哪里。

他说,年轻人,如果你等着,他就在你身后。

当然我们会等,格劳康说;几分钟后波勒马尔科斯
出现了,还有格劳康的兄弟阿德曼托斯,尼基亚斯
的儿子尼塞拉图斯,以及其他一些参加了游行的人。

波勒马尔科斯对我说:我看到,苏格拉底,你和你的
同伴已经要去城里了。

我说,你没说错。

在准备数据时,我们看到什么需要处理?

快速浏览一下,我看到了这些:

  • 书籍/章节标题(例如,“第一卷”)。
  • 英式拼写(例如,“honoured”)。
  • 大量标点符号(例如,“–”,“;–”,“?–”等等)。
  • 奇怪的名字(例如,“Polemarchus”)。
  • 一些持续数百行的长独白。
  • 一些引用的对话(例如,“……”)。

这些观察以及更多内容,都为我们如何准备文本数据提供了一些思路。

我们准备数据的具体方式确实取决于我们打算如何建模,而这又取决于我们打算如何使用它。

语言模型设计

在本教程中,我们将开发一个文本模型,然后用它来生成新的文本序列。

该语言模型将是统计性的,并且将根据文本的输入序列预测每个单词的概率。预测的单词将作为输入,以生成下一个单词。

一个关键的设计决策是输入序列的长度。它们需要足够长,以便模型能够学习单词的上下文以进行预测。这个输入长度也将定义我们使用模型生成新序列时使用的种子文本的长度。

没有正确答案。如果有足够的时间和资源,我们可以探索模型使用不同大小输入序列学习的能力。

相反,我们将输入序列的长度任意选择为50个单词。

我们可以处理数据,以便模型仅处理独立的句子,并填充或截断文本以满足每个输入序列的要求。您可以将此作为本教程的扩展来探索。

相反,为了保持示例简短,我们将让所有文本连贯地流动,并训练模型来预测跨越句子、段落甚至书籍或章节的下一个单词。

现在我们有了模型设计,我们可以着手将原始文本转换为50个输入单词到1个输出单词的序列,准备好拟合模型。

加载文本

第一步是将文本加载到内存中。

我们可以开发一个小型函数,将整个文本文件加载到内存中并返回。该函数名为load_doc(),如下所示。给定一个文件名,它返回加载的文本序列。

使用此函数,我们可以加载文件‘republic_clean.txt’中文档的清理版本,如下所示:

运行此片段会加载文档,并打印前200个字符作为初步检查。

第一卷。

昨天我和阿里斯顿的儿子格劳康一起去了比雷埃夫斯,
我可以向女神(色雷斯人
阿耳忒弥斯);而且我还想看看如何

到目前为止,一切顺利。接下来,让我们清理文本。

清理文本

我们需要将原始文本转换为标记或单词序列,作为训练模型的来源。

根据对原始文本的审查(见上文),以下是我们为清理文本将执行的一些具体操作。您可能想作为扩展来探索更多清理操作。

  • 将‘–’替换为空格,以便我们能更好地分割单词。
  • 按空格分割单词。
  • 删除单词中的所有标点符号以减小词汇量(例如,“What?”变为“What”)。
  • 删除所有非字母单词,以移除独立的标点符号标记。
  • 将所有单词标准化为小写,以减小词汇量。

词汇量大小对于语言模型来说很重要。更小的词汇量意味着模型更小,训练速度更快。

我们可以在函数中按此顺序实现这些清理操作。下面是clean_doc()函数,它以加载的文档作为参数,并返回一个清理过的标记数组。

我们可以对加载的文档运行此清理操作,并打印一些标记和统计信息作为初步检查。

首先,我们可以看到一列不错的标记,它们看起来比原始文本更干净。我们可以删除“Book I”章节标记等内容,但这只是一个好的开始。

我们还获得了一些关于清理后文档的统计数据。

我们可以看到,清理后的文本中有近12万个单词,词汇量不足7500个单词。这相对较小,在适度的硬件上,可以处理在这个数据上拟合的模型。

接下来,我们可以将标记整理成序列并保存到文件中。

保存清理后的文本

我们可以将长长的标记列表组织成50个输入单词和1个输出单词的序列。

也就是说,序列的长度为51个单词。

我们可以通过从第51个标记开始迭代标记列表,并将前面的50个标记作为序列来做到这一点,然后重复这个过程直到列表的末尾。

我们将把标记转换为空格分隔的字符串,以便稍后存储在文件中。

下面列出了将清理后的标记列表分割成长度为51个标记的序列的代码。

运行这段代码会创建一个长长的行列表。

打印列表的统计信息,我们可以看到我们将有118,633个训练样本来拟合模型。

接下来,我们可以将序列保存到新文件中以供以后加载。

我们可以定义一个新函数来将文本行保存到文件。这个新函数名为save_doc(),如下所示。它接受行列表和文件名作为输入。这些行以ASCII格式逐行写入。

我们可以调用此函数并将我们的训练序列保存到文件‘republic_sequences.txt’。

用文本编辑器查看文件。

您会发现,每一行都向前移动了一个单词,末尾添加了一个新单词来预测;例如,这里是截断后的前3行:

book i i … catch sight of
i i went … sight of us
i went down … of us from

完整示例

将所有这些结合起来,完整的代码清单如下所示。

现在,您的当前工作目录中应该已经有一个名为“republic_sequences.txt”的文件,其中存储了训练数据。

接下来,让我们看看如何拟合语言模型。

训练语言模型

我们现在可以从准备好的数据中训练一个统计语言模型。

我们将训练的模型是一个神经网络语言模型。它有几个独特的特征:

  • 它为单词使用分布式表示,因此具有相似含义的不同单词将具有相似的表示。
  • 它在学习模型的同时学习表示。
  • 它学会利用最近100个单词的上下文来预测下一个单词的概率。

具体来说,我们将使用Embedding Layer来学习单词的表示,并使用长短期记忆(LSTM)循环神经网络来学习根据上下文预测单词。

让我们从加载训练数据开始。

加载序列

我们可以使用我们在上一节中开发的load_doc()函数来加载训练数据。

加载后,我们可以通过按换行符分割数据来将数据分成独立的训练序列。

下面的片段将从当前工作目录加载“republic_sequences.txt”数据文件。

接下来,我们可以对训练数据进行编码。

编码序列

词嵌入层期望输入序列由整数组成。

我们可以将词汇表中的每个单词映射到一个唯一的整数,并对输入序列进行编码。稍后,当我们进行预测时,我们可以将预测转换为数字,并在相同的映射中查找其关联的单词。

为了实现这种编码,我们将使用Keras API中的Tokenizer类

首先,必须在整个训练数据集上训练Tokenizer,这意味着它会找到数据中的所有唯一单词,并为每个单词分配一个唯一的整数。

然后,我们可以使用训练好的Tokenizer对所有训练序列进行编码,将每个序列从单词列表转换为整数列表。

我们可以将单词到整数的映射作为字典属性`word_index`访问,它在Tokenizer对象上。

我们需要知道词汇量的大小,以便稍后定义嵌入层。我们可以通过计算映射字典的大小来确定词汇量。

单词被分配从1到单词总数(例如,7,409)的值。嵌入层需要为这个词汇表中从索引1到最大索引的每个单词分配一个向量表示,并且因为数组的索引是零偏移的,所以词汇表中最后一个单词的索引将是7,409;这意味着数组的长度必须是7,409 + 1。

因此,在为嵌入层指定词汇量大小时,我们指定的值比实际词汇量大1。

序列输入和输出

现在我们已经对输入序列进行了编码,我们需要将它们分离成输入(X)和输出(y)元素。

我们可以通过数组切片来实现这一点。

分离后,我们需要对输出单词进行独热编码。这意味着将其从一个整数转换为一个向量,其中包含词汇表中每个单词的0值,以及一个1来指示在单词整数值索引处出现的特定单词。

这样,模型就可以学习预测下一个单词的概率分布,并且可以从(除了实际下一个单词之外的所有单词为0的)目标值中学习。

Keras提供了to_categorical()函数,可以用来对每个输入-输出序列对的输出单词进行独热编码。

最后,我们需要向嵌入层指定输入序列的长度。我们知道长度是50个单词,因为我们设计了模型,但一个好的通用方法是使用输入数据形状的第二个维度(列数)。这样,如果您在准备数据时更改序列的长度,您就不需要更改此数据加载代码;它是通用的。

拟合模型

现在我们可以定义我们的语言模型并在训练数据上进行拟合。

学习到的嵌入需要知道词汇量的大小和输入序列的长度,如前所述。它还有一个参数可以指定用于表示每个单词的维度数量。也就是说,嵌入向量空间的大小。

常见的值是50、100和300。我们将使用50,但可以考虑测试更小或更大的值。

我们将使用两个LSTM隐藏层,每个隐藏层有100个记忆单元。更多的记忆单元和更深的网络可能会获得更好的结果。

一个具有100个神经元的密集全连接层连接到LSTM隐藏层,以解释从序列中提取的特征。输出层将下一个单词预测为与词汇量大小相同的单个向量,其中包含词汇表中每个单词的概率。使用softmax激活函数来确保输出具有归一化概率的特性。

网络定义的摘要被打印出来,作为初步检查,以确保我们构建了我们想要的东西。

接下来,模型被编译,指定了拟合模型所需的分类交叉熵损失。从技术上讲,模型正在学习多类分类,这是此类问题的合适损失函数。使用了高效的Adam实现来最小批量梯度下降,并评估了模型的准确性。

最后,模型在数据上训练100个训练周期,并使用了适度的128个批次大小来加速。

使用现代硬件(无GPU)进行训练可能需要几个小时。您可以通过更大的批次大小和/或更少的训练周期来加速它。

在训练过程中,您将看到性能摘要,包括每个批次更新结束时从训练数据中评估出的损失和准确率。

注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。请考虑运行几次示例并比较平均结果。

您会得到不同的结果,但预测下一个单词的准确率可能略高于50%,这也不算差。我们的目标不是100%的准确率(例如,一个记住了文本的模型),而是捕捉文本本质的模型。

保存模型

运行结束时,训练好的模型将被保存到文件

在这里,我们使用Keras模型API将模型保存到当前工作目录下的文件“model.h5”中。

稍后,当我们加载模型进行预测时,我们还需要单词到整数的映射。这在Tokenizer对象中,我们也可以使用Pickle将其保存。

完整示例

我们可以将所有这些放在一起;用于拟合语言模型的完整示例列在下面。

使用语言模型

现在我们有了一个训练好的语言模型,我们可以使用它了。

在这种情况下,我们可以使用它来生成具有与源文本相同统计特性的新文本序列。

这并不实用,至少对于这个例子来说不是,但它提供了一个具体的例子来说明语言模型学到了什么。

我们将从再次加载训练序列开始。

加载数据

我们可以使用上一节中的相同代码来加载文本的训练数据序列。

具体来说,是load_doc()函数。

我们需要文本,以便我们可以选择一个源序列作为模型输入来生成新的文本序列。

模型将需要50个单词作为输入。

稍后,我们将需要指定预期的输入长度。我们可以通过计算加载数据的一行长度并减去一行中也存在的预期输出单词数来确定此长度。

加载模型

我们现在可以从文件加载模型了。

Keras提供了load_model()函数来加载模型,以便使用。

我们也可以使用Pickle API从文件加载分词器。

我们已准备好使用已加载的模型。

生成文本

生成文本的第一步是准备种子输入。

为此,我们将从输入文本中选择一个随机行。选定后,我们将打印它,以便我们对使用的内容有所了解。

接下来,我们可以一次生成一个新单词。

首先,必须使用与训练模型时相同的分词器将种子文本编码为整数。

模型可以直接通过调用model.predict_classes()来预测下一个单词,它将返回概率最高的单词的索引。

然后,我们可以查找分词器映射中的索引以获取关联的单词。

然后,我们可以将此单词附加到种子文本并重复此过程。

重要的是,输入序列会变得太长。在将输入序列编码为整数之后,我们可以将其截断到所需的长度。Keras提供了pad_sequences()函数,我们可以使用它来进行截断。

我们可以将所有这些包装到一个名为generate_seq()的函数中,该函数以模型、分词器、输入序列长度、种子文本和要生成的单词数为输入。然后,它返回模型生成的单词序列。

现在我们准备根据一些种子文本生成新单词序列。

将所有这些放在一起,用于从学习的语言模型生成文本的完整代码列表如下。

运行示例首先打印种子文本。

when he said that a man when he grows old may learn many things for he can no more learn much than he can run much youth is the time for any extraordinary toil of course and therefore calculation and geometry and all the other elements of instruction which are a

然后打印50个生成的文本单词。

preparation for dialectic should be presented to the name of idle spendthrifts of whom the other is the manifold and the unjust and is the best and the other which delighted to be the opening of the soul of the soul and the embroiderer will have to be said at

注意:由于算法或评估程序的随机性,或数值精度的差异,您的结果可能有所不同。请考虑运行几次示例并比较平均结果。

您可以看到文本看起来是合理的。事实上,连接的添加将有助于解释种子文本和生成的文本。尽管如此,生成的文本还是会得到正确类型的单词,并以正确的顺序排列。

尝试运行几次示例,看看其他生成的文本。如果您看到任何有趣的内容,请在下面的评论中告诉我。

扩展

本节列出了一些您可能希望探索的扩展本教程的想法。

  • 逐句模型。根据句子分割原始数据,并将每个句子填充到固定长度(例如,最长句子的长度)。
  • 简化词汇。探索一个更简单的词汇,也许去除词干或停用词。
  • 调整模型。调整模型,例如嵌入的大小或隐藏层中的记忆单元数量,看看您是否能开发出更好的模型。
  • 更深的模型。将模型扩展为具有多个LSTM隐藏层,可能带有dropout,看看您是否能开发出更好的模型。
  • 预训练词嵌入。将模型扩展为使用预训练的word2vec或GloVe向量,看看它是否能产生更好的模型。

进一步阅读

如果您想深入了解此主题,本节提供了更多资源。

总结

在本教程中,您将了解如何使用词嵌入和循环神经网络开发一个基于单词的语言模型。

具体来说,你学到了:

  • 如何为开发基于单词的语言模型准备文本。
  • 如何设计和拟合带有学习到的嵌入层和LSTM隐藏层的神经网络语言模型。
  • 如何使用学习到的语言模型生成具有与源文本相似统计特性的新文本。

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

立即开发文本数据的深度学习模型!

Deep Learning for Natural Language Processing

在几分钟内开发您自己的文本模型

...只需几行python代码

在我的新电子书中探索如何实现
用于自然语言处理的深度学习

它提供关于以下主题的自学教程
词袋模型、词嵌入、语言模型、标题生成、文本翻译等等...

最终将深度学习应用于您的自然语言处理项目

跳过学术理论。只看结果。

查看内容

302条对如何开发单词级别神经网络语言模型并用于生成文本的回复

  1. nike November 10, 2017 at 12:59 pm #

    感谢您提供此博客,您是否使用RNN进行推荐?例如,使用用户消费电影序列来推荐电影。

    • Jason Brownlee November 11, 2017 at 9:15 am #

      抱歉,我没有将RNN用于推荐系统。

      • Mike April 29, 2020 at 10:49 pm #

        out_word = ”
        for word, index in tokenizer.word_index.items()
        if index == yhat
        out_word = word
        break

        为什么要对字典进行顺序搜索?

        • Jason Brownlee April 30, 2020 at 6:44 am #

          这是反向查找,按值而不是按键查找。

          • Mike April 30, 2020 at 7:14 pm #

            我明白了。但是不是有一个tokenizer.index_word(:: index -> word)字典来做这个吗?

          • Jason Brownlee May 1, 2020 at 6:34 am #

            可能吧,很棒的建议!也许在我写这个的时候它还没有,或者我没注意到。

      • Mike May 5, 2020 at 3:08 am #

        嘿Jason,我有一个问题。我不明白为什么Embedding(输入)层和输出层比我们词汇表中的单词数多1。

        我很确定输出层(以及one-hot向量的输入层)必须与我们的词汇表大小完全相同,这样每个输出值才能与我们的词汇表单词一一对应。如果我们在这个大小上加1,额外的输出值会映射到哪个单词?

        • Jason Brownlee May 5, 2020 at 6:34 am #

          我们添加一个“无”的“单词”,索引为0。这是针对所有我们不知道的单词,或者我们想将其映射为“不知道”的单词。

  2. Stuart November 11, 2017 at 6:01 am #

    出色的文章,谢谢!两个问题

    1. 移除标点符号的好处有多大?几更多的标点符号标记是不是比几千个单词标记要微不足道的添加?

    2. 根据您的经验,哪种方法在合理的时间内(几小时内)在适中的硬件(较便宜的GPU AWS选项)上生成有意义的文本更好:单词级别还是字符级别生成?

    另外,如果您能包含您的硬件设置、python/keras版本以及生成示例文本输出了多长时间,那将是极好的。

  3. Raoul November 12, 2017 at 11:55 pm #

    很棒的教程,感谢分享!

    我是否可以假设,给定特定的种子文本,模型总是会输出相同的文本?

    • Jason Brownlee November 13, 2017 at 10:17 am #

      是的,一个训练好的模型会。但是模型每次训练时都会不同。
      https://machinelearning.org.cn/randomness-in-machine-learning/

      • Gustavo February 15, 2019 at 3:27 am #

        不总是这样,你可以通过拟合多项分布来生成新文本,其中你取一个字符出现的概率而不是字符的最大概率。这允许生成文本有更多的多样性,并且你可以结合“温度”参数来控制这种多样性。

  4. Sarang November 13, 2017 at 1:15 am #

    Jason,

    感谢优秀的博客,您认为深度学习的未来如何?
    您认为深度学习会持续10年吗?

    • Jason Brownlee November 13, 2017 at 10:18 am #

      是的。结果在广泛的领域中都非常有价值。

  5. Roger January 3, 2018 at 8:40 pm #

    你好Jason,很棒的博客!
    不过,我在运行“model.add(LSTM(100, return_sequences=True))”时有一个问题。
    TypeError: Expected int32, got list containing Tensors of type '_Message' instead.
    您能帮忙吗?谢谢。

    • Roger January 3, 2018 at 9:15 pm #

      顺便说一句,我正在使用os系统,py3.5。

      • Kirstie January 5, 2018 at 1:03 am #

        你好Roger。我遇到了同样的问题,通过pip install –upgrade Tensorflow更新Tensorflow对我有效。

    • Jason Brownlee January 4, 2018 at 8:10 am #

      抱歉,我以前没见过这个错误。也许试试发布到stackoverflow?

      可能是你的库版本问题?确保一切都是最新的。

  6. Roger January 8, 2018 at 6:14 pm #

    嗨,Jason,
    您能将上面的代码用作语言模型,而不是预测下一个单词吗?
    我想判断“我正在吃一个苹果”比“我一个苹果正在吃”更常用。
    对于短句子,我可能没有50个单词作为输入。
    另外,Keras是否可以输出概率及其索引,例如下一个单词的最大概率是“republic”,而我想获得“republic”的索引,该索引可以在tokenizer.word_index中匹配。
    谢谢!

    • Roger January 8, 2018 at 8:53 pm #

      如果您想用3个前置词作为输入来预测下一个词,您有什么建议吗?谢谢。

      • Jason Brownlee January 9, 2018 at 5:28 am #

        您可以构建您的问题,准备数据并训练模型。

        3个单词作为输入可能不够。

      • Mike April 30, 2020 at 8:09 pm #

        这是一个马尔可夫假设。循环神经网络模型的要点是避免这种情况。如果您只使用3个单词来预测下一个词,那么可以使用n-gram或前馈模型(如Bengio的模型)。不需要循环模型。

    • Jason Brownlee January 9, 2018 at 5:25 am #

      抱歉,我不确定您的应用程序。

      Keras可以预测词汇表中的概率,您可以使用argmax()来获取概率最大的单词的索引。

  7. Cid February 14, 2018 at 3:47 am #

    嗨,Jason,
    感谢您的帖子。我注意到在扩展部分您提到了逐句建模。
    我理解填充(padding)技术(在阅读了您的另一篇博文后)。但是它如何包含句号来生成文本呢?这是后处理文本的问题吗?在嵌入之前标记句号是否可能/更方便?

    • Jason Brownlee February 14, 2018 at 8:23 am #

      我通常建议移除标点符号。它会膨胀词汇量大小,进而减慢建模速度。

      • Cid February 14, 2018 at 8:00 pm #

        好的,谢谢您的建议,那么如何将句子结构纳入我的模型呢?

        • Jason Brownlee February 15, 2018 at 8:40 am #

          每个句子都可以是一个“样本”或作为输入的单词序列。

  8. Maria 2018年2月16日晚上10:32 #

    嗨 Jason,我尝试使用你的模型并用我自己的语料库进行训练,一切似乎都正常工作,但在最后出现了这个错误
    34 sequences = array(sequences)
    35 #print(sequences)
    —> 36 X, y = sequences[:,:-1], sequences[:,-1]
    37 # print(sequences[:,:-1])
    38 # X, y = sequences[:-1], sequences[-1]

    IndexError: 数组索引过多

    关于序列的滑动。你知道如何解决吗?
    非常感谢!

    • Jason Brownlee 2018年2月17日早上8:45 #

      也许仔细检查一下加载的数据是否具有你期望的形状?

      • Ray 2018年3月1日早上7:31 #

        嗨 Jason 和 Maria。
        我遇到了完全相同的问题。
        我希望 Jason 能有更好的建议
        这是错误

        IndexError Traceback (最近一次调用)
        in ()
        1 # 分离输入和输出
        2 sequences = array(sequences)
        —-> 3 X, y = sequences[:,:-1], sequences[:,-1]
        4 y = to_categorical(y, num_classes=vocab_size)
        5 seq_length = X.shape[1]

        IndexError: 数组索引过多

        • Jason Brownlee 2018年3月1日晚上3:05 #

          你能确认你的 Python 3 环境是最新的吗,包括 Keras 和 tensorflow?

          例如,这是我目前运行的版本

          • Doron Ben Elazar 2018年3月20日早上8:14 #

            这意味着你的输入不均匀,np.array 无法正确解析它(作者创建了每个 50 个 token 的段落),一个可能的修复方法是

            original_sequences = tokenizer.texts_to_sequences(text_chunk)

            vocab_size = len(tokenizer.word_index) + 1

            aligned_sequneces = []
            for sequence in original_sequences
            aligned_sequence = np.zeros(max_len, dtype=np.int64)
            aligned_sequence[:len(sequence)] = np.array(sequence, dtype=np.int64)
            aligned_sequneces.append(aligned_sequence)

            sequences = np.array(aligned_sequneces)

          • Cathy 2019年10月18日晚上10:30 #

            你使用 gensim 来生成这段代码吗?
            如果你使用了 gensim,你在代码中使用的 gensim 命令在哪里?

          • Jason Brownlee 2019年10月19日早上6:37 #

            本教程未使用 Gensim。

        • Basil 2018年6月28日晚上6:36 #

          不知道回复是不是太晚了。问题出现的原因是你错误地输入了

          tokenizer.fit_on_sequences 而不是 tokenizer.texts_to_sequences。

          希望这能帮助以后访问此页面的其他人!

          谢谢 Jason。

    • Naetmul 2018年10月28日晚上1:06 #

      主要问题是 `tokenizer.texts_to_sequences(lines)` 返回的是 List of List,而不是保证是矩形的二维列表,
      这意味着 `sequences` 可能具有这种形式
      [[1, 2, 3], [2, 3, 4, 5]]
      但本文中的示例假设 `sequences` 应该是这种矩形形状的列表
      [[1, 2, 3, 4], [2, 3, 4, 5]]

      如果你使用了自定义的 `clean_doc` 函数,你可能需要为 Tokenizer() 使用自定义的过滤器参数,例如 `tokenizer = Tokenizer(filters='\n')`。

      Tokenizer() 的构造函数有一个可选参数
      filters: 一个字符串,其中每个元素都是一个将从文本中过滤掉的字符。默认值是所有标点符号、制表符和换行符,但不包括 ' 字符。

      示例已移除了所有标点符号和空格,因此在示例中这不成问题。
      但是,如果你使用了自定义的,那么这可能会成为一个问题。

  9. vikas dixit 2018年3月5日晚上9:26 #

    先生,我的词汇量大小为 12000,当我使用 to_categorical 时,系统会抛出如下所示的内存错误

    /usr/local/lib/python2.7/dist-packages/keras/utils/np_utils.pyc in to_categorical(y, num_classes)
    22 num_classes = np.max(y) + 1
    23 n = y.shape[0]
    —> 24 categorical = np.zeros((n, num_classes))
    25 categorical[np.arange(n), y] = 1
    26 return categorical

    内存错误

    如何解决这个错误?

    • Jason Brownlee 2018年3月6日早上6:12 #

      也许可以尝试在具有更多 RAM 的机器上运行代码,例如 S3?

      也许可以尝试使用更节省内存的代码手动映射词汇到整数?

  10. Eli Mshomi 2018年3月7日早上9:40 #

    你能基于其他相关文章生成一篇可供人类阅读的文章吗?

    • Jason Brownlee 2018年3月7日晚上3:05 #

      是的,我认为可以。模型必须足够大并且经过精心训练。

  11. Adam 2018年3月12日晚上9:52 #

    嗨,Jason,
    我刚刚用我自己的文本样本(来自一个 Tumblr 博客的博文)试用了你的代码并进行了训练,现在它已经到了文本不再被“生成”,而是被原样返回的阶段。
    我使用的样本集相当小(每个单独的帖子都很小,所以我将每个序列设置为 10 个输入 1 个输出),大约有 25,000 个序列。其他所有代码都与你的教程相同 - 大约 150 个 epoch 后,准确率约为 0.99,所以我停止了它,试图进行生成。

    当我将种子文本从样本中的内容更改为词汇表中的其他内容(即不是完整的行,而是“随机”的行)时,文本就变得相当随机,这正是我想要的。当种子文本更改为词汇表之外的内容时,每次都会生成相同的文本。

    如果我想要更随机一些,我应该怎么做?我应该更改 LSTM 层中的内存单元吗?减少序列长度?在更高的损失/更低的准确率下停止训练?

    非常感谢你的教程,我从中学到了很多。

    • Jason Brownlee 2018年3月13日早上6:28 #

      也许模型过拟合了,可以减少训练量?

      也许需要更大的数据集?

      • Adam 2018年3月13日早上9:17 #

        我认为可能是过拟合了。可惜,我能获取的数据不多了(至少目前我所知道的),所以我无法获取更多数据,这很糟糕——这就是为什么我将序列长度减少到 10。

        我每个 epoch 都进行了检查点,这样我就可以尝试找出能产生最佳结果的设置。谢谢你的建议!

        • Jason Brownlee 2018年3月13日晚上3:04 #

          也许还可以尝试混合/集成一些检查点模型或来自多次运行的模型,看看是否能带来一点提升。

  12. Prateek 2018年3月30日晚上4:05 #

    嗨,Jason,

    我在 Tensorflow 上查看了准确率和损失的数量。我想知道 NLP 中的准确率到底是什么意思?

    在计算机视觉中,如果我们想预测猫,并且模型的预测结果是猫,那么我们可以说模型的准确率大于 95%。

    我想从物理上理解 NLP 模型中的准确率意味着什么。你能解释一下吗?

  13. Jin Zhou 2018年4月14日中午12:10 #

    你好,我有一个关于评估这个模型的问题。据我所知,困惑度是一个非常流行的方法。对于 BLEU 和困惑度,你认为哪个更好?你能举一个在 keras 中评估这个模型的例子吗?

  14. Jin 2018年4月23日晚上7:11 #

    嗨 Jason,我有点困惑,你告诉我们需要 100 个词作为输入,但你的 X_train 每行只有 50 个词。你能解释一下吗?

  15. jason 2018年5月1日早上9:54 #

    Jason,

    你的模型中有一个嵌入层。嵌入权重将与其它层一起被训练。为什么不单独分离并训练它呢?换句话说,先单独使用 Embedding 来训练词向量/嵌入权重。然后用嵌入权重初始化嵌入层并设置 trainable=false 来运行你的模型。我看到大多数人使用你的方法来训练模型。但这在某种程度上违背了嵌入的目的,因为输出不是词语上下文而是 0/1 标签。为什么不将嵌入替换为一个具有线性激活的普通层呢?

    另一个 Jason

    • Jason Brownlee 2018年5月2日早上5:36 #

      你可以分开训练它们。我在博客上提供了示例。

      通常,我发现模型在嵌入与网络一起训练时具有更好的技能。

  16. johhnybravo 2018年5月19日凌晨2:33 #

    ValueError: Error when checking : expected embedding_1_input to have shape (50,) but got array with shape (1,) while predicting output

  17. Nitin Mukesh 2018年5月30日晚上6:33 #

    你好,我想在 keras 中开发图像字幕。它的先决条件是什么?我已经完成了你的关于使用 CNN 进行对象检测的教程。接下来我应该做什么?

  18. mel_dagh 2018年6月1日凌晨1:59 #

    嗨,Jason,

    1.) 我们能否使用这种方法来预测训练数据中的某个词在序列中的位置是否高度异常?即它在该序列位置的概率不高。

    2.) 有没有办法在嵌入层中集成预训练的词嵌入(glove/word2vec)?

  19. Tanaya 2018年6月8日晚上7:29 #

    你好,这对于像我这样的 NLP 初学者来说是一篇非常棒的文章。

    我已经生成了一个语言模型,它正在生成我想要的文本。
    我的问题是,在生成之后,我如何过滤掉所有在语法或语义上没有意义的文本?

    • Jason Brownlee 2018年6月9日早上6:49 #

      谢谢。

      你可能需要另一个模型来对文本进行分类、纠正文本或在使用前过滤文本。

      • Tanaya 2018年6月12日晚上4:40 #

        这是否也会使用 Keras?你建议使用 nltk 还是 SpaCy?

  20. Venkat 2018年6月12日凌晨4:38 #

    嗨,Jason,

    感谢您这篇精彩的文章。

    我正在处理句子中的单词纠正。理想情况下,模型应该生成与输入单词数量相同的输出单词,并纠正句子中的错误单词。

    语言模型对此有帮助吗?如果可以,请给我一些关于模型的提示。

    • Jason Brownlee 2018年6月12日早上6:48 #

      听起来是一个有趣的工程。语言模型可能有用。抱歉,我没有可用的示例。我建议查阅文献。

  21. Amar 2018年6月20日晚上8:53 #

    嗨,Jason,

    我正在处理一个高度不平衡的文本分类问题。
    例如:基于电子邮件正文中的文本,将“真实电子邮件”与“垃圾邮件”进行分类。

    真实电子邮件文本 = 30k 行
    垃圾邮件文本 = 1k 行

    我需要分类下一封电子邮件是真实邮件还是垃圾邮件。

    我使用与上述相同的示例来训练模型。
    我提供给模型的训练数据仅为“真实文本”。

    我是否能够通过生成的文本和词语的概率来分类下一句输入的句子:“真实电子邮件” vs “垃圾邮件”?

    (我假设模型从未见过垃圾邮件数据,因此生成的文本的概率会很低。)

    你认为有没有办法用语言模型来实现这个目标?在 NLP 用例的稀有事件场景中,还有什么其他选择?

    谢谢你!!

  22. musa 2018年6月29日凌晨2:36 #

    嗨,Jason,

    你能评论一下语言模型训练中的过拟合问题吗?我构建了一个基于句子的 LSTM 语言模型,并将训练:验证集划分为了 80:20 的比例。我没有在验证数据中看到任何改进,而模型的准确率似乎在提高。

    谢谢

    • Jason Brownlee 2018年6月29日早上6:13 #

      语言模型的过拟合实际上只在你使用该模型的问题上下文中才重要。

      单独使用的语言模型实际上没有多大用处,所以过拟合并不重要。它可能是一个描述性模型,而不是预测性模型。

      通常,它们在另一个模型的输入或输出中使用,在这种情况下,过拟合可能会限制预测能力。

  23. Marc 2018年6月30日早上8:42 #

    返回隐藏状态和单元状态在这里会有什么影响?

    我想象如果输入序列足够长,这可能不会太重要,因为时间关系会得到捕捉,但如果我们有较短的序列或非常长的文档,我们会考虑这样做来提高模型的学习能力……我这么想对吗?

    返回隐藏序列和单元状态并将其输入到下一个观察值有什么缺点?

    • Jason Brownlee 2018年7月1日早上6:21 #

      我不明白,为什么你要把单元状态外部返回?它在网络外部没有意义。

      • star 2018年7月5日凌晨2:25 #

        希望你一切都好。我有一个关于嵌入向量理解的问题。
        例如,如果我有这个句子“the weather is nice”,我的模型目标是预测“nice”,当我想要使用预训练的谷歌词嵌入模型时,我必须搜索谷歌嵌入矩阵,找到与单词“the”、“weather”、“is”、“nice”相关的嵌入向量并将它们作为输入输入到我的模型中?我说的对吗?

  24. Fatemeh 2018年7月4日凌晨2:34 #

    你好,感谢你的精彩描述。我想使用预训练的谷歌词嵌入向量,所以我认为我不需要进行序列编码,例如,如果我想创建长度为 10 的序列,我必须搜索嵌入矩阵并找到每个 10 个词的等效嵌入向量,对吗?

    • Jason Brownlee 2018年7月4日早上8:28 #

      正确。在准备嵌入或编码时,你必须将每个词映射到其分布式表示。

      • Fatemeh 2018年7月5日凌晨2:43 #

        谢谢,你的书中有这方面的示例代码吗?我购买了你的专业套餐。

        • Jason Brownlee 2018年7月5日早上8:01 #

          所有示例代码都随 PDF 一起提供在 code/ 目录中。

          • fatemeh 2018年7月6日凌晨1:57 #

            谢谢。当我想使用 model.fit 时,我必须指定 X 和 y,我使用了预训练的谷歌嵌入矩阵。所以每个词都映射到一个向量,我的输入实际上是句子(长度为 4)。现在我不理解 X 的等效值。例如,假设第一个句子是“the weather is nice”,那么 X 是“the weather is”,y 是“nice”。当我将 X 转换为整数时,X 中的每个词都会被映射到一个向量吗?例如,如果句子中词语的等效向量在谷歌模型中是:“the”= 0.9,0.6,0.8 和 “weather”=0.6,0.5,0.2 和 “is”=0.3,0.1,0.5,以及“nice”=0.4,0.3,0.5,那么输入 X 将是:[[0.9,0.6,0.8],[0.6,0.5,0.2],[0.3,0.1,0.5]] 而输出 y 将是 [0.4,0.3,0.5]?

          • Jason Brownlee 2018年7月6日早上6:45 #

            你可以指定或学习映射,但之后模型会将整数映射到它们的向量。

  25. mh 2018年7月5日凌晨4:19 #

    你好 Jason,为什么你没有将 X 输入转换为热向量格式?你只对 y 输出做了这个。

  26. Anshuman Mahapatra 2018年7月5日晚上10:43 #

    您好!首先,我想感谢您对这个概念的详细解释。为了更好地理解,我正在一步步执行这个模型,但在进行预测时遇到了问题。
    yhat = model.predict_classes(encoded, verbose=0)
    我遇到了以下错误:
    ValueError: Error when checking input: expected embedding_1_input to have shape (50,) but got array with shape (1,)

  27. NLP_enthusiast 2018年8月3日下午5:08 #

    您好,教程很棒!

    调用时
    model.fit(X, y, batch_size=128, epochs=100)
    此时 X.shape 和 y.shape 是什么?

    我收到了错误:
    Error when checking input: expected embedding_1_input to have shape (500,) but got array with shape (1,)

    在我的例子中
    X.shape = (500,) # 在我的例子中是 500 个样本
    y.shape = (500, 200) # 这是在 y= to_categorical(y, num_classes=vocab_size) 之后

    使用 Theano 后端。

      • NLP_enthusiast 2018年8月4日上午7:46 #

        谢谢。可能对其他人有用:X.shape 的形式应该是 (a, b),其中 a 是“sequences”的长度,b 是输入序列的长度,以便进行前向预测。请注意,如果使用 Python 2.x(而不是 Python 3.x),则很可能需要修改/省略 string.maketrans(),并且 Theanos 后端也可能缓解 TensorFlow 潜在的维度错误。

        • Jason Brownlee 2018年8月5日上午5:21 #

          谢谢。

        • Mike 2020年4月30日下午8:15 #

          我不明白为什么每个序列的长度必须相同(即固定)?RNN 的意义不就是通过一次接收一个单词作为输入,并将其余单词保留在隐藏状态中来处理可变长度的输入吗?

          这是为了优化,当我们碰巧使用所有相同的尺寸时,但实际上我们并非必须这样做?那样的话更有意义。

          • Jason Brownlee 2020年5月1日上午6:36 #

            你说得对,动态 RNN 可以做到这一点。

            我大多数实现都使用固定长度的输入/输出以提高效率,并使用零填充和掩码来忽略填充。

    • usman 2018年9月4日下午5:35 #

      @NLP_enthusiast 你是如何解决这个错误的?

      • Carlos Aguayo 2018年11月20日上午10:49 #

        你只需将这些替换为

        table = string.maketrans(string.punctuation, ‘ ‘)
        tokens = [‘w.translate(table)’ for w in tokens]

        改为

        tokens = [‘ ‘ if w in string.punctuation else w for w in tokens]

  28. Eric 2018年8月20日下午9:15 #

    有人有使用用户提供的文本字符串而不是随机样本数据进行预测的示例吗?我对此还是新手,所以提前为如此简单的问题道歉。谢谢!

    • Jason Brownlee 2018年8月21日上午6:15 #

      新的输入数据必须与模型的训练数据以相同的方式进行准备。

      例如,相同的 数据预处理步骤和分词器。

  29. Santosh 2018年8月21日上午6:28 #

    我们能否在 Android 平台上实现这个功能,以运行训练好的模型,为用户提供给定的单词集?

    • Jason Brownlee 2018年8月21日上午6:38 #

      也许可以,我没有 Android 上的示例,抱歉。

  30. anirban 2018年8月31日晚上11:29 #

    你好,
    博客中建议的一个扩展是
    逐句模型。按句子分割原始数据,并将每个句子填充到固定长度(例如,最长句子的长度)。
    所以如果我进行逐句分割,是保留标点符号还是删除它?

  31. wu.zheng 2018年9月6日下午1:40 #

    # 分离为输入和输出
    sequences = array(sequences)
    X, y = sequences[:,:-1], sequences[:,-1]

    这个模型是只使用前面的 50 个单词来预测最后一个单词吗?

    上下文长度是固定的吗?

  32. Anshul Patel 2018年10月3日下午5:55 #

    Jason您好,我也在用RNN进行词预测。但是我遇到了和很多人一样的 INDEXERROR : Too many Indices 的问题。

    lines = training_set.split(‘\n’)
    tokenizer = Tokenizer()
    tokenizer.fit_on_sequences(lines)
    tokenizer.fit_on_texts(lines)
    sequences = tokenizer.texts_to_sequences(lines)

    vocab_size = len(tokenizer.word_index) + 1

    sequences = array(sequences)
    X_train = sequences[:, :-1]
    y_train = sequences[:,-1]

    我已经阅读了所有与此错误相关的评论,但似乎没有一个解决了我的问题。我想知道是否是我导入的文本有问题,我导入的是古腾堡的《傲慢与偏见》一书。

    请帮帮我:提前感谢!!!

    • Jason Brownlee 2018年10月4日上午6:12 #

      我没见过这个错误,您能确认您的库是最新版本并且您复制了教程中的所有代码吗?

  33. Andrew 2018年10月16日下午4:51 #

    非常好的文章。

    在 118633 个长度为 50 个符号的序列,来自 7410 个元素的词汇表中,训练模型需要多长时间?

    您能否分享一下您在哪台机器上训练了模型?内存、CPU、操作系统?

  34. ervin 2018年10月20日凌晨3:36 #

    好文!

    2 个问题

    1. 在您的“扩展”部分,您提到了尝试 dropout。由于没有验证/保留集,为什么我们应该使用 dropout?它不是一种正则化技术,对训练数据准确性没有帮助吗?

    2. 谈到准确性——我将我的模型训练到了 99% 的准确率。当我生成文本并使用柏拉图的确切台词作为种子文本时,我应该得到柏拉图的几乎精确副本,对吗?因为我的模型有 99% 的概率在我的种子文本中获得下一个单词。我发现事实并非如此。我是否正确地解释了这 99% 的准确率?是什么阻止它制造出副本?

    • Jason Brownlee 2018年10月20日凌晨5:59 #

      是的,它是一种正则化方法。是的,它可以提供帮助,因为模型是使用监督学习进行训练的。

      准确性不是语言模型的有效衡量标准。

      我们不希望模型记住柏拉图,我们希望模型学会如何生成类似柏拉图的文本。

  35. OkRo 2018年11月29日晚上9:17 #

    您好,非常棒的文章!
    我有一个问题——如何使用该模型来获得句子中某个单词的概率?
    例如 P(Piraeus| went down yesterday to the?

  36. Emi 2018年12月10日下午12:36 #

    我是您教程的忠实粉丝,当我需要学习深度学习知识时,我总是先搜索您的教程。

    我目前遇到了一个问题,如下所示。

    我有一个庞大的非结构化文本语料库(我已经对其进行了清理和分词,如:word1, word2, word3, … wordN)。我还有一个目标单词列表,它应该通过分析这些清理过的文本来输出(例如,word88, word34, word 48, word10002, … , word8)。

    我想构建一个语言模型,它能通过我的清理文本正确地输出这些目标单词。我想知道这是否可以使用深度学习技术来实现?请告诉我您的想法。

    如果您有与上述场景相关的教程,请与我分享(因为我找不到)。

    感谢您提供的精彩教程。

    -Emi

    • Jason Brownlee 2018年12月10日下午2:19 #

      听起来很像翻译或文本摘要任务?

      也许用于这些问题的模型会是一个好的起点?

      • Emi 2018年12月10日下午4:36 #

        感谢您的回复。不,它不是翻译或摘要。我下面举了一个更详细的例子。

        —————————————————————————————————————-

        我目前的输入准备过程如下:
        非结构化文本 -> 清理数据 -> 只保留信息性词语 -> 计算不同特征

        示例(假设我们只有 5 个词)
        信息性词语 = {“Deep Learning”, “SVM”, “LSTM”, “Data Mining”, ‘Python’}

        对于每个单词,我还有特征(假设我们只有 3 个词)
        特征 = {Frequency, TF-IDF, MI}
        但是,我不确定在构建深度学习模型时是否需要这些特征。

        ——————————————————————————————————————–

        我的输出是信息性词语的排名列表。
        目标输出 = {‘SVM’, ‘Data Mining’, ‘Deep Learning’, ‘Python’, ‘LSTM’}
        ——————————————————————————————————————–

        我只是想弄清楚是否有办法通过深度学习或机器学习模型来获得我的目标输出?请告诉我您的想法。

        -Emi

        • Jason Brownlee 2018年12月11日上午7:39 #

          听起来您想要一个模型来输出相同的输入,但以某种方式排序。

          可以尝试编码器-解码器吗?

          • Emi 2018年12月11日下午12:48 #

            嗨,Jason,

            非常感谢您的建议。我今天遵循了您关于编码器-解码器的教程:https://machinelearning.org.cn/develop-encoder-decoder-model-sequence-sequence-prediction-keras/

            它解释得很好,我想将其用于我的任务。但是,我遇到一个小问题。

            在您的示例中,您使用了 100000 个训练示例,如下所示。

            X=[22, 17, 23, 5, 29, 11] y=[23, 17, 22]
            X=[28, 2, 46, 12, 21, 6] y=[46, 2, 28]
            X=[12, 20, 45, 28, 18, 42] y=[45, 20, 12]
            X=[3, 43, 45, 4, 33, 27] y=[45, 43, 3]

            X=[34, 50, 21, 20, 11, 6] y=[21, 50, 34]

            但是在我的任务中,我只有一个输入序列和目标序列,如下所示(输入相同,但顺序不同)。

            信息性词语 = {“Deep Learning”, “SVM”, “LSTM”, “Data Mining”, ‘Python’}
            目标输出 = {‘SVM’, ‘Data Mining’, ‘Deep Learning’, ‘Python’, ‘LSTM’}

            这会是个问题吗?

            PS:但是,在我的真实数据集中,我的输入和目标序列都非常长(大约 10000 个单词)。

          • Jason Brownlee 2018年12月11日下午2:33 #

            您需要根据您的问题调整模型并进行测试,以便_发现_模型是否合适。

  37. Emi 2018年12月11日上午10:38 #

    非常感谢您宝贵的建议。我真的很感激🙂

    我遵循了您关于“编码器-解码器 LSTM”用于时间序列分析的教程。您是否有接近我任务的“编码器-解码器”教程?如果有,请提供链接。

  38. Jin 2018年12月14日下午8:23 #

    Jason您好,我有一个关于预训练词向量的问题。我知道应该用 weights=[pre_embedding] 来设置嵌入层,但是如何决定预训练的顺序呢?比如,某一行中的向量代表哪个词?第一行是否总是全零?

    • Jason Brownlee 2018年12月15日上午6:11 #

      每个向量的索引必须与词汇表中每个词的整数编码相匹配。

      这就是为什么我们逐步收集词汇表中所需的向量。

  39. Lee 2019年1月9日下午1:42 #

    我正在运行这里和书中描述的模型,但损失经常变为 NaN。我的计算机(18 核 + Vega 64 显卡)运行一个 epoch 的时间也比这里显示的长得多。所有 CPU 需要 1 小时才能完成。编码为 int8 并通过 PlaidML 使用 GPU 可以将其加速到约 376 秒,但会出现 NaN。

    有什么建议吗?代码与这里和书中的完全一样,但我就是无法让它完成一次运行。

    • Jason Brownlee 2019年1月10日上午7:46 #

      我有两个想法。

      您是否尝试运行书中提供的代码文件?
      您能否确认您的库是最新的?

  40. Palani 2019年1月20日下午6:11 #

    Jason,非常棒的入门教程!谢谢!

  41. Matt Lust 2019年2月5日上午9:17 #

    我在 Google Colab 中运行此程序(尽管使用了不同的、更大的数据集),Colab 系统崩溃,我的运行时基本上被重置。

    我像您在此示例中一样分解了每个部分,发现它在以下代码处崩溃:

    # 分离为输入和输出
    sequences = array(sequences)
    X, y = sequences[:,:-1], sequences[:,-1]
    y = to_categorical(y, num_classes=vocab_size)
    seq_length = X.shape[1]

    我认为问题在于我的数据集可能太大了,但我不确定。

    这是 Colab 笔记本的链接。

    https://colab.research.google.com/drive/1iTXV_iC-aBTSlQ8BtiwM7zSszmIrlB3k

    • Jason Brownlee 2019年2月5日下午2:20 #

      抱歉,我没有该环境的经验。

      我建议在您自己的工作站上运行所有代码。

    • Valerie 2019年5月2日晚上11:06 #

      同样的问题((((google colab 没有足够的内存来处理如此大的矩阵。

      • Jason Brownlee 2019年5月3日上午6:21 #

        可以尝试在您自己的工作站或 AWS EC2 上运行吗?

  42. vijay 2019年2月13日下午4:49 #

    嗨,Jason,
    我有两个问题,

    1. 当我们用新的序列测试时,而不是尝试训练数据中已有的相同序列,会发生什么?

    2. 为什么您可以使用 voc_size-1?

    • Jason Brownlee 2019年2月14日上午8:38 #

      好问题,不确定。模型是针对特定数据集量身定制的,它可能会生成垃圾数据或回到它已知的模式。

      不确定您的第二个问题,您具体指的是什么?

  43. saria 2019年3月13日凌晨3:51 #

    Jason 您好,希望您能帮助我解除困惑。
    所以当我们把数据输入 LSTM 时,一个关于特征,另一个关于时间戳。
    如果我对保持上下文为一段话感兴趣,而我拥有的最长段落是 200 个单词,那么我应该将时间戳设置为 200。
    但是特征会怎样呢?
    输入到模型的特征会是什么?
    这里的特征是单词吗?还是段落?
    抱歉,这让我非常困惑,我不确定如何准备我的文本数据。
    如果这里的特征是单词,那么为什么我需要按段落分割?在这种情况下,我可以按单词分割并设置时间戳为 200,这样我的上下文就可以保持 200 个单词。
    我这样做对吗?

    感谢您的时间和耐心:)

    • Jason Brownlee 2019年3月13日上午8:01 #

      如果您输入的是单词,那么一个特征就是一个单词,无论是独热编码还是使用词嵌入编码。

  44. islam 2019年3月29日晚上11:23 #

    感谢您提供另一个信息丰富的网站。我还能在哪里
    找到像这样写得如此完美的信息?我
    有一个项目我正在处理,我一直在
    寻找这类信息。

  45. torr 2019年3月31日下午3:51 #

    您能帮我提供语法检查器的代码和好文章吗?

  46. Aksha 2019年4月6日凌晨3:45 #

    我是 NLP 领域的新手。如果您有一个输入文本“The price of orange has increased”(橙子的价格上涨了),输出文本“Increase the production of orange”(增加橙子的产量)。我们能否让我们的 RNN 模型预测输出文本?或者我应该使用什么算法?您能告诉我使用什么算法来映射输入句子到输出句子吗?

  47. Thomas L. Packer 2019年4月27日上午7:48 #

    对于那些想使用神经语言模型来计算句子概率的人,请看这里。

    https://stackoverflow.com/questions/51123481/how-to-build-a-language-model-using-lstm-that-assigns-probability-of-occurence-f

  48. Thomas L. Packer 2019年4月30日凌晨3:51 #

    而不是写一个循环

    为什么不使用分词器的其他字典呢

    • Thomas L. Packer 2019年4月30日上午3:52 #

      我是新来的。你们如何标记评论中的代码块?你们如何添加个人资料图片?

      • Jason Brownlee 2019年4月30日上午7:03 #

        您可以使用 `

        ` HTML 标签(我已经为您修复了之前的评论)。

        个人资料图片基于 gravatar,就像您可能遇到的任何 WordPress 博客一样。
        https://en.gravatar.com/

    • Jason Brownlee 2019年4月30日上午7:02 #

      听起来不错,它有效吗?

      • Thomas L. Packer 2019年5月3日上午3:13 #

        谢谢。我确实尝试了另一个字典,它似乎既有效又运行得更快。

  49. Shivam Bhati 2019年6月5日晚上10:37 #


    首先,感谢您完成如此出色的项目。
    我曾致力于此项目,但在预测值时遇到了困难。

    错误显示:
    ValueError: Error when checking input: expected embedding_1_input to have shape (50,) but got array with shape (1,)

    你能帮忙吗?

    • Jason Brownlee 2019年6月6日上午6:30 #

      该错误表明您的数据与模型的期望之间存在不匹配。

      您可以更改您的数据或更改模型的期望。

  50. Sidharth 2019年6月18日下午6:11 #

    你好!谢谢你的代码
    有没有办法将 Keras 模型转换为 TFLite 或 TensorFlow 模型,因为官方文档显示 TFLite 不支持 LSTM 层?

    谢谢!

  51. Shashank 2019年6月24日晚上10:35 #

    先生,请务必帮帮我。我正在做文本摘要。我能用语言模型来做吗,因为我对神经网络了解不多,或者如果您有任何建议,想法,请告诉我。我还有大约 20 天时间完成项目。
    非常感谢!

  52. Shashank 2019年6月24日晚上11:40 #

    先生,语言模型如何处理像金钱、日期之类的数字数据?
    如果存在问题,该如何解决这个问题?我正在做文本摘要,而这些数字数据对于摘要可能很重要。我该如何处理它们?
    非常感谢您的博文!非常喜欢您的帖子。说真的,非常有帮助!

    • Jason Brownlee 2019年6月25日上午6:22 #

      对于小型数据集,最好将它们归一化为单个形式,例如单词。

  53. Kakoli 2019年8月1日上午4:12 #

    再次感谢您发布了这篇精彩的博文。
    我尝试了此处关于《爱丽丝梦游仙境》的词级别建模,该书来自 Project Gutenberg。但损失值太大了,从 6.39 开始,并没有怎么降低。前 10 个 epoch 损失在 6.18-6.19 之间。有什么建议吗?

  54. Kuro 2019年8月29日上午6:33 #

    我修改了 clean_doc,使其生成独立的标点符号标记,但单引号用作撇号时除外,例如 "don't"、"Tom's"。

    在第一次运行模型制作时,我将 batch_size 和 epochs 参数更改为 512 和 25,认为这可能会加快进程。在 MacBook Pro 上耗时 2 小时,但运行序列生成程序生成的文本大部分重复了“and the same, ”,如下所示:

    to be the best , and the same , and the same , and the same , and the same , and the same , and the same , and the same , and the same , and the same , and the same , and

    我将 batch_size 和 epochs 改回了原始值(125,100),然后通宵运行了模型构建程序。然后生成的序列看起来更合理。例如:

    be a fortress to be justice and not yours , as we were saying that the just man will be enough to support the laws and loves among nature which we have been describing , and the disregard which he saw the concupiscent and be the truest pleasures , and

    对我第一次尝试的糟糕结果是否有直观的解释?第一次尝试的最后一个 epoch 的损失值为 4.125,第二次尝试(结果良好)的损失值为 2.2130。我忘了记录准确率。

    • Jason Brownlee 2019年8月29日下午1:30 #

      嗯,凭经验来看,增加更多的 token 可能需要增加数量级的数据、训练和一个更大的模型。

  55. Kuro 2019年8月31日上午8:36 #

    我正尝试将这些程序应用于某个流派的歌曲歌词集。一首歌通常由 50 到 200 个单词组成。由于它们属于同一流派,词汇量相对较小(谈论失去的爱、灵魂等)。在这种情况下,将序列大小从 50 减少到 20 是否有意义?
    我的实验目标是通过给出前 5-10 个单词来生成歌词,纯粹为了好玩。

    • Jason Brownlee 2019年9月1日上午5:33 #

      听起来很有趣。

      也许可以尝试一下,看看什么最适合您的特定数据集。

      我很想看看您的发现。

  56. Aly 2019年9月1日上午5:59 #

    我正在针对阿拉伯语文本语料库实现这一点,但每次运行时,我都会在整个文本生成过程中得到重复相同的单词。我正在训练约 50,000 个单词,约 16,000 个唯一单词。我尝试了层数、更多数据(但这是一个问题,因为唯一单词的数量也会增加,这是一个有趣的发现,感觉像 Tokenizer 和非英语之间的错误)和 epoch。

    有什么办法可以解决这个问题吗?

  57. Irfan Danish 2019年10月2日凌晨1:51 #

    有没有办法从单个种子生成 2 或 3 个不同的样本文本?
    例如,我们输入“Hello I’m”,模型会给我们:
    Hello I’m interested in
    Hello I’m a bit confused
    Hello I’m not sure
    而不是只生成一个输出,而是给出 2 到 3 个最佳输出。
    实际上,我训练了您的模型,将序列长度从 50 改为 3,现在我希望当我输入一个三个单词的种子时,不是只生成一个三个单词的序列,而是生成 2 到 3 个与该种子相关的序列。这可能吗?请告诉我,我将非常感谢您!

  58. Arjun 2019年10月17日下午4:38 #

    你好,
    X 和 y 会是怎样的?
    是否可以通过将 X 和 y 分割成训练集和测试集来完成?
    另外,当模型创建后,嵌入层的输入会是什么?
    然后将模型拟合到 X_train 上?

    • Jason Brownlee 2019年10月18日上午5:46 #

      抱歉,我不明白。您具体指的是什么?

      • Arjun 2019年10月18日下午3:26 #

        在拟合模型时,我似乎得到了一个错误。
        ValueError: Error when checking input: expected embedding_input to have 2 dimensions, but got array with shape (264, 5, 1)
        但输入应该是 3D 的,对吧?
        所以我想,也许我在嵌入层中给出的输入有问题?
        如果是这样,嵌入层应该给出哪些输入?

        • Jason Brownlee 2019年10月19日上午6:26 #

          嵌入层的输入是 2D 的,每个样本都是一个映射到单词的整数向量。

          • Arjun 2019年10月21日下午4:52 #

            好的,那么在模型形成后,我们将在拟合时将 X_train 设置为 3D 吗?

          • Jason Brownlee 2019年10月22日上午5:42 #

            不。嵌入的输入是 2D 的。

  59. Arjun 2019年10月21日下午5:00 #

    您知道如何使用 RNN 进行神经网络旋律创作吗?
    根据一份已发表的论文,其中使用了两个编码器并将其输入到一个解码器。
    我想知道您是否能提供一些见解?
    这是论文。
    https://arxiv.org/pdf/1809.04318.pdf

  60. Arjun 2019年10月23日下午3:50 #

    它并没有完全解决我的疑问,但即使如此,谢谢你的帮助。

  61. Arjun 2019年10月24日下午4:23 #

    您好,如果我有两个输入序列,并且对这两个序列输入都有训练和测试。
    我设法将两个输入连接起来并创建一个模型。
    但是当涉及到拟合模型时,如何为两个序列提供 X 和 y?

    • Jason Brownlee 2019年10月25日上午6:35 #

      如果您有一个多输入模型,那么 `fit()` 函数将接受一个包含每个样本数组的列表。

      例如

      X1 = …
      X2 = …
      X = [X1, X2]

      model.fit(X, y, ….)

      • Arjun 2019年10月25日下午4:03 #

        那么在训练 RNN 时,我们也应该有相同数量的输出吗?

  62. Arjun 2019年10月28日下午3:23 #

    如果我们有两个不同的输入,并且需要一个同时包含这两个输入的模型,该怎么办?
    我们是否可以将这两个输入都放入一个模型中,或者创建两个具有相应输入的模型,然后在最后将这两个模型合并?

    • Jason Brownlee 2019年10月29日上午5:19 #

      当然,有许多不同的方法可以解决问题。也许可以探索几种不同的方法,看看哪种最适合您的数据集?

  63. Arjun 2019年10月29日下午3:12 #

    好的..
    谢谢您..

  64. Arjun 2019年10月31日下午3:30 #

    我们如何知道两个输入是否已对齐?
    我们可以通过合并两个模型来做到这一点吗?
    无论哪种方式,我们都只能在测试之后才能知道结果,对吧?

    • Jason Brownlee 2019年11月1日上午5:25 #

      是的。

      我们的想法是通过验证来建立对模型的信任。

      • Arjun 2019年11月1日下午3:47 #

        验证是什么意思?

        • Jason Brownlee 2019年11月2日上午6:38 #

          使用测试集确认模型能产生合理的结果。

  65. Arjun 2019年11月4日下午4:46 #

    嗨,Jason,
    我一直在做一个文本生成问题。
    似乎在拟合 X_train 和 y_train 时遇到了问题。
    这与形状不兼容有关。但我将 batch size 设置为 1 后,它就能运行了。
    但是当它进行评估部分时,它显示了之前的错误。

    InvalidArgumentError: 找到 2 个根错误。
    (0) Invalid argument: Incompatible shapes: [32,5,5] vs. [32,5]
    [[{{node metrics/mean_absolute_error/sub}}]]
    (1) Invalid argument: Incompatible shapes: [32,5,5] vs. [32,5]
    [[{{node metrics/mean_absolute_error/sub}}]]
    [[metrics/mean_absolute_error/Identity/_153]]
    0 次成功操作。
    0 个派生错误被忽略。
    这可能是什么原因?

  66. Arjun 2019年11月5日下午3:25 #

    我只是很困惑,为什么它在拟合时运行,但在评估时不运行?
    我的意思是,我们无法在评估中对参数做太多调整?

    • Jason Brownlee 2019年11月6日上午6:30 #

      抱歉,我不明白您的问题,也许您可以详细说明?

  67. Arjun 2019年11月6日下午3:09 #

    哦,抱歉,我的回复是基于之前的评论。

    InvalidArgumentError: 找到 2 个根错误。
    (0) Invalid argument: Incompatible shapes: [32,5,5] vs. [32,5]
    [[{{node metrics/mean_absolute_error/sub}}]]
    (1) Invalid argument: Incompatible shapes: [32,5,5] vs. [32,5]
    [[{{node metrics/mean_absolute_error/sub}}]]
    [[metrics/mean_absolute_error/Identity/_153]]
    0 次成功操作。
    0 个派生错误被忽略。

    这个错误是在我拟合模型时发现的。但是当我把 batch size 设为 1 时,模型拟合得没有问题。
    但是当我尝试评估它时,出现了同样的错误。
    您知道为什么它在拟合时工作,但在评估时不工作吗?

    • Jason Brownlee 2019年11月7日上午6:34 #

      抱歉,我没有见过这个错误。

      也许尝试将您的代码和错误发布到stackoverflow?

      • Arjun 2019年11月7日下午3:25 #

        好的,没问题..
        谢谢你

  68. Arjun 2019年11月6日下午5:13 #

    你好 jason,
    您能否就 Keras 中的注意力机制提供一些见解?

    • Jason Brownlee 2019年11月7日上午6:35 #

      Keras 目前不支持注意力机制。

      • Arjun 2019年11月7日下午3:17 #

        还有其他实现注意力机制的方法吗?

        • Jason Brownlee 2019年11月8日上午6:38 #

          是的

          - 手动实现
          - 使用第三方实现
          - 直接使用 TensorFlow
          - 使用 PyTorch

  69. Arjun 2019年11月7日晚上8:50 #

    训练准确率增加而验证准确率下降的原因是什么?
    这是过拟合的情况吗?

    • Jason Brownlee 2019年11月8日上午6:40 #

      准确率是会波动的。

      请查看训练和验证损失。

      • Arjun 2019年11月8日下午3:19 #

        甚至验证损失似乎也在波动。
        那么这可能是过拟合的情况,对吧?
        如果是这样,我们该如何解决这个问题?

        • Jason Brownlee 2019年11月9日上午6:10 #

          或者验证数据集太小和/或不能代表训练数据集。

          • Arjun 2019年11月11日下午3:20 #

            我正在为情感分析训练 IMDB 数据集。我正在训练 100,000 个单词。
            一切似乎都进展顺利,直到训练部分,此时损失和准确率不断波动。
            验证数据集是从整个数据集中分割出来的,所以我认为这不是问题。

          • Jason Brownlee 2019年11月12日上午6:33 #

            也许尝试替代模型?
            也许可以尝试一种替代的数据准备方法?
            也许可以尝试一种替代的配置?

  70. Arjun 2019年11月13日晚上11:41 #

    我们如何知道 IMDB 数据集中的总词数?
    不是词汇量,而是数据集的大小?

    • Jason Brownlee 2019年11月14日上午8:03 #

      对所有样本的长度求和。

      • Arjun 2019年11月14日下午3:36 #

        此数据集中,一个样本是一条评论。每条评论包含不同数量的单词。我们考虑数据集包含10000或100000个单词,并将其分为训练集和测试集。所以,我需要获取总单词数。

  71. Augusto 2019年12月28日上午9:07 #

    嗨,Jason,

    我完成了你帖子“使用Keras的Python LSTM循环神经网络进行文本生成”中的练习,但你在此处描述的使用语言模型的方法产生的文本更连贯,那么你能否详细说明何时使用一种技术而不是另一种?

    提前感谢,

    • Jason Brownlee 2019年12月29日上午5:59 #

      好问题。

      没有好的启发式方法。也许可以遵循偏好,或者在特定数据集和指标上的模型技能。

  72. Fred 2020年1月3日上午6:48 #

    你好!我正在尝试转换此示例,以制作一个简单的概念验证模型来进行单词预测,该模型可以使用相同的训练模型向后和向前进行推理。(不重复数据)

    我想将文本行在中间分割,并将目标单词放在那里。像这样

    X1 y X2
    1. [yesterday to the piraeus with glaucon the son of ariston]
    2. [yesterday to the piraeus with glaucon the son of ariston that]
    3. [to the piraeus with glaucon the son of ariston that i]
    等等
    (X1 和 X2 实际上是各 20 个单词)

    我一直遇到各种数据格式错误,感觉自己尝试了很多方法,但显然正确的方法仍然难以捉摸。

    这大致是我的代码,

    X1 = X1.reshape((n_lines+1, 20))
    X2 = X2.reshape((n_lines+1, 20))
    y = y.reshape((n_lines+1, vocab_size))

    model = Sequential()
    model.add(Embedding(vocab_size, 40, input_length=seq_length))
    model.add(LSTM(100, return_sequences=True, input_shape=(20, 1)))
    model.add(LSTM(100))
    model.add(Dense(100, activation=’relu’))
    model.add(Dense(vocab_size, activation=’softmax’))
    model.compile(loss=’categorical_crossentropy’, optimizer=’adam’, metrics=[‘accuracy’])

    model.fit(np.array([X1, X2]), np.array(y), batch_size=128, epochs=10)

    您认为这应该接近成功,而且您知道为什么我似乎无法输入两个“X”特征吗?

    谢谢,Fred

  73. Wei Jiang 2020年1月25日下午8:06 #

    我想考虑所有因素,包括标点符号,所以我在下面注释掉了这一行

    tokens = [word for word in tokens if word.isalpha()]

    但是当我运行时,我遇到了以下错误
    回溯(最近一次调用)
    File “lm2.py”, line 34, in
    X, y = sequences[:,:-1], sequences[:,-1]
    IndexError: 数组索引过多

    有什么想法吗?

  74. sachin 2020年2月27日下午1:52 #

    老师,当我们要考虑句子的上下文来将其分类到某个类别时,我应该使用哪种神经网络架构。

    例如:我想像这样分类,

    他们杀了很多人:无毒

    我要杀了他们:有毒

  75. Dylan Lunde 2020年3月12日上午8:05 #

    有没有人明确解决了“数组的索引太多”这个问题?

    IndexError Traceback (最近一次调用)
    in ()
    1 sequences = np.array(sequences)
    —-> 2 X, y = sequences[:,:-1], sequences[:,-1]
    3 y = to_categorical(y, num_classes=vocab_size)
    4 seq_length = X.shape[1]

    IndexError: 数组索引过多

  76. Carson 2020年3月27日下午2:21 #

    我有一个问题,你将 50 个单词输入到你的神经网络中,然后得到一个输出单词,如果我没记错的话,但当你只输入 50 个单词时,你怎么能得到一个 50 个单词的文本呢?

    • Jason Brownlee 2020年3月28日上午6:11 #

      你可以递归地使用相同的模型,将输出作为输入,或者可以使用使用编码器-解码器模型实现的 seq2seq 模型。

      你可以在这个博客上找到很多用于 NLP 的编码器-解码器示例,也许从这里开始
      https://machinelearning.org.cn/start-here/#nlp

  77. Arsal 2020年4月26日上午8:43 #

    你能做一个关于使用 GANs 进行文本生成的教程吗?

    • Jason Brownlee 2020年4月27日上午5:23 #

      感谢您的建议。

      语言模型用于文本生成,GANs 用于生成图像。

  78. Efstathios Chatzikyriakidis 2020年5月15日上午3:35 #

    嗨,Jason,

    两个问题

    “该模型需要 100 个单词作为输入。”

    我认为是 50 个。

    另外

    “简化词汇。探索更简单的词汇,也许可以去除词干处理或去除停用词。”

    这通常用于文本分类。在语言模型中这样做并用于文本生成会导致糟糕的结果。停用词对于捕捉基本单词组很重要,例如:“I went to the”。

    • Jason Brownlee 2020年5月15日上午6:12 #

      谢谢你发现这个印刷错误。

      当然,随意更改!

  79. Vipul 2020年5月30日下午5:03 #

    我需要一个深度神经网络来从预定义的候选中选择一个单词。请给我一些解决方案。

  80. Prem 2020年6月1日上午9:58 #

    对于句子级别的训练,下面帖子中的模型 2 是否基本上展示了这一点?
    https://machinelearning.org.cn/develop-word-based-neural-language-models-python-keras/

  81. Laura 2020年6月4日下午8:29 #

    你好 Jason!感谢你的帖子。
    我需要构建一个神经网络来检测系统调用执行中的异常,以及这些系统调用接收的参数。哪种解决方案适合这个问题?
    提前感谢!

    • Jason Brownlee 2020年6月5日上午8:09 #

      也许可以从文本输入和类别标签输出开始,例如文本分类模型。测试词袋模型和嵌入表示,看看哪个效果最好。

  82. Laura 2020年6月5日凌晨12:04 #

    嗨,Jason!
    感谢您的帖子!
    我需要构建一个神经网络来检测系统调用执行中的异常以及它们接收的参数中的异常。您对此有什么建议?
    提前感谢!

    • Jason Brownlee 2020年6月5日上午8:14 #

      我建议原型化并系统地评估一系列不同的模型,并发现什么最适合您的数据集。

  83. Neha 2020年6月10日下午1:32 #

    你好 sir,感谢如此精彩的帖子,但是 sir,如何处理 csv 文件,如何加载、保存它们?我是一名深度学习新手,您能给我一些语法的思路吗?

  84. Kaalu 2020年6月16日下午12:15 #

    嗨,Jason,

    感谢您提供有用的分步教程和相关解释。我正尝试将此技术用于为特定恶意软件家族/类型生成 snort 规则(某种程度上类似于防火墙规则 / 入侵检测规则)。您认为这可行吗?您能给我一些提示吗?这样做是否可行,因为此类规则需要遵循特定的格式或关键字序列。

    这是规则示例。

    “alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:”MALWARE-BACKDOOR Win.Backdoor.Demtranc variant outbound connection”; flow:to_server,established; content:”GET”; nocase; http_method; content:”/AES”; fast_pattern; nocase; http_uri; pcre:”/\/AES\d+O\d+\.jsp\?[a-z0-9=\x2b\x2f]{20}/iU”; metadata:policy balanced-ips drop, policy max-detect-ips drop, policy security-ips drop, service http; reference:url,www.virustotal.com/file/b3a97be4160fb261e138888df276f9076ed76fe2efca3c71b3ebf7aa8713f4a4/analysis/; classtype:trojan-activity; sid:24115; rev:3;)

    您的建议将不胜感激。

    • Jason Brownlee 2020年6月16日下午1:40 #

      不客气。

      或许可以试试看?

      我最好的建议是回顾文献,看看其他人如何解决相同类型的问题。这将节省大量时间,并可能很快获得良好的结果。

      • Kaalu 2020年6月16日晚上11:37 #

        嗨,Jason,

        非常感谢。可惜我没有找到任何文献让他们有类似的东西🙁。这就是我联系你的原因。

        我会继续搜索。

        • Jason Brownlee 2020年6月17日上午6:24 #

          坚持下去,也许可以搜索另一个“足够接近”的项目,并从中挖掘想法。

          • Ebenezer A. Laryea 2020年6月19日上午1:36 #

            谢谢

  85. Hilal Ozer 2020年8月26日上午7:54 #

    嗨,Jason,

    感谢这篇精彩的帖子。我使用了您的代码来进行词素预测。起初我实现了固定序列长度,但后来我必须使其可变序列长度。所以,我使用了 stateful LSTM,batch size 为 1,并将序列长度设置为 None。

    我尝试一次拟合一个样本。但是,我遇到了“ValueError: Input arrays should have the same number of samples as target arrays. Found 1 input samples and 113 target samples。”

    输入和输出样本的大小实际上是相等的,“113”是输出的 one-hot 向量大小。在我的第一个固定序列实现中,目标输出实现与您的代码完全相同,并且运行正确。
    您知道为什么模型不识别 one-hot 编码吗?

    提前感谢。

    • Jason Brownlee 2020年8月26日下午1:42 #

      不客气。

      如果您使用的是 stateful LSTM,您可能需要将目标设置为 3D 而不是 2D,例如 [samples, timesteps, features]。我可能错了,但我记得这可能是一个需要考虑的问题。

  86. Hilal Ozer 2020年8月27日上午7:14 #

    感谢您的回复。当我将其设置为 2D 时,它运行成功了。它本来是 1D 的。

  87. riyaz 2020年9月5日晚上9:59 #

    如果您想了解更多信息,还可以查看 Keras Team 在 GitHub 上的文本生成实现:https://github.com/keras-team/keras/blob/master/examples/lstm_text_generation.py

    看看这段代码……它展示得很好。

  88. Minura Punchihewa 2020年9月13日凌晨4:09 #

    嗨,Jason,

    我使用了一个类似的 RNN 架构来开发一个语言模型。我现在想做的是,当向模型提供一个完整的句子时,能够生成它的概率。

    注意:我指的是整个句子的概率,而不仅仅是下一个单词。

    您是否知道如何做到这一点?

    根据我所了解的,这种机制用于语音识别软件的实现。

    • Jason Brownlee 2020年9月13日上午6:12 #

      好问题,我没有示例。

      也许手动计算一下如何做到这一点,然后实现它?
      也许查阅文献,看看是否有人以前做过,以及是如何做的?
      也许查看开源库,看看它们是否提供此功能,并了解它们是如何做到的?

  89. Minura Punchihewa 2020年9月14日凌晨5:34 #

    我一直在查找,但仍然找不到答案。

  90. Pranav 2020年9月28日凌晨1:04 #

    你好 Jason Sir,
    感谢您提供如此精彩且信息丰富的博客,关于文本生成。刚看到标题时,我以为会很难,但解释和代码都很简洁易懂。期待阅读您更多博客!!

  91. John Bueno 2020年10月7日下午2:43 #

    我遵循了这些步骤,几乎完成了,但在这一错误上卡住了

    回溯(最近一次调用)
    File “C:/Users/andya/PycharmProjects/finalfinalFINALCHAIN/venv/Scripts/Monster.py”, line 45, in
    yhat = model.predict_classes(encoded)
    File “C:\Users\andya\PycharmProjects\finalfinalFINALCHAIN\venv\lib\site-packages\keras\models.py”, line 1138, in predict_classes
    steps=steps)
    File “C:\Users\andya\PycharmProjects\finalfinalFINALCHAIN\venv\lib\site-packages\keras\models.py”, line 1025, in predict
    steps=steps)
    File “C:\Users\andya\PycharmProjects\finalfinalFINALCHAIN\venv\lib\site-packages\keras\engine\training.py”, line 1830, in predict
    check_batch_axis=False)
    File “C:\Users\andya\PycharmProjects\finalfinalFINALCHAIN\venv\lib\site-packages\keras\engine\training.py”, line 129, in _standardize_input_data
    str(data_shape))
    ValueError: Error when checking : expected embedding_1_input to have shape (50,) but got array with shape (51, 1)

    供参考,我明确使用了几乎与您相同版本的库。除了第一个状态语句之外,其他一切都正常。

    yhat = model.predict_classes(encoded, verbose=0)

    我尝试过修改代码,但遗憾的是,我的数学和软件技能还不足以找到一个合适的解决方案。您可能需要记住,我已经修改了文本清理器,以保留数字和标点符号,即使在将其恢复正常时,它似乎也没有修复任何问题。还值得注意的是,为了测试目的,我已经将 epoch 数量设置为 1,但我怀疑这应该有任何影响。除此之外,应该没有重要的偏差。

  92. Payton F 2020年10月27日上午9:18 #

    嗨,Jason,

    您将如何处理在多个不同文本源上训练模型?例如,如果我想在演讲稿上训练一个模型,以便能够生成特定发言者风格的文本,我是否应该将所有演讲稿存储在一个 .txt 文件中?我担心如果这样做,我会得到一些误导性的序列,例如序列以一个演讲稿的词开头,然后以下一个演讲稿的开头词结尾。将模型训练成一次一个演讲稿,而不是在一个包含所有演讲稿的大文件中训练,会不会更好?

    • Jason Brownlee 2020年10月27日下午1:01 #

      也许为每个源训练一个单独的模型,然后使用模型的集成/堆叠来组合。

  93. 123 2020年11月6日凌晨6:43 #

    我现在不确定您的信息来源,但这是一个好话题。
    我必须花一些时间学习更多或了解更多。
    感谢您提供我一直在寻找的精彩信息,这对我现在的任务很有帮助。

  94. cnsn8 2021年4月6日凌晨12:43 #

    感谢 Jason 的精彩教程。我如何为这个语言模型添加简单的控制?例如,正面-负面文本生成。

    • Jason Brownlee 2021年4月6日凌晨5:18 #

      不客气。

      也许分别为每种类型开发一个模型?

  95. Eric 2021年4月27日下午8:35 #

    嗨,Jason,

    在这个步骤中,我收到了这些代码。

    # 定义模型
    model = Sequential()
    model.add(Embedding(vocab_size, 50, input_length=seq_length))
    model.add(LSTM(100, return_sequences=True))
    model.add(LSTM(100))
    model.add(Dense(100, activation=’relu’))
    model.add(Dense(vocab_size, activation=’softmax’))
    打印(model.summary())

    ————————————————
    总序列数: 118633
    2021-04-27 06:24:25.190966: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library ‘cudart64_110.dll’; dlerror: cudart64_110.dll not found
    2021-04-27 06:24:25.191304: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.
    2021-04-27 06:24:33.866815: I tensorflow/stream_executor/platform/default/dso_loader.cc:49] Successfully opened dynamic library nvcuda.dll
    2021-04-27 06:24:34.937609: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1733] Found device 0 with properties
    pciBusID: 0000:01:00.0 name: GeForce GTX 1050 Ti computeCapability: 6.1
    coreClock: 1.62GHz coreCount: 6 deviceMemorySize: 4.00GiB deviceMemoryBandwidth: 104.43GiB/s
    2021-04-27 06:24:34.940037: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library ‘cudart64_110.dll’; dlerror: cudart64_110.dll not found
    2021-04-27 06:24:34.941955: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library ‘cublas64_11.dll’; dlerror: cublas64_11.dll not found
    2021-04-27 06:24:34.943931: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library ‘cublasLt64_11.dll’; dlerror: cublasLt64_11.dll not found
    2021-04-27 06:24:34.945872: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library ‘cufft64_10.dll’; dlerror: cufft64_10.dll not found
    2021-04-27 06:24:34.947770: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library ‘curand64_10.dll’; dlerror: curand64_10.dll not found
    2021-04-27 06:24:34.949522: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library ‘cusolver64_11.dll’; dlerror: cusolver64_11.dll not found
    2021-04-27 06:24:34.951167: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library ‘cusparse64_11.dll’; dlerror: cusparse64_11.dll not found
    2021-04-27 06:24:34.952449: W tensorflow/stream_executor/platform/default/dso_loader.cc:60] Could not load dynamic library ‘cudnn64_8.dll’; dlerror: cudnn64_8.dll not found
    2021-04-27 06:24:34.952766: W tensorflow/core/common_runtime/gpu/gpu_device.cc:1766] Cannot dlopen some GPU libraries. Please make sure the missing libraries mentioned above are installed properly if you would like to use GPU. Follow the guide at https://tensorflowcn.cn/install/gpu for how to download and setup the required libraries for your platform.
    Skipping registering GPU devices…
    2021-04-27 06:24:34.954395: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations: AVX AVX2
    To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
    2021-04-27 06:24:34.955743: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1258] Device interconnect StreamExecutor with strength 1 edge matrix
    2021-04-27 06:24:34.956035: I tensorflow/core/common_runtime/gpu/gpu_device.cc:1264]
    回溯(最近一次调用)
    File “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\LANGUAGE MODEL BUILDING\LANGUAGE MODEL TEST.py”, line 105, in
    model.add(LSTM(100, return_sequences=True))
    File “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\tensorflow\python\training\tracking\base.py”, line 522, in _method_wrapper
    result = method(self, *args, **kwargs)
    File “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\keras\engine\sequential.py”, line 223, in add
    output_tensor = layer(self.outputs[0])
    File “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\keras\layers\recurrent.py”, line 660, in __call__
    return super(RNN, self).__call__(inputs, **kwargs)
    File “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\keras\engine\base_layer.py”, line 945, in __call__
    return self._functional_construction_call(inputs, args, kwargs,
    File “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\keras\engine\base_layer.py”, line 1083, in _functional_construction_call
    outputs = self._keras_tensor_symbolic_call(
    File “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\keras\engine\base_layer.py”, line 816, in _keras_tensor_symbolic_call
    return self._infer_output_signature(inputs, args, kwargs, input_masks)
    File “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\keras\engine\base_layer.py”, line 856, in _infer_output_signature
    outputs = call_fn(inputs, *args, **kwargs)
    File “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\keras\layers\recurrent_v2.py”, line 1139, in call
    inputs, initial_state, _ = self._process_inputs(inputs, initial_state, None)
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\keras\layers\recurrent.py”,第 860 行,在 _process_inputs 中
    initial_state = self.get_initial_state(inputs)
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\keras\layers\recurrent.py”,第 642 行,在 get_initial_state 中
    init_state = get_initial_state_fn(
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\keras\layers\recurrent.py”,第 2508 行,在 get_initial_state 中
    return list(_generate_zero_filled_state_for_cell(
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\keras\layers\recurrent.py”,第 2990 行,在 _generate_zero_filled_state_for_cell 中
    return _generate_zero_filled_state(batch_size, cell.state_size, dtype)
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\keras\layers\recurrent.py”,第 3006 行,在 _generate_zero_filled_state 中
    return tf.nest.map_structure(create_zeros, state_size)
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\tensorflow\python\util\nest.py”,第 867 行,在 map_structure 中
    structure[0], [func(*x) for x in entries],
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\tensorflow\python\util\nest.py”,第 867 行,在 中
    structure[0], [func(*x) for x in entries],
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\keras\layers\recurrent.py”,第 3003 行,在 create_zeros 中
    return tf.zeros(init_state_size, dtype=dtype)
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\tensorflow\python\util\dispatch.py”,第 206 行,在 wrapper 中
    return target(*args, **kwargs)
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\tensorflow\python\ops\array_ops.py”,第 2911 行,在 wrapped 中
    tensor = fun(*args, **kwargs)
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\tensorflow\python\ops\array_ops.py”,第 2960 行,在 zeros 中
    output = _constant_if_small(zero, shape, dtype, name)
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\tensorflow\python\ops\array_ops.py”,第 2896 行,在 _constant_if_small 中
    if np.prod(shape) < 1000
    文件 " ", 第 5 行,在 prod 中
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\numpy\core\fromnumeric.py”,第 3030 行,在 prod 中
    return _wrapreduction(a, np.multiply, ‘prod’, axis, dtype, out,
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\numpy\core\fromnumeric.py”,第 87 行,在 _wrapreduction 中
    return ufunc.reduce(obj, axis, dtype, out, **passkwargs)
    文件 “D:\PYTHON SOFTWARE\Doc\LEARN PYTHON\venv\lib\site-packages\tensorflow\python\framework\ops.py”,第 867 行,在 __array__ 中
    raise NotImplementedError(
    NotImplementedError: Cannot convert a symbolic Tensor (lstm/strided_slice:0) to a numpy array. This error may indicate that you’re trying to pass a Tensor to a NumPy call, which is not supported

    我的库是:
    Python 3.9
    Theano 1.0.5
    Numpy 1.20.2
    pip 21.1
    keras 2.4.3
    tensorflow 2.4.1
    matplotlib 3.4.1
    pandas 1.2.4

    我正在使用 PyCharm。看到这么多错误信息后,我想在从 PyCharm 外部运行脚本之前等待一下。

    我的电脑有一个 GPU,是一台配备 NVIDIA 独立显卡的 DELL G3,但我没有为它进行任何设置或配置,以为运行这个教程不需要它。

    非常感谢您的帮助!

  96. lp 2021 年 10 月 7 日晚上 10:55 #

    感谢教程,如果能提供 TF2 版本 的解码器会很好,predict_classes() 已弃用

    谢谢!

    • Adrian Tam
      Adrian Tam 2021 年 10 月 12 日上午 12:19 #

      谢谢你的建议。应该是用 np.argmax(model.predict_class(encoded)) 代替。

      • Amrit 2022 年 7 月 10 日下午 12:52 #

        尝试替换但代码不起作用。
        model.predict_classes(encoded, verbose=0) -> np.argmax(model.predict_class(encoded))

        对此有什么解决方案吗?谢谢。。

        • James Carmichael 2022 年 7 月 11 日上午 4:24 #

          你好 Amrit…你收到什么错误了?这将有助于我们更好地帮助你。

  97. Manuela 2021 年 11 月 10 日上午 3:04 #

    在“普通”笔记本电脑上运行此示例需要多长时间,CPU 1.10 GHz?可行吗?

    • Adrian Tam
      Adrian Tam 2021 年 11 月 14 日下午 1:14 #

      我相信可以。除非你的内存真的很小。

  98. John LI 2022 年 1 月 28 日下午 12:58 #

    你好 Jason,我有一个问题。希望你能花时间回答。关于这个例子,在训练的每个周期中,每行文本的第 51 个单词被预测出来,最终如何预测出有意义的连续单词字符串?

    • James Carmichael 2022 年 1 月 31 日上午 11:08 #

      你好 John…请重述或阐述你的问题,以便我能更好地帮助你。

      • John LI 2022 年 1 月 31 日下午 1:17 #

        感谢你的及时回复,James。
        让我重新表述我的问题如下:
        1. 在训练阶段,我们将每行 50 个单词的文本字符串输入到 LSTM 中,并将输出(一个单词)与目标(该 50 个单词字符串的实际第 51 个单词)进行比较,然后反复回溯,直到权重和偏差设置为最优。简而言之,一个单词字符串被输入到模型,一个单词被预测出来。
        2. 但是在“使用语言模型”阶段,我们给出一个种子文本,生成一个 50 个单词的文本。

        3. 所以在训练时:文本 -> 单词,在使用模型时:文本 -> 文本。我的问题是:从 1 到 2,如何实现?我不是英语母语者。希望我的问题清楚。非常感谢您的时间和耐心。

  99. Aniket Saxena 2022 年 3 月 23 日上午 3:43 #

    嗨,Jason,

    我尝试探索使用预训练词嵌入(GloVe 向量)来提高您在此处讨论的文本生成任务(柏拉图的《理想国》数据集)的准确性。但是,当我下载 zip 文件(glove.6B.zip)时,我发现上述数据集中有 90 多个单词在任何可用的文本文件中(glove.6B.50d.txt、glove.6B.100d.txt、glove.6B.200d.txt 和 glove.6B.300d.txt)都没有学习到的嵌入向量。

    解决此问题的一个方法是完全从数据集中删除所有这些 90 个单词,然后通过冻结嵌入层来训练模型,但这似乎没有解决核心问题。由于预训练的 GloVe 向量 zip 文件没有预学习的嵌入向量来表示这 90 个单词,我不知道如何扩展模型以将这些预训练的 GloVe 向量用于整个柏拉图的《理想国》数据集。

    您能否建议一种在这种数据集上执行迁移学习以提高准确性(正如您在博客的扩展部分中建议的那样)的方法,以防万一可以实现?

    此致
    Aniket Saxena

  100. Feron 2022 年 7 月 1 日上午 12:27 #

    你好,你认为 flatten 层会有用或能提高模型的准确性吗?我有一个人总是提醒我使用 flatten 层放在每个模型的最后一层之后。

  101. Fati Taherin 2022 年 8 月 16 日晚上 11:43 #


    感谢您出色的教程。我都很喜欢。
    我在 Keras 中为波斯数据集实现了模型,效果很好。然后尝试实现 PyTorch 版本。模型什么也没学到。我没能找出问题所在,但我认为可能是 LSTM 层。我只想说,我用字典结构和列表为 Keras 和 PyTorch 制作了自己的分词器和整数词典。我将非常感谢任何帮助。
    非常感谢。
    这是我的模型…

    class seqModel(nn.Module)
    def __init__(self, vocab_size1=vocab_size, embedding_dim=50, hidden_size=100)
    super(seqModel, self).__init__()
    self.encoder = nn.Embedding(vocab_size1, embedding_dim)
    self.lstm1 = nn.LSTM(embedding_dim, hidden_size)
    self.lstm2 = nn.LSTM(hidden_size, hidden_size)
    self.linear1 = nn.Linear(hidden_size, hidden_size)
    self.linear2 = nn.Linear(hidden_size, vocab_size1)
    self.act1 = nn.ReLU()
    self.act2 = nn.Softmax(dim=1)

    def forward(self, x)

    output = self.encoder(x)

    output, _ = self.lstm1(output)

    output = output[:,-1,:]

    output, _ = self.lstm2(output)

    output = self.linear1(output)

    output = self.act1(output)

    output = self.linear2(output)

    output = self.act2(output)

    return output

    • James Carmichael 2022 年 8 月 17 日上午 6:20 #

      你好 Fati…不客气!请提供有关您的模型性能遇到问题的更多详细信息,以便我们能更好地帮助您。也许您的模型可以受益于超参数优化。

  102. Fati Taherin 2022 年 8 月 18 日下午 4:33 #

    谢谢回复。这是我的训练循环:

    def train3(train_loader, sModel, optimizer, criterion, epochs)
    loss_track = []
    leastLoss = 100.000
    sModel.train()
    for epoch in range(epochs)
    epoch_loss = []
    sModel.train()
    for x_batch, y_batch in train_loader
    x_batch = x_batch.to(device)
    y_batch = y_batch.to(device)
    x_batch = x_batch.to(torch.long)

    pred = model(x_batch)

    y_batch = y_batch.to(torch.float32)

    optimizer.zero_grad()

    loss = criterion(pred,y_batch)
    # 反向传播
    loss.backward()

    optimizer.step()

    epoch_loss.append(loss.item())
    print(” Epoch {} | Train Cross Entropy Loss: “.format(epoch),np.mean(epoch_loss))

    loss_track.append(np.mean(epoch_loss))
    print(“\n\n*********************************************”)

    if ((np.mean(epoch_loss)) < leastLoss)
    torch.save(sModel.state_dict(), ‘/path/Model/best_model2.pt’)

    训练模型将如下所示,并且在 20 个 epoch 中没有任何改进(仅在很小的范围内徘徊):

    Epoch 0 | Train Cross Entropy Loss: 9.027385948332194

    *********************************************
    Epoch 1 | Train Cross Entropy Loss: 9.027385958870033

    *********************************************
    Epoch 2 | Train Cross Entropy Loss: 9.027385963260798

    *********************************************
    Epoch 3 | Train Cross Entropy Loss: 9.027385970944637

    *********************************************
    Epoch 4 | Train Cross Entropy Loss: 9.027385972481406

    *********************************************
    Epoch 5 | Train Cross Entropy Loss: 9.027385962821722

    *********************************************
    Epoch 6 | Train Cross Entropy Loss: 9.027385953381575

    *********************************************
    Epoch 7 | Train Cross Entropy Loss: 9.027385970944637

    *********************************************
    *********************************************

    我的损失函数有问题吗?我的意思是,打印层的尺寸,我发现输出必须从 (16,7,100) 重塑为 (16,100),其中 16 是批次大小,7 是序列长度,100 是 lstm 层的输出,在 lstm 层之后。在模型的末尾,输出的形状是 (16,vocab_size),与 y_batch 的形状匹配。从矩阵中消除一个维度是否会导致此问题?

    我还尝试使用一个 lstm 层,并在每个批次中分离其状态,并在每个 epoch 开始时初始化状态,如下所示:

    for epoch in range(epochs)
    states = (torch.zeros(num_layers = 1, batch_size, hidden_size).to(device),
    torch.zeros(num_layers, batch_size, hidden_size).to(device))
    epoch_loss = []
    sModel.train()
    for x_batch, y_batch in train_loader
    if (x_batch.size(0) < 16)
    break
    x_batch = x_batch.to(device)
    y_batch = y_batch.to(device)
    x_batch = x_batch.to(torch.long)

    states = detach(states)
    # 状态作为参数传递给 lstm 层,如下所示:
    #output , (h,c) = self.lstm(output,states)
    pred, states = model(x_batch, states)

    y_batch = y_batch.to(torch.float32)

    model.zero_grad()

    loss = criterion(pred,y_batch)
    # 反向传播
    loss.backward()
    nn.utils.clip_grad_norm_(model.parameters(), 0.5)
    optimizer.step()

    这在我训练的 epoch 数量上也有相同的损失。
    * 还有一件事,我的 lstm 层中 batch_first = true。

    再次感谢。

  103. Nada 2022 年 9 月 7 日上午 1:09 #

    你好,非常感谢这个教程。
    我尝试复制相同的步骤,但是模型每次都预测相同的单词,我不知道问题可能是什么。您能给点提示吗??
    谢谢

留下回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。