如何使用 Keras 的词嵌入层进行深度学习

词嵌入提供了词语及其相对含义的密集表示。

它们是对简单词袋模型表示中使用的稀疏表示的改进。

词嵌入可以从文本数据中学习,并在项目之间重用。它们也可以作为拟合文本数据神经网络的一部分来学习。

在本教程中,您将学习如何在 Python 中使用 Keras 进行深度学习时使用词嵌入。

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

  • 关于词嵌入以及 Keras 通过嵌入层支持词嵌入。
  • 如何在拟合神经网络时学习词嵌入。
  • 如何在神经网络中使用预训练的词嵌入。

通过我的新书《自然语言处理深度学习启动您的项目,包括分步教程和所有示例的 Python 源代码文件。

让我们开始吧。

  • 2018年2月更新:修复了由于底层 API 更改导致的错误。
  • 2019 年 10 月更新:更新至 Keras 2.3 和 TensorFlow 2.0。
How to Use Word Embedding Layers for Deep Learning with Keras

如何使用 Keras 的词嵌入层进行深度学习
图片由此人提供,保留部分权利。

教程概述

本教程分为3个部分;它们是

  1. 词嵌入
  2. Keras 嵌入层
  3. 学习嵌入的示例
  4. 使用预训练 GloVe 嵌入的示例

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

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

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

1. 词嵌入

词嵌入是一类使用密集向量表示来表示词语和文档的方法。

它比传统的词袋模型编码方案有所改进,传统的方案使用大型稀疏向量来表示每个词,或者在向量中对每个词进行评分以表示整个词汇表。这些表示是稀疏的,因为词汇量庞大,给定的词或文档将由一个大部分由零值组成的大型向量表示。

相反,在嵌入中,词语由密集向量表示,其中向量表示词语在连续向量空间中的投影。

词语在向量空间中的位置是从文本中学习的,并基于词语使用时周围的词语。

词语在学习到的向量空间中的位置被称为其嵌入。

从文本中学习词嵌入的两个流行方法包括:

  • Word2Vec。
  • GloVe。

除了这些精心设计的方法之外,词嵌入还可以作为深度学习模型的一部分进行学习。这可能是一种较慢的方法,但它使模型适应特定的训练数据集。

2. Keras 嵌入层

Keras 提供了一个嵌入层,可用于文本数据的神经网络。

它要求输入数据是整数编码的,以便每个词都由一个唯一的整数表示。这个数据准备步骤可以使用 Keras 提供的Tokenizer API 来执行。

嵌入层用随机权重初始化,并将学习训练数据集中所有词语的嵌入。

它是一个灵活的层,可以通过多种方式使用,例如:

  • 它可以单独使用来学习词嵌入,然后可以保存并在另一个模型中使用。
  • 它可以作为深度学习模型的一部分使用,其中嵌入与模型本身一起学习。
  • 它可以用于加载预训练的词嵌入模型,这是一种迁移学习。

嵌入层被定义为网络的第一个隐藏层。它必须指定 3 个参数:

它必须指定 3 个参数:

  • input_dim:这是文本数据中词汇表的大小。例如,如果您的数据被整数编码为 0-10 之间的值,那么词汇表的大小将是 11 个词。
  • output_dim:这是词语将被嵌入的向量空间的大小。它定义了该层为每个词输出向量的大小。例如,它可以是 32 或 100,甚至更大。为您的具体问题尝试不同的值。
  • input_length:这是输入序列的长度,就像您为 Keras 模型的任何输入层定义的那样。例如,如果您的所有输入文档都包含 1000 个词,那么这将是 1000。

例如,下面我们定义了一个嵌入层,其中词汇表大小为 200(例如,整数编码的词语从 0 到 199,包括在内),词语将被嵌入的向量空间为 32 维,输入文档各有 50 个词。

嵌入层具有学习到的权重。如果您将模型保存到文件,这将包括嵌入层的权重。

嵌入层的输出是一个 2D 向量,其中输入词序列(输入文档)中的每个词都有一个嵌入。

如果您希望将一个 Dense 层直接连接到嵌入层,您必须首先使用 Flatten 层将 2D 输出矩阵展平为 1D 向量。

现在,让我们看看如何在实践中使用嵌入层。

3. 学习嵌入的示例

在本节中,我们将探讨如何在文本分类问题上拟合神经网络时学习词嵌入。

我们将定义一个小型问题,其中有 10 个文本文档,每个文档都包含对学生提交作品的评论。每个文本文档被分类为积极“1”或消极“0”。这是一个简单的情感分析问题。

首先,我们将定义文档及其类别标签。

接下来,我们可以对每个文档进行整数编码。这意味着作为输入,嵌入层将有整数序列。我们可以尝试其他更复杂的词袋模型编码,如计数或 TF-IDF。

Keras 提供了 one_hot() 函数,它将每个词创建为高效的整数编码哈希。我们将词汇表大小估计为 50,这远大于所需,以减少哈希函数冲突的可能性。

序列的长度不同,Keras 倾向于将输入向量化,并且所有输入具有相同的长度。我们将把所有输入序列填充到长度为 4。同样,我们可以使用 Keras 内置函数,在这种情况下是 pad_sequences() 函数

我们现在准备将我们的 Embedding 层定义为神经网络模型的一部分。

嵌入的词汇表大小为 50,输入长度为 4。我们将选择一个 8 维的小型嵌入空间。

该模型是一个简单的二分类模型。重要的是,Embedding 层的输出将是 4 个 8 维向量,每个词一个。我们将其展平为一个 32 元素向量,以传递给 Dense 输出层。

最后,我们可以拟合和评估分类模型。

完整的代码列表如下。

运行示例首先打印整数编码的文档。

然后打印每个文档的填充版本,使它们都具有统一的长度。

定义网络后,会打印层摘要。我们可以看到,正如预期的那样,嵌入层的输出是一个 4x8 矩阵,并通过 Flatten 层将其压缩为 32 元素向量。

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

最后,打印出训练模型的准确率,显示它完美地学习了训练数据集(这并不奇怪)。

您可以将嵌入层学习到的权重保存到文件中,以便将来在其他模型中使用。

您也可以普遍使用此模型来分类测试数据集中具有相同词汇表的其他文档。

接下来,让我们看看如何在 Keras 中加载预训练的词嵌入。

4. 使用预训练 GloVe 嵌入的示例

Keras 嵌入层也可以使用在其他地方学习到的词嵌入。

在自然语言处理领域,学习、保存和免费提供词嵌入是很常见的。

例如,GloVe 方法的研究人员在其网站上提供了一套根据公共领域许可发布的预训练词嵌入。请参阅

最小的嵌入包是 822MB,名为“glove.6B.zip”。它在一个包含十亿个标记(词语)的数据集上进行训练,词汇表大小为 40 万个词。有几种不同的嵌入向量大小,包括 50、100、200 和 300 维。

您可以下载此嵌入集合,我们可以用预训练嵌入中的权重来初始化 Keras 的 Embedding 层,以用于训练数据集中的词语。

此示例的灵感来自 Keras 项目中的一个示例:pretrained_word_embeddings.py

下载并解压后,您会看到几个文件,其中之一是“glove.6B.100d.txt”,其中包含 100 维的嵌入版本。

如果您查看该文件,您会看到每行都有一个标记(单词)和权重(100 个数字)。例如,下面是嵌入 ASCII 文本文件的第一行,显示了“the”的嵌入。

与上一节一样,第一步是定义示例,将其编码为整数,然后填充序列以使其长度相同。

在这种情况下,我们需要能够将词映射到整数,并将整数映射到词。

Keras 提供了一个 Tokenizer 类,该类可以在训练数据上进行拟合,可以通过调用 Tokenizer 类的 texts_to_sequences() 方法将文本一致地转换为序列,并提供对词到整数映射字典的访问,该字典存储在 word_index 属性中。

接下来,我们需要将整个 GloVe 词嵌入文件加载到内存中,作为词到嵌入数组的字典。

这相当慢。最好是过滤掉训练数据中不唯一的词的嵌入。

接下来,我们需要为训练数据集中的每个词创建一个嵌入矩阵。我们可以通过枚举 Tokenizer.word_index 中的所有唯一词,并从加载的 GloVe 嵌入中找到嵌入权重向量来完成此操作。

结果是一个仅包含训练期间我们将看到的词的权重矩阵。

现在我们可以像以前一样定义模型、拟合和评估它。

关键区别在于嵌入层可以用 GloVe 词嵌入权重初始化。我们选择了 100 维版本,因此嵌入层的 output_dim 必须设置为 100。最后,我们不想更新此模型中学习到的词权重,因此我们将模型的 trainable 属性设置为 False

完整的示例代码如下。

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

运行示例可能需要更长的时间,但随后演示了它同样能够解决这个简单的问题。

在实践中,我鼓励您尝试使用固定的预训练嵌入来学习词嵌入,并尝试在预训练嵌入之上进行学习。

看看哪种方法最适合您特定的问题。

进一步阅读

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

总结

在本教程中,您了解了如何在 Python 中使用 Keras 进行深度学习时使用词嵌入。

具体来说,你学到了:

  • 关于词嵌入以及 Keras 通过嵌入层支持词嵌入。
  • 如何在拟合神经网络时学习词嵌入。
  • 如何在神经网络中使用预训练的词嵌入。

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

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

Deep Learning for Natural Language Processing

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

...只需几行python代码

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

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

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

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

查看内容

对《如何在 Keras 深度学习中使用词嵌入层》的 657 条回复

  1. Mohammad 2017年10月4日上午7:58 #

    谢谢你,Jason。
    我很期待阅读更多自然语言处理文章。

  2. shiv 2017年10月5日上午10:07 #

    我将数据分成 80-20 的测试-训练集,但我仍然得到 100% 的准确率。有什么想法吗?在第 1 个 epoch 时约为 99%,其余的都是 100%。

  3. Sandy 2017年10月6日下午2:44 #

    谢谢你,杰森。我总觉得读你的文章更容易理解。
    我有一个关于训练后每个单词向量的问题。例如,句子“Well done!”中的单词“done”与句子“Could have done better!”中的该单词会用不同的向量表示吗?我的意思是,每个单词的表示会根据每个句子的上下文而定吗?

    • Jason Brownlee 2017年10月7日上午5:48 #

      不,字典中的每个词的表示都不同,但在不同上下文中的同一个词将具有相同的表示。

      词语的表示是根据它在不同上下文中的使用来定义的。

      这有帮助吗?

      • Sandy 2017年10月7日下午5:37 #

        是的,谢谢你。但我还有一个问题。我们将分别训练每个上下文,然后训练第一个上下文,在这种情况下是“Well done!”,我们将得到“done”这个词的向量表示。训练第二个上下文“Could have done better”之后,我们将得到“done”这个词的另一个向量表示。那么,我们将选择哪个向量作为“done”这个词的表示呢?
        我可能误解了训练过程。谢谢你为我澄清。

        • Jason Brownlee 2017年10月8日上午8:32 #

          不。所有使用一个词的示例都用于该词的表示训练。在训练期间和之后,每个词只有一个表示。

          • Sandy 2017年10月8日下午2:46 #

            我明白了。谢谢你,杰森。

  4. Chiedu 2017年10月7日下午5:36 #

    嗨,Jason,
    关于如何“过滤训练数据中独一无二的词的嵌入”,教程中有提及,有什么想法吗?

    • Jason Brownlee 2017年10月8日上午8:32 #

      词到向量的映射字典已内置于 Gensim 中,您可以直接访问它以检索您想要的词的表示:model.wv.vocab

      • mahna 2018年4月28日凌晨2:31 #

        嗨 Jason,
        我非常感谢您抽出时间撰写本教程并回复。
        我的问题是关于您写的“model.wv.vocab”。它是一个地址站点吗?
        实际上它不起作用。

  5. Abbey 2017年10月8日上午2:19 #

    嗨,Jason

    你好。

    我只是需要您的建议和示例。我有两个不同的数据集,一个是结构化的,另一个是非结构化的。目标是使用结构化数据为非结构化数据构建表示,因此对两个输入数据都应用词嵌入,但我如何才能找到这两个嵌入的平均值并将其展平为一个,然后再将该层输入到 CNN 和 LSTM 中。

    期待您的回复。
    此致
    Abbey

    • Jason Brownlee 2017年10月8日上午8:40 #

      抱歉,您的问题是什么?

      如果你的问题是这是否是一个好方法,我的建议是尝试一下,看看结果。

      • Abiodun Modupe 2017年10月9日下午7:46 #

        嗨,Jason
        如何找到两个输入的词嵌入的平均值?
        此致
        Abbey

        • Jason Brownlee 2017年10月10日上午7:43 #

          也许你可以检索每个单词的向量并取它们的平均值?

          也许你可以使用 Gensim API 来实现这个结果?

      • Rafael Sá 2019年6月17日凌晨2:47 #

        嗨,Jason,

        我有一组文档(1200 篇电影剧本文本),我想使用预训练的嵌入。但我想更新词汇表并重新训练,添加我的语料库中的词。这可能吗?

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

          当然可以。

          加载预训练向量。为词汇表中的新词添加新的随机向量,然后将它们一起训练。

  6. Vinu 2017年10月9日下午5:54 #

    嗨 Jason…您能也为我们提供使用预训练 GloVe 嵌入的 R 代码吗?

  7. Hao 2017年10月12日下午5:49 #

    嗨 Jason,非常感谢你回复了所有评论!我计划在文本分类上尝试 CNN 和 RNN(可能是 LSTM 和 GRU)。我的大部分文档都不到 100 字,但大约有 5% 的文档长度超过 500 字。您建议在使用 RNN 时如何设置最大长度?如果我将其设置为 1000,会降低学习结果吗?我应该只使用 100 吗?在 CNN 的情况下会有所不同吗?
    谢谢!

  8. Michael 2017年10月13日上午10:22 #

    我想感谢您这篇文章。我挣扎了一个星期才理解 Keras 的这种精确使用方法,而这是我找到的唯一一篇真正解释了过程中每个步骤在做什么的文章——并且提供了自我记录了数据在模型构建和训练过程中如何变化的代码。这使得它更容易适应我的特定需求。

  9. Azim 2017年10月17日下午5:47 #

    在上面的 Keras 示例中,我们如何根据给定单词预测上下文单词列表?比方说我有一个单词叫“sudoku”,想预测周围的单词。我们如何使用 keras 的 word2vec 来实现这一点?

  10. Willie 2017年10月21日下午5:55 #

    嗨,Jason,

    感谢您的有用博客,我学到了很多。

    我想知道,如果我已经有了预训练的词嵌入,是否可以将 keras 嵌入层设置为可训练?如果可行,当我只使用少量数据预训练词嵌入模型时,我会得到更好的结果吗?非常感谢!

    • Jason Brownlee 2017年10月22日上午5:16 #

      你可以。很难知道它是否会带来更好的结果。试试看。

  11. cam 2017年10月28日上午5:34 #

    嗨,Jason,

    是否可以对标签执行概率计算?我正在考虑一个案例,它不仅仅是 +/-,而是给定的数据条目可能既是也可能不是,但更有可能是一个而不是另一个。

    • Jason Brownlee 2017年10月29日上午5:48 #

      是的,带有 sigmoid 或 softmax 输出的神经网络可以预测每个类别的概率得分。

      • David Stancu 2017年11月3日上午6:10 #

        我正在做类似的事情,只不过是用我自己的特征向量——但就标签而言——我使用 categorical_crossentropy 和 softmax 输出进行三元分类。我得到的是每个标签的概率答案。

  12. Ravil 2017年11月3日上午5:43 #

    嘿,杰森!

    感谢您对该帖子的精彩而详细的解释。它对我帮助很大。

    然而,我仍然不明白模型如何预测一个句子是积极的还是消极的。
    我明白文档中的每个词都被转换为词嵌入,那么我们的模型如何评估整个句子是积极的还是消极的呢?它会取所有词向量的和吗?或者它们的平均值?我一直无法弄清楚这部分。

    • Jason Brownlee 2017年11月3日下午2:13 #

      很好的问题!

      模型解释序列中的所有词,并学习将特定的模式(编码词的)与积极或消极情绪关联起来

      • Ken 2018年4月2日上午8:37 #

        嗨,Jason,

        非常感谢您精彩的帖子。我与 Ravil 有相同的问题。您能更详细地解释一下“学习关联特定模式”吗?

        • Jason Brownlee 2018年4月2日下午2:49 #

          好问题,Ken,也许这篇文章能更清楚地说明机器学习算法是如何工作的(一种函数映射)。
          https://machinelearning.org.cn/how-machine-learning-algorithms-work/

          这有帮助吗?

          • Ken 2018年4月2日下午10:40 #

            谢谢你的回复。但我试图问的是,keras 是如何通过每个词的向量来生成文档级表示的?我似乎在代码中找不到这是如何实现的。

            谢谢。

          • Jason Brownlee 2018年4月3日上午6:34 #

            像 LSTM 或 CNN 这样的模型会将其整合在一起。

            对于 LSTM,你可以在这里了解更多
            https://machinelearning.org.cn/start-here/#lstm

            这有帮助吗?

          • Alexi 2018年9月27日凌晨1:48 #

            嗨,Jason,

            首先,感谢您所有非常有用的帖子。

            如果我理解您的帖子以及对 Ken 和 Ravil 的回复,您构建的神经网络实际上将对应于文档中所有单词的嵌入向量序列,通过 Flatten 层将其降维为一维向量,并且您只是训练这种扁平化以及嵌入,以在您的训练集上获得最佳分类,对吗?

            提前感谢您的回答。

          • Jason Brownlee 2018年9月27日上午6:04 #

            差不多吧。

            单词 => 整数 => 嵌入

            嵌入层为每个词提供一个向量,网络将使用该向量作为词的表示。

            我们有一个词向量序列,所以我们把这个序列展平为一个长向量,供稠密模型读取。或者,我们可以将稠密层封装在一个 timedistributed 层中。

          • Alexi 2018年9月27日下午5:49 #

            啊!所以扁平化时没有做什么花哨的事情,或多或少只是连接了固定数量的嵌入向量,这些向量是嵌入层的输出,这就是为什么每个文档的单词数量必须固定为该层的一个设置。如果这是正确的,我想我终于明白了这一切是如何工作的。

            很抱歉再次打扰您,但是如果一个文档比最长的文档短得多(其词数被设置为嵌入层每个文档的词数),那么网络如何工作?它只是将那些未出现的词的嵌入向量填充为 0 吗?我一直在寻找将文本的所有词嵌入转换为某种文档嵌入的方法,这看起来太简单了,似乎不太可能起作用,或者它可能起作用,但只适用于短文档(以及其他选项,例如对词向量求平均或取逐元素的最大值或最小值)。

            我正在尝试对西班牙语新闻进行情感分析,我的新闻中有大约 1000 甚至更多个词,并且想使用每个 300 维的预训练词嵌入。这对于网络来说,每个文档的大小会不会太大了,无法正常训练,或者训练速度不够快?我想你没有精确的答案,但我想知道你是否用长文档尝试过上述方法,或者知道有人尝试过。

            再次感谢您,很抱歉问了这么长的问题。

          • Jason Brownlee 2018年9月28日上午6:07 #

            是的。

            我们可以对小文档使用填充,并使用 Masking 输入层来忽略填充值。更多信息在此。
            https://machinelearning.org.cn/handle-missing-timesteps-sequence-prediction-problems-python/

            尝试不同大小的嵌入,并根据结果指导配置。

          • Alexi 2018年10月1日下午5:26 #

            好的,非常感谢!我会试一试的。

  13. chengcheng 2017年11月9日凌晨2:56 #

    中文词语如何进行向量序列化

    • Jason Brownlee 2017年11月9日上午10:03 #

      抱歉?

    • lstmbot 2017年12月16日下午10:30 #

      我机器人尝试与评论互动,生于 lstm

  14. Hilmi Jauffer 2017年11月16日下午4:30 #

    嗨,Jason,
    我已成功使用词嵌入和 Keras 训练了一个模型。准确率达到 100%。

    我保存了训练好的模型和词语标记以进行预测。
    MODEL.save(‘model.h5’, True)

    TOKENIZER = Tokenizer(num_words=MAX_NB_WORDS)
    TOKENIZER.fit_on_texts(TEXT_SAMPLES)
    pickle.dump(TOKENIZER, open(‘tokens’, ‘wb’))

    进行预测时
    – 加载已保存的模型。
    – 通过加载已保存的词语标记设置分词器。
    – 然后预测新数据的类别。

    我不确定预测逻辑是否正确,因为我没有看到预期的预测类别。

    源代码在 Github 上:https://github.com/hilmij/keras-test/blob/master/predict.py

    如果您能查看并告诉我我遗漏了什么,将不胜感激。

    此致,
    希尔米。

    • Jason Brownlee 2017年11月17日上午9:20 #

      你的流程听起来是正确的。抱歉,我无法审阅你的代码。

      问题到底是什么?

      • Tony 2018年7月11日上午8:00 #

        谢谢你,杰森!你的例子非常有帮助。我希望能得到你的关注,我的问题是。在训练时,你通过以下方式准备分词器:

        t = text.Tokenizer();
        t.fit_on_texts(docs)

        这会创建一个词语到数字的字典。如果在预测时有一个包含许多新词的新文档,我们该怎么办?所有这些词都会变成未知标记吗?如果是这样,有什么解决方案吗,比如我们能将分词器拟合到英语词汇表中的所有词语上吗?

        • Jason Brownlee 2018年7月11日下午2:52 #

          在训练时,您必须知道您想要支持的词汇,即使您必须猜测。

          为了支持新词汇,您将需要一个新模型。

  15. Fabrício Melo 2017年11月17日上午7:35 #

    你好,Jason!

    在使用预训练GloVe嵌入的示例中,您是否使用词嵌入向量作为嵌入层的权重?

  16. Alex 2017年11月21日下午11:15 #

    关于NLP和Keras的博客系列非常棒——感谢您的撰写。

    给其他人快速说明一下

    当我尝试使用以下行加载glove文件时
    f = open(‘../glove_data/glove.6B/glove.6B.100d.txt’)

    我收到错误
    UnicodeDecodeError: ‘charmap’ 编码器无法解码位置2776处的字节0x9d:字符映射到

    为了修复,我添加了
    f = open(‘../glove_data/glove.6B/glove.6B.100d.txt’,encoding=”utf8″)

    此问题可能是由于使用了Windows造成的。

    • Jason Brownlee 2017年11月22日上午11:12 #

      谢谢Alex的提示。

      • Liliana 2017年11月26日中午12:00 #

        嗨,Jason,

        精彩的教程!

        我有一个问题。为什么我们必须对标签进行独热向量化?另外,如果我有一个填充序列,例如 [2,4,0],那么独热编码会是什么?我正在努力更好地理解独热向量化。

        感谢您的回复!

  17. Wassim 2017年11月28日上午1:06 #

    嗨,Jason,
    感谢您的精彩教程。您知道是否有办法构建一个网络,同时使用文本嵌入数据和分类数据进行分类?
    谢谢你

  18. ashish 2017年12月2日下午8:29 #

    如何在keras中使用CNN进行句子分类?请帮忙

  19. Stuart 2017年12月7日上午12:11 #

    解释得很棒,非常感谢。我惊讶于自上次查看以来,这变得如此容易。

  20. Stuart 2017年12月11日下午3:30 #

    嗨,Jason……您的文档中的14个词汇是“well done good work great effort nice excellent weak poor not could have better”。对于14个词汇量,它独热编码为[13 8 7 6 10 13 3 6 10 4 9 2 10 12]。为什么“great”、“weak”和“have”都出现了3次10?

    • Jason Brownlee 2017年12月11日下午4:54 #

      抱歉,Stuart,我不明白。您能重新提问吗?

  21. Stuart 2017年12月11日下午9:34 #

    嗨,Jason,我上面示例中提供的编码来自kerasR,词汇量为14。所以,让我用您上面第3部分的独热示例,词汇量为50,来问相同的问题,即编码的唯一性。
    这里,针对不同的新内核(使用Spyder3/Python 3.4)产生了不同的编码
    [[31, 33], [27, 33], [48, 41], [34, 33], [32], [5], [14, 41], [43, 27], [14, 33], [22, 26, 33, 26]]
    [[6, 21], [48, 44], [7, 26], [46, 44], [45], [45], [10, 26], [45, 48], [10, 44], [47, 3, 21, 27]]
    [[7, 8], [16, 42], [24, 13], [45, 42], [23], [17], [34, 13], [13, 16], [34, 42], [17, 31, 8, 19]]

    请注意,在第一行,“33”编码了“done”、“work”、“work”、“work”和“done”这些词。在第二行,“45”编码了“excellent”、“weak”和“not”这些词。在第三行,“13”编码了“effort”、“effort”和“not”。

    所以我想知道为什么编码不是唯一的?其次,词汇量是否必须比实际词汇量大得多?

    谢谢

  22. Nadav 2017年12月25日上午8:28 #

    Jason,很棒的文章。
    如何从嵌入反向转换为独热编码?例如,如果您有一个seq2seq模型,并将输入作为词嵌入,在您的解码器中,您需要将嵌入反向转换为表示字典的独热编码。如果您通过矩阵乘法来实现,那可能是一个相当大的矩阵(例如,嵌入大小300,词汇量40万)。

    • Jason Brownlee 2017年12月26日上午5:12 #

      输出层可以直接预测整数,您可以将其映射到词汇表中的单词。输出层将不会有嵌入层。

  23. Hitkul 2018年1月9日下午9:05 #

    你好,
    非常有用的文章。
    我使用gensim和预训练的Google新闻向量创建了一个句子的word2vec矩阵。我可以直接将此矩阵展平为向量并将其用作神经网络的输入吗?
    例如:
    每个句子长度为140,我使用的是一个100维的预训练模型,因此:- 我有一个140*100的矩阵表示句子,我可以直接将其展平为一个14000长度的向量并将其馈送到我的输入层吗?

  24. Paul 2018年1月12日下午6:40 #

    很棒的文章,您能解释一下两个神经网络中参数#400和#1500是如何得来的吗?谢谢

    • Paul Lo 2018年1月12日下午9:55 #

      哦!它仅仅是词汇量 * 嵌入空间的维度数吗?
      1. 50 * 8 = 400
      2. 15* 100 = 1500

    • Jason Brownlee 2018年1月13日上午5:31 #

      你具体指的是什么?

  25. Andy Brown 2018年1月14日下午2:02 #

    很棒的帖子!我正在使用自己的语料库。我如何将嵌入层的权重向量保存到像glove数据集一样的文本文件中?

    我的想法是,这样我就可以更容易地将向量表示应用于新的数据集和/或机器学习平台(mxnet等),并使输出具有可读性(因为单词与向量相关联)。

  26. jae 2018年1月17日上午8:10 #

    清晰简洁,阅读愉快,一如既往地感谢您的工作!

  27. Murali Manohar 2018年1月17日下午4:58 #

    你好 Jason,
    我有一个数据集,通过5折交叉验证使用SVM获得了0.87的fscore。最大上下文窗口为20,并进行了独热编码。

    现在,我已经完成了所有提到的操作,并且在RNN模型中获得了13-15%的准确率,每个模型都有一个LSTM单元,带有3、20、150、300个隐藏单元。我预训练的嵌入维度是300。

    损失正在减少,甚至达到了负值,但准确率没有变化。

    我用您为文本分类提到的CNN、基本ANN模型也尝试了同样的方法。

    您能否提供一些解决方案。提前致谢。

  28. Carsten 2018年1月17日下午8:35 #

    当我复制第一个框中的代码时,出现错误

    AttributeError: ‘int’ object has no attribute ‘ndim’

    在这一行

    model.fit(padded_docs, labels, epochs=50, verbose=0)

    问题出在哪里?

    • Jason Brownlee 2018年1月18日上午10:07 #

      复制“完整示例”中的代码。

      • Thiziri 2018年2月8日上午12:45 #

        嗨,Jason,
        我得到了同样的错误,在运行“竞争示例”时也是如此。
        原因可能是什么?

        • Gokul 2018年2月8日下午6:49 #

          尝试将标签转换为numpy数组。

        • soren 2018年2月9日上午6:31 #

          我得到了同样的!

          • Jason Brownlee 2018年2月9日上午9:22 #

            我已经修复并更新了示例。

    • ademyanchuk 2018年2月8日下午3:34 #

      Carsten,您需要labels是numpy.array而不是list。

  29. Willie 2018年1月17日下午9:18 #

    嗨,Jason,

    如果在训练集中有未知单词,在使用预训练向量模型(如glove或w2v)时,如何将相同的随机初始化向量分配给所有未知单词。谢谢!!!

    • Jason Brownlee 2018年1月18日上午10:08 #

      你为什么要那样做?

      • Willie 2018年1月18日下午1:05 #

        如果我的数据在特定领域,并且我仍然想利用通用词嵌入模型(例如,从维基训练的glove.6b.100d),那么它在领域数据中肯定会有一些OOV,所以,无论是在训练时间还是推理时间,都可能出现一些未知词。

        • Jason Brownlee 2018年1月19日上午6:27 #

          也许会。

          您可以忽略这些词。

          您可以创建一个新的嵌入,从现有嵌入中设置向量并学习新词。

  30. Vladimir 2018年1月21日下午1:46 #

    太棒了,Jason博士!
    感谢您精彩的演练。

    请就以下问题提供建议。
    在将每个单词编码为整数的步骤中,您说:“我们可以尝试其他更复杂的词袋模型编码,如计数或TF-IDF”。您能否详细说明如何实现它,因为tfidf将标记编码为浮点数。以及如何将其与Keras关联,并将其传递给嵌入层?我渴望尝试一下,希望它能产生更好的结果。

    另一个问题是关于输入文档。假设我已经通过nltk对文本进行了预处理,直到词形还原,因此,每个样本都是一个标记列表。在这种情况下,将其传递给Keras嵌入层的最佳方法是什么?

    • Jason Brownlee 2018年1月22日上午4:42 #

      我有很多关于词袋模型的帖子,请在此处了解更多信息
      https://machinelearning.org.cn/?s=bag+of+words&submit=Search

      您可以手动将您的令牌编码为整数,或使用Keras Tokenizer。

      • Vladimir 2018年1月22日下午11:54 #

        嗯,Keras Tokenizer 只能接受文本或序列。看来唯一的办法是使用 ' '.join(token_list) 将标记连接起来,然后传递给 Tokenizer。

        至于BOW文章,我已经通读了,它们非常有价值。谢谢!

        使用BOW与使用嵌入有很大的不同。BOW会为每个样本引入巨大的稀疏特征数组,而嵌入旨在将这些特征(标记)密集地表示为数百个项目。

        所以,另一篇文章中的BOW仅通过非常简单的NN架构(1层50或100个神经元)就获得了令人难以置信的好结果。而我却难以使用嵌入和卷积层获得好结果……
        根据您的经验,您能就此提供建议吗?嵌入是否真的可行,只是找到正确架构的问题?

        • Jason Brownlee 2018年1月23日上午8:01 #

          太棒了!而且您能完成这些教程,干得好。我喜欢看到这样的成果,很少有人真正“完成工作”。

          一般来说,嵌入在较大/困难的问题上更有意义——例如,大型词汇量,前端的复杂语言模型等。

          • Vladimir 2018年1月23日上午10:15 #

            明白了,谢谢。

  31. joseph 2018年1月31日下午9:20 #

    感谢Jason的另一个精彩教程。

    我有一些问题

    独热编码的定义不是二进制的,即0和1的向量吗?
    所以[[1,2]]会被编码为[[0,1,0],[0,0,1]]

    在keras word2vec/globe或简单的密集层(或其他东西)上,嵌入算法是如何完成的
    谢谢
    joseph

    • Jason Brownlee 2018年2月1日上午7:20 #

      抱歉,我不明白您的问题。您能重新表述一下吗?

  32. Anna 2018年2月4日下午9:40 #

    太棒了,Jason博士!
    感谢您精彩的演练。

    例如上面例子中的8,每个词向量的维度是随机设置的吗?

    谢谢你

    • Jason Brownlee 2018年2月5日上午7:45 #

      维度是固定且指定的。

      在第一个示例中是8,在第二个示例中是100。

      • Anna 2018年2月5日下午2:17 #

        感谢Jason博士的快速反馈!

        好的,我明白了预训练的词嵌入被设置为100维,因为原始文件“glove.6B.100d.txt”包含了每行ASCII固定的100个权重。

        然而,正如您在此处提到的第一个例子,“嵌入的词汇量为50,输入长度为4。我们将选择一个小的8维嵌入空间。”

        您为第一个例子选择了8维。这是否意味着它可以设置为8以外的任何数字?我尝试将维度更改为12。它没有出现任何错误,但准确率从100%下降到89%。

        _________________________________________________________________
        层(类型) 输出形状 参数 #
        =================================================================
        embedding_1 (Embedding) (None, 4, 12) 600
        _________________________________________________________________
        flatten_1 (Flatten) (None, 48) 0
        _________________________________________________________________
        dense_1 (Dense) (None, 1) 49
        =================================================================
        总参数:649
        可训练参数:649
        不可训练参数: 0

        准确率:89.999998

        那么,维度是如何设置的?维度会影响准确率性能吗?

        抱歉,我正在努力理解NLP基础概念。非常感谢Jason博士的帮助。

        谢谢你

        • Jason Brownlee 2018年2月5日下午2:54 #

          没问题,请提出更多问题。

          是的,您可以选择任何您喜欢的维度。越大表示表达能力越强,对于更大的词汇量来说是必需的。

          这有帮助吗,Anna?

          • Anna 2018年2月5日下午4:40 #

            确实如此,博士。现在我明白了维度是根据词汇量设置的。

            再次感谢Jason博士的启发!🙂

          • Jason Brownlee 2018年2月6日上午9:11 #

            你问了很好的问题。

  33. Miroslav 2018年2月5日上午7:09 #

    嗨,Jason,
    感谢精彩的教程。

    我有一个问题。我正在尝试使用Keras中的上下文窗口进行语义角色标注。如何使用嵌入层实现上下文窗口?

    谢谢你

  34. Gabriel 2018年2月6日上午4:08 #

    你好,很棒的网站!我从所有的教程中学到了很多。感谢您提供所有这些易于理解的信息。

    我该如何将其他数据用于CNN模型呢?目前,我只使用文本数据和词嵌入来构建我的模型。据我所知,模型的第一层必须是嵌入层,那么我如何将整数等其他输入数据与嵌入层一起使用呢?

    谢谢!

  35. Aditya 2018年2月6日上午4:59 #

    你好Jason,这个教程简单易懂。谢谢。

    然而,我有一个问题。在使用预训练的嵌入权重(如Glove或word2vec)时,如果我的数据集中存在一些单词,而这些单词在word2vec或Glove训练的数据集中不存在,模型如何表示这些单词?

    我的理解是,在您的第二节(使用预训练的Glove嵌入)中,您将加载的权重中的单词映射到您数据集中存在的单词,因此有上述问题。

    如果我的理解不对,请纠正我。

    • Jason Brownlee 2018年2月6日上午9:22 #

      您可以忽略它们,或者将它们设置为零向量,或者训练一个包含它们的新模型。

      • Serhiy 2019年2月7日下午10:52 #

        你好Jason。感谢这篇以及其他非常清晰和信息丰富的文章。
        想给Aditya的帖子补充一个问题

        “将加载的权重中的单词映射到数据集中存在的单词”

        它是如何映射的?它是否使用矩阵索引 == (padded_docs 或) 中的单词编号?

        我之所以问,是因为——如果我传递带有原始顺序的embedding_matrix,但在model.fit之前打乱padded_docs会怎样?

        • Jason Brownlee 2019年2月8日上午7:49 #

          单词必须分配唯一的整数,并且在所有数据和嵌入中保持一致。

  36. Han 2018年2月20日下午4:03 #

    嗨,Jason,

    我正在尝试使用Keras LSTM模型训练一些文本情感数据。我还使用sklearn中的GridSearchCV来寻找最佳参数。我不太确定哪里出了问题,但是sklearn的分类报告显示

    UndefinedMetricWarning: Precision and F-score are ill-defined and being set to 0.0 in labels with no predicted samples.

    以下是分类报告的样子

    精确率 召回率 f1分数 支持数

    负面 0.00 0.00 0.00 98
    正面 0.70 1.00 0.83 232

    平均/总计 0.49 0.70 0.58 330

    您知道问题出在哪里吗?

    • Jason Brownlee 2018年2月21日上午6:35 #

      也许您正在尝试将 keras 度量与 sklearn 结合使用?请注意您在指定 keras 模型与 sklearn 评估 (CV) 时使用的关键词。

  37. Alberto Nogales Moyano 2018年3月2日上午2:10 #

    嗨,Jason,
    你的博客真的很有趣。我有一个问题:使用word2vec和Keras中Tokenizer的texts_to_sequences有什么区别?我的意思是文本表示方式的区别。
    这两种选择中哪一个更好?
    非常感谢。
    此致。

    • Jason Brownlee 2018年3月2日上午5:33 #

      word2vec 将单词(整数)编码为向量。texts_to_sequences 将单词编码为整数。它是 word2vec 之前的一个步骤,或者是词袋模型之前的一个步骤。

  38. Souraj Adhikary 2018年3月2日下午5:39 #

    嗨,Jason,

    我有一个包含文本和相应标签的数据框。我使用了 gensim 模块并使用 word2vec 从文本中生成了一个模型。现在我想将该模型用作 Conv1D 层的输入。您能告诉我如何在 Keras Embedding 层中加载 word2vec 模型吗?我是否需要在加载之前以某种方式预处理模型?提前感谢。

    • Jason Brownlee 2018年3月3日上午8:07 #

      是的,将权重加载到嵌入层,然后定义网络的其余部分。

      上面的教程会很有帮助。

  39. Ankush Chandna 2018年3月13日上午1:57 #

    这真的很有帮助。你让我们在工作中变得更棒。谢谢!!

  40. R.L. 2018年3月20日下午4:13 #

    感谢这篇极有帮助的博客文章。我有一个关于解释模型的问题。有没有办法在模型训练后知道/可视化单词的重要性?我正在寻找一种方法来做到这一点。例如,有没有办法找出前10个会触发模型将文本分类为负面的单词,反之亦然?提前非常感谢您的帮助

  41. Mohit 2018年3月30日下午9:35 #

    嗨,Jason,

    您能告诉我这背后的逻辑吗?

    vocab_size = len(t.word_index) + 1

    我们为什么要在这里加1??

    • Jason Brownlee 2018年3月31日上午6:36 #

      这样词汇索引从1开始,而0保留用于填充/无数据。

  42. Ryan 2018年3月31日下午9:59 #

    嗨,Jason,

    如果我想用这个模型预测下一个词,我可以直接将输出层改为Dense(100, activation = ‘linear’)并将损失函数改为MSE吗?

    非常感谢,

  43. Coach 2018年4月17日下午10:23 #

    感谢这个教程!非常清晰有用!

  44. Maryam 2018年4月28日上午4:53 #

    嗨,Jason,
    您在keras教程和回复问题方面都是最棒的。我真的非常感谢。
    尽管我理解了您上面所写的内容和代码,但我无法理解您这句话的意思:[最好根据训练数据中唯一的词汇来筛选嵌入。]
    “筛选嵌入”是什么意思?
    感谢您的回复。

    • Jason Brownlee 2018年4月28日上午5:34 #

      这意味着,只在嵌入中包含您知道存在于您的数据集中的单词。

      • Maryam 2018年4月28日下午11:45 #

        嗨,Jason,
        感谢您的回复,但由于我不是母语为英语的人,我不确定我是否理解了。您的意思是移除所有在glove中存在但不在我的数据集中存在的单词吗?为了提高实现速度?
        我很抱歉再次提问,因为我没有清楚地理解。
        提前感谢Jason

  45. Aiza 2018年5月9日上午6:14 #

    你好,
    这篇帖子很棒。我是机器学习新手,所以我有一个可能很基础的问题,我不确定。据我所知,模型一次性接收嵌入矩阵、文本和标签。我尝试做的是将POS标签嵌入与每个预训练的词嵌入连接起来,但POS标签可能因上下文而异。这本质上意味着我不能修改嵌入矩阵并将其添加到网络嵌入层。我想逐句处理,找到其嵌入,并与POS标签嵌入连接,然后输入神经网络。有没有办法逐句进行训练?谢谢

    • Jason Brownlee 2018年5月9日上午6:32 #

      您可以使用嵌入并预先计算每个句子的向量表示。

      • Aiza 2018年5月9日上午7:06 #

        抱歉,我不太明白。您能详细说明一下吗?

        • Jason Brownlee 2018年5月9日下午2:54 #

          抱歉,我的意思是您可以单独准备一个word2vec模型。然后将每个句子通过它来构建向量列表。将向量连接起来,您就拥有了一个分布式的句子表示。

          • Aiza 2018年5月9日下午10:16 #

            非常感谢!还有一件事,除了权重之外,是否可以向嵌入层传递其他信息?例如,我当时想,如果我完全不改变嵌入矩阵,而是为整个训练数据创建一个单独的POS标签矩阵,也将其传递给嵌入层,该层将按顺序连接这两个矩阵,会怎样?

          • Jason Brownlee 2018年5月10日上午6:32 #

            您可以开发一个具有多个输入的模型,例如,请参阅此帖子中的示例
            https://machinelearning.org.cn/keras-functional-api-deep-learning/

  46. Aiza 2018年5月15日上午8:46 #

    谢谢。我看到了这篇帖子。您的模型有独立的输入,但在展平后合并。在我的例子中,我希望将嵌入传递给第一个卷积层,只有在它们连接后才传递。到目前为止我所做的是,我根据POS标签(embedding_pos)创建了另一个整数序列,作为另一个输入,以及另一个包含所有POS标签嵌入的嵌入矩阵。
    e=(Embedding(vocab_size, 50, input_length=23, weights=[embedding_matrix], trainable=False))
    e1=(Embedding(38, 38, input_length=23, weights=[embedding_matrix_pos], trainable=False))
    merged_input = concatenate([e,e1], axis=0)
    model_embed = Sequential()
    model_embed.add(merged_input)
    model_embed.fit(data,embedding_pos, final_labels, epochs=50, verbose=0)

    我知道这是错误的,但我不知道如何连接这两个序列,如果您能给我正确的方向,那将非常棒。错误是
    ‘Layer concatenate_6 was called with an input that isn’t a symbolic tensor. Received type: . Full input: [, ]. All inputs to the layer should be tensors.’

    • Jason Brownlee 2018年5月15日下午2:42 #

      也许您可以尝试并比较不同合并层模型在组合输入时的性能。

  47. Franco 2018年5月16日下午6:51 #

    嗨Jason,一如既往地写得真棒!

    不过你最后一句有点难懂。你写道

    “实际上,我鼓励你尝试使用预训练的固定嵌入来学习词嵌入,并尝试在预训练嵌入的基础上进行学习。”

    如果没有原始语料库,我会说,那是不可能的。

    在谷歌的案例中,大约1000亿词的原始语料库没有公开。解决方案?我相信您建议的是“NLP的迁移学习”。在这种情况下,我看到的唯一解决方案是手动添加词汇。

    例如,您需要“dolares”,它不在谷歌的Word2Vec中。您希望拥有与“money”相似的向量。在这种情况下,您添加“dolares” + 300个来自money的向量。我知道这很痛苦。但这是我看到的进行“NLP迁移学习”的唯一方法。

    如果您有更好的解决方案,我乐意听取您的意见。

    再见,一位忠实粉丝

    • Jason Brownlee 2018年5月17日上午6:30 #

      并非不可能,您可以使用在其他语料库上训练的嵌入,并忽略差异或在拟合模型时微调嵌入。

      您还可以将缺失的单词添加到嵌入中并学习这些单词。

      请记住,我们希望每个单词都有一个最能捕捉其用法的向量,一些不一致不会导致模型无用,这不是二进制有用/无用的情况。

      • Franco 2018年5月17日下午4:42 #

        非常感谢您的详细解答!

  48. Ashar 2018年5月31日上午6:11 #

    Tokenizer API 的链接是此同一个网页。请您更新它吗?

  49. Andreas Papandreou 2018年5月31日上午10:55 #

    嗨 Jason,很棒的帖子!
    我已经成功地使用词嵌入和Keras训练了我的模型。我保存了训练好的模型和词令牌。现在为了进行一些预测,我必须使用与训练时相同的分词器吗?

  50. zedom 2018年6月2日下午5:15 #

    嗨Jason,当我寻找如何使用预训练词嵌入时,
    我发现了您的文章以及这篇
    https://jovianlin.io/embeddings-in-keras/
    它们有很多相似之处。

  51. Jack 2018年6月13日下午10:58 #

    嘿 Jason,

    我正在尝试这样做,但有时Keras会给不同的单词相同的整数。使用scikit编码器将单词转换为整数会更好吗?

    • Jason Brownlee 2018年6月14日上午6:08 #

      如果您使用的是哈希编码器(Keras就是如此,但将其称为独热编码器),则可能会发生这种情况。

      也许可以尝试不同的单词到整数编码方案

  52. Meysam 2018年6月18日上午5:13 #

    嗨,Jason,
    我已经实现了上述教程,代码在GloVe下运行良好。我非常感谢Jason的教程。
    但当我下载预训练的word2vec嵌入模型GoogleNews-vectors-negative300.bin时,它给我报了这个错误

    文件“/home/mary/anaconda3/envs/virenv/lib/python3.5/site-packages/gensim/models/keyedvectors.py”,第171行,在__getitem__中
    返回vstack([self.get_vector(entity) for entity in entities])

    TypeError: 'int' object is not iterable.

    我写的代码与您加载glove的代码相同,只是稍有改动。

    ‘model = gensim.models.KeyedVectors.load_word2vec_format(‘./GoogleNews-vectors-negative300.bin’, binary=True)

    for line in model
    values = line.split()
    word = values[0]
    coefs = asarray(values[1:], dtype=’float32′)
    embeddings_index[word] = coefs
    model.close()
    print(‘Loaded %s word vectors.’ % len(embeddings_index))

    embedding_matrix = zeros((vocab_dic_size, 300))
    for word in vocab_dic.keys()
    embedding_vector = embeddings_index.get(word)
    if embedding_vector is not None
    embedding_matrix[vocab_dic[word]] = embedding_vector

    我看到您在这篇文章“https://machinelearning.org.cn/develop-word-embedding-model-predicting-movie-review-sentiment/”中写了一个关于自己创建word2vec的教程,
    但我还没有看到关于应用预训练word2vec(如GloVe)的教程。
    请指导我解决此错误以及如何应用GoogleNews-vectors-negative300.bin预训练的word2vec?
    我很抱歉写了很多,因为我想详细解释清楚。
    任何指导都将不胜感激。
    祝好
    Meysam

    • Jason Brownlee 2018年6月18日上午6:46 #

      也许可以尝试像上面教程中的文本版本?

      • Meysam 2018年6月19日上午12:28 #

        嗨 Jason
        非常感谢您的回复,但由于我英语不好,这句话的意思不清楚。“尝试文本版本”是什么意思??
        实际上,GloVe 包含 txt 文件,我正确地实现了它,但当我想要运行一个使用 GoogleNews-vectors-negative300.bin(这是一个预训练的 word2vec 嵌入)的程序时,它给我报错了,而且这个文件是二进制的,没有以 txt 为前缀的预训练 word2vec 嵌入文件。
        即使您很忙,您能帮我吗?
        祝好
        Meysam

  53. Kavit Gangar 2018年6月18日下午7:17 #

    我们如何在移动设备上使用预训练的词嵌入?

    • Jason Brownlee 2018年6月19日上午6:29 #

      除了磁盘/内存大小问题,我看不出有什么不行。

  54. NewToDeepNLP 2018年6月28日上午12:17 #

    很棒的帖子!如果标签不是二进制的,而是有4个类,例如
    labels = array([2,1,1,1,2,0,-1,0,-1,0])
    ?
    例如,代替“binary_crossentropy”,也许是“categorical_crossentropy”?
    以及Dense层应该如何改变?
    如果我使用:model.add(Dense(4, activation=’sigmoid’)),我将得到一个错误

    ValueError: Error when checking target: expected dense_1 to have shape (None, 4) but got array with shape (10, 1)

    感谢您的工作!

  55. James 2018年6月28日下午9:58 #

    嗨,Jason,

    首先,感谢这篇帖子。它非常适合快速启动。如果您不介意,我还有几个问题

    1) 我认为独热编码字符串向量并不理想。即使使用建议的词汇量(50),我仍然会遇到冲突,这即使在玩具示例中也违背了目的。甚至文档也说明不保证唯一性。Keras的Tokenizer(),您在预训练示例中使用的那个,是一个更可靠的选择,因为没有两个单词会共享相同的整数映射。为什么您建议独热编码,而Tokenizer()能更好地完成相同的工作?

    2) 获取 Tokenizer() 的 word_index 属性,返回完整的字典。我期望 vocab_size 等于 len(t.word_index),但您将该值递增了 1。这实际上是必需的,否则模型拟合会失败。但我无法理解其中的道理。为什么输入维度大小等于 vocab_size + 1?

    3) 我创建了一个模型,期望每个“文档”的BoW向量表示。自然地,向量更大更稀疏[ (10,14) ],这意味着要学习更多的参数,不是吗。然而,在您的文档中,您将这种编码或tf-idf称为“更复杂”。您为什么这样认为?使用这种编码,您不是会丢失对学习词嵌入很重要的词序吗?顺便说一句,这种编码也运行良好,但这可能归因于这个小实验的性质。

    先谢谢您了。

    • Jason Brownlee 2018年6月29日上午6:05 #

      Keras 的独热编码方法实际上只是一个哈希。在需要时,最好使用真正的独热编码。

      我实际上更喜欢使用 Tokenizer 类。

      这些单词是1偏移的,为0留出了“未知”单词的空间。

      tf-idf 在词袋模型中提供了一些关于单词频率而非简单存在/缺失的信息。

      希望这有帮助。

  56. abbas 2018年7月12日上午3:27 #

    我在哪里可以找到文件“../glove_data/glove.6B/glove.6B.100d.txt”?因为我遇到了以下错误。
    文件“”,第36行
    f = open(‘../glove_data/glove.6B/glove.6B.100d.txt’)
    ^
    SyntaxError: 标识符中包含无效字符

  57. Harry 2018年7月17日下午1:02 #

    干得漂亮!这对新手很有帮助。
    我想知道这是否对英语以外的其他语言有用?因为我是中国人,我想知道我是否可以将其应用于汉语和词汇。
    再次感谢您的付出!

  58. sree harsha 2018年7月18日上午6:02 #

    你好,

    您能解释一下词嵌入如何作为隐藏状态输入到LSTM吗?

    先谢谢了

    • Jason Brownlee 2018年7月18日上午6:39 #

      词嵌入没有隐藏状态。它们没有任何状态。

      • sree harsha 2018年7月18日下午6:57 #

        例如,我有一个单词及其50维的嵌入。如何将这些嵌入作为隐藏状态输入到LSTM层?

        • Jason Brownlee 2018年7月19日上午7:47 #

          你为什么想把它们作为隐藏状态而不是作为LSTM的输入呢?

  59. zbk 2018年7月20日上午8:39 #

    嗨,多么实用的一篇文章!
    我有一个问题,我正在用word2vec作为嵌入模型在keras中进行情感分析项目。我的问题是,当我想要预测一个新句子作为输入时,我遇到了这个错误

    ValueError: Error when checking input: expected conv1d_1_input to have shape (15, 512) but got array with shape (3, 512)

    请注意,我想输入一个简单的句子,例如:“I’m really sad”,长度为3,而我的输入形状长度为15。我不知道如何重塑它或如何解决这个错误。

    这是我的代码的相关部分

    model = Sequential()
    model.add(Conv1D(32, kernel_size=3, activation=’elu’, padding=’same’, input_shape=(15, 512)))
    model.add(Conv1D(32, kernel_size=3, activation=’elu’, padding=’same’))
    model.add(Conv1D(32, kernel_size=3, activation=’elu’, padding=’same’))
    model.add(Conv1D(32, kernel_size=3, activation=’elu’, padding=’same’))
    model.add(Dropout(0.25))

    model.add(Conv1D(32, kernel_size=2, activation=’elu’, padding=’same’))
    model.add(Conv1D(32, kernel_size=2, activation=’elu’, padding=’same’))
    model.add(Conv1D(32, kernel_size=2, activation=’elu’, padding=’same’))
    model.add(Conv1D(32, kernel_size=2, activation=’elu’, padding=’same’))
    model.add(Dropout(0.25))

    model.add(Dense(256, activation=’relu’))
    model.add(Dense(256, activation=’relu’))
    model.add(Dropout(0.5))
    model.add(Flatten())
    model.add(Dense(2, activation=’softmax’))

    您能帮我解决这个问题吗?

    • Jason Brownlee 2018年7月21日上午6:27 #

      您必须以与训练数据完全相同的方式准备新句子,包括长度和整数编码。

  60. zbk 2018年7月20日下午6:09 #

    至少您能否分享一些合适的资源来帮助我解决这个问题?
    希望您能像往常一样回答我的问题。谢谢

    • Jason Brownlee 2018年7月21日上午6:32 #

      我很乐意提供帮助并回答具体问题,但我没有能力为您编写代码,抱歉。

  61. Alalehrz 2018年7月28日上午5:13 #

    嗨,Jason,

    我有两个问题。首先,对于新实例,如果长度大于此模型输入,我们是否应该截断句子?
    此外,由于嵌入输入仅用于已见过的训练集单词,那么预测到单词的过程会发生什么?我假设它只返回一些与训练单词相似的单词,而不考虑所有词典单词。当然,我正在谈论的是带有Glove的语言模型。

    • Jason Brownlee 2018年7月28日上午6:40 #

      是的,截断。

      未见词被映射为无或0。

      训练数据集必须代表您正在解决的问题。

      • az 2018年7月31日上午3:30 #

        根据我对这个评论的理解,它是关于测试数据上的预测。假设词汇表中有50个词,这意味着句子将有唯一的整数,直到50。现在,由于测试数据必须使用相同的分词器实例进行分词,如果它有一些新词,它将有51、52等整数。在这种情况下,模型会自动使用0作为词嵌入,还是会抛出越界异常?谢谢

        • Jason Brownlee 2018年7月31日上午6:11 #

          您会将未见词编码为0。

          • Yuedong Wu 2020年8月30日下午4:25 #

            所有50个词汇词都应该从索引1到50开始,而0留给词汇表中未见过的词。我说的对吗?

          • Jason Brownlee 2020年8月31日 上午6:07 #

            正确。

  62. Jaskaran 2018年7月29日 晚上11:21 #

    这可以描述为迁移学习吗?

  63. eden 2018年7月31日 上午1:07 #

    你好,
    我训练并测试了自己的网络。在我的工作中,当我将句子整数化并创建相应的词嵌入矩阵时,它也包含了训练、验证和测试数据的嵌入。
    现在,如果我想重新加载我的模型来测试一些其他类似数据,我很困惑这些新数据中的词如何与嵌入矩阵相关联?
    你也应该有测试数据的嵌入,对吗?或者当你创建嵌入矩阵时,你会排除测试数据吗?谢谢

    • Jason Brownlee 2018年7月31日 上午6:09 #

      嵌入是从训练数据集中创建的。

      它应该足够丰富/具有代表性,以涵盖你未来期望的所有数据。

      新数据在进行预测时,在映射到嵌入之前,必须与训练数据具有相同的整数编码。

      这有帮助吗?

      • eden 2018年7月31日 上午8:04 #

        是的,我明白我应该使用相同的分词器对象来编码训练和测试数据,但我不确定嵌入层对于不属于嵌入矩阵的词或索引会如何表现。显然,测试数据会有类似的词,但肯定会有一些新词。你会说这种方法在为模型创建嵌入矩阵时也包含测试数据是正确的吗?如果你想使用一些预训练模型进行预测,我该如何处理这个问题?一个小例子会非常有帮助。非常感谢你的所有帮助和时间!

        • Jason Brownlee 2018年7月31日 下午2:55 #

          不会。编码会将未知词设置为0。

          这真的取决于你想要评估的目标。

  64. Jaskaran 2018年8月1日 下午5:04 #

    我想训练我的模型来预测给定5个词序列的目标词。我如何表示我的目标词?

  65. Bharath 2018年8月3日 下午12:48 #

    你好 Jason,

    这是关于第一个嵌入层的输出形状:(None,4,8)。
    我理解为4代表输入大小,即4个词,8是它使用这些词生成的特征数量,对吗?

  66. Sreenivasa 2018年8月10日 晚上7:33 #

    嗨,Jason,
    感谢分享您的知识。
    我的任务是将一组文档分类到不同的类别。(我有一个包含100个文档和10个类别的训练集)。
    想法是从每个文档的前几行中提取前M个词(例如20个),将词转换为词嵌入,并将其用作神经网络的特征向量。

    问题:由于我从文档中提取前M个词,它们的顺序可能不总是“正确”的,这意味着输入层在给定位置可能有不同的词(不像词袋模型)。这种方法不会影响神经网络的收敛吗?

    此致,
    Srini

    • Jason Brownlee 2018年8月11日 上午6:08 #

      关键是在将数据输入嵌入层之前,为每个词分配相同的整数值。

      您必须对所有文档使用相同的文本分词器。

  67. Fatemeh 2018年8月17日 上午7:15 #

    嗨,Jason,
    感谢您精彩的解释。我在我的seqtoseq项目中使用了预训练的Google嵌入矩阵,通过编码器-解码器。但在我的测试中,我遇到了一个问题。我不知道如何反转我的嵌入矩阵。您有示例项目吗?我的解决方案是:当我的解码器预测一个向量时,我应该在我的预训练嵌入矩阵中搜索它,然后找到它的索引,然后理解它相关的词。我说的对吗?

    • Jason Brownlee 2018年8月17日 上午7:40 #

      你为什么要反转它?

      • Vivien 2018年9月29日 下午1:45 #

        嗨 Jason

        感谢这篇出色的教程。使用您的方法,我已将文本转换为词索引并应用了词嵌入。

        和Fatemeh一样,我想知道是否有可能反转这个过程,将嵌入向量转换回文本?这对于文本摘要等应用可能很有用。

        谢谢你。

        • Jason Brownlee 2018年9月30日 上午6:00 #

          是的,每个向量都有一个由嵌入层已知的整数值,每个整数通过分词器映射到一个词。

          空间中的随机向量没有,您必须使用欧几里得距离找到嵌入层中最接近的向量。

  68. fatma 2018年8月18日 上午10:09 #

    尊敬的Jason博士,

    准确率:我的笔记本电脑上是89.999998,结果和别的电脑不同?

  69. Ivan 2018年9月1日 下午2:00 #

    你好,

    非常感谢这篇教程!

    我一直在尝试训练一个包含嵌入层、LSTM和softmax作为输出层的网络。然而,损失和准确率似乎在某个点卡住了。

    您有什么建议吗?

    提前感谢。

  70. Aramis 2018年9月28日 上午10:28 #

    非常感谢您,
    它在学习如何在神经网络中使用预训练嵌入方面对我帮助很大

  71. Rafael sa 2018年10月24日 上午5:28 #

    嗨,Jason,感谢您提供的精彩资料。

    我有一个疑问,想对1200个文档列表进行嵌入,然后将其作为分类模型的输入,根据电影剧本文本预测电影票房……
    我的问题是……如果我想用真实数据集的词汇训练嵌入,那么我如何才能对未训练的其余数据集进行分类呢?我可以使用训练中学到的嵌入作为分类模型的输入吗?

    • Jason Brownlee 2018年10月24日 上午6:33 #

      好问题。

      您必须确保训练数据集能代表更广泛的问题。除非您更新模型,否则在训练期间未见过的任何单词都将由分词器标记为零(未知)。

      • Rafael SA 2018年11月1日 晚上9:06 #

        谢谢你,Jason。我一拿到结果就会在这里分享。
        我也想感谢您的出色平台,它对我非常有帮助。

  72. Dimitris 2018年10月26日 上午2:06 #

    又一篇好文章!似乎每个批次中的所有嵌入都已更新,我认为这不应该发生。您知道如何只更新每次通过的嵌入吗?这是出于计算原因或其他与问题定义相关的原因。

    • Jason Brownlee 2018年10月26日 上午5:38 #

      我不太明白你的意思,能详细说明一下吗?

  73. Mahdi 2018年11月18日 上午1:57 #

    你好Jason,我想感谢你这篇文章,它真的很有趣且易懂。

    我重复使用了脚本,但没有使用“docs”和“labels”列表,而是使用了IMDB电影评论数据集。问题是准确率无法超过50%,并且所有epochs中的损失都稳定在0.6932。

    你对此有什么看法?

  74. Mehran 2018年11月18日 下午12:55 #

    谢谢你的文章。你能不能也提供一个只用一个嵌入层训练模型的例子?我正尝试用 Keras 做同样的事情,但问题是 fit 方法需要标签,而我没有。我的意思是,我只有一堆文本文件,我正在尝试为它们找到映射。

    • Jason Brownlee 2018年11月19日 上午6:42 #

      模型通常只有一个嵌入层。你具体是什么意思?

  75. Vishal 2018年11月22日 下午4:07 #

    你好,

    感谢您出色的解释!

    我对未知词有一些疑问。

    一些预训练的词嵌入,比如GoogleNews嵌入,也包含一个名为“UNKNOWN”的标记的嵌入向量。

    1. 我可以使用这个向量来表示训练集中不存在的词,而不是全零向量吗?如果可以,我应该如何将这个向量加载到Keras嵌入层中?它应该加载到嵌入矩阵的第0个索引位置吗?

    2. 另外,我可以使用Tokenizer API来帮助我将所有未知词(不在训练集中的词)转换为“UNKNOWN”吗?

    谢谢你。

    • Jason Brownlee 2018年11月23日 上午7:43 #

      是的,找到未知词的整数值,并用它来赋值给词汇表中没有的所有词。

  76. Saurabh 2018年11月27日 下午4:46 #

    你好,
    如果词嵌入不包含我们输入到模型中的词,如何解决这个问题?
    1) 是否可以在嵌入矩阵中加载额外的词(除了词汇表中的词)?
    或者您有什么其他优雅的方法可以建议吗?

  77. mohammad 2018年11月28日 晚上11:15 #

    嗨。非常感谢你的帖子。我是Python和深度学习的新手!

    我有240,000条推文训练集(50%男性和50%女性类别)。以及120,000条推文测试集(50%男性和50%女性)。我想在Python中使用LSTM,但在“fit”方法中出现以下错误:

    ValueError: 检查输入时出错:期望lstm_16_input具有3个维度,但得到形状为(120000, 400)的数组

    你能帮我吗?

    • Jason Brownlee 2018年11月29日 上午7:40 #

      这看起来是您的数据与模型不匹配,您可以更改数据或更改模型。

  78. Mohamed 2018年12月5日 上午3:46 #

    嗨 Jason,感谢您的这篇文章。

    我收到了这个错误

    TypeError: ‘OneHotEncoder’ 对象不可调用

    如何解决?

    谢谢

  79. Rushi 2018年12月6日 下午5:40 #

    嗨,我有2个带有嵌入层的模型,我如何合并这些模型?

    谢谢

  80. Utkarsh Rai 2018年12月7日 上午12:29 #

    嗨Jason,很棒的教程,我对这一切都很陌生。我有一个疑问,您在嵌入层使用glove,但在拟合时直接使用padded_docs。padded_docs中的向量与glove没有关联。我确信我遗漏了一些东西,请指教。

    • Jason Brownlee 2018年12月7日 上午5:23 #

      填充只是添加“0”以确保序列长度相同。它不影响编码。

  81. Eduardo Andrade 2018年12月7日 下午3:48 #

    你好,Jason。考虑到“3. 学习嵌入的例子”,我在嵌入层之后添加了“model.add(LSTM(32, return_sequences=True))”,我想了解会发生什么。这个LSTM层返回的参数数量是“5248”,我不知道如何计算它。谢谢。

    • Jason Brownlee 2018年12月8日 上午6:58 #

      LSTM中的每个单元都将整个嵌入作为输入,因此必须为嵌入中的每个维度分配一个权重。

  82. Vic` 2018年12月18日 上午10:12 #

    嗨,Jason,

    您有任何示例展示如何将双向LSTM应用于文本(即使用词嵌入)吗?

  83. Matt 2018年12月24日 晚上9:57 #

    我很有兴趣使用预测函数来预测新文档。例如,“出局!”我的理解是,如果想要预测的文档中有一个或多个词没有参与训练,那么模型就无法预测。解决方案是不是简单地在足够的文档上进行训练,以确保词汇量足够广泛,从而以这种方式进行新预测?

    • Jason Brownlee 2018年12月25日 上午7:21 #

      是的,或者在预测时将新词标记为“未知”。

  84. Ajay 2018年12月26日 晚上11:53 #

    你好Jason,嵌入层的输出是一个4x8矩阵,有什么原因吗?

  85. Zeyu 2018年12月30日 上午7:09 #

    嗨,Jason。非常感谢这篇优秀的教程。我对Keras嵌入层有一个小问题。

    vocab_size = len(t.word_index) + 1

    t.word_index 从1开始,到15结束。因此,词汇表中总共有15个词。那么我们为什么需要在这里加1呢?

    非常感谢您的帮助!

    • Jason Brownlee 2018年12月31日 上午6:02 #

      这些词是1-偏移的,索引0保留给“未知”词。

      • Niccola 2021年3月3日 上午7:49 #

        您介意详细说明这个答案吗?我仍然不太清楚

        • Jason Brownlee 2021年3月3日 上午8:09 #

          当然,哪一部分不清楚?

          • Niccola 2021年3月3日 下午1:49 #

            在这种情况下,1-偏移究竟是什么意思?

            如果“索引0保留给未知词”,那是否意味着你可以忽略它们?

            如果我改用这个

            vocab_size = len(t.word_counts.keys()) + 1

            我还需要加1吗?

          • Jason Brownlee 2021年3月3日 下午1:59 #

            词汇表中没有的词被赋值为0,该值映射到第一个向量的索引,代表未知词。

            词汇表中的第一个词映射到索引1处的向量。第二个词映射到索引2处的向量,依此类推,直到处理完所有向量。

            这有帮助吗?

          • Niccola 2021年3月3日 下午2:09 #

            谢谢您的回复,但我还是不太明白。我的理解是,当我使用t.word_counts而不是t.word_index(不确定这是否有所不同)时,我会得到类似这样的东西:

            OrderedDict([('word1', 35), ('word2'), 232))

            那么,如果我使用len(t.word_counts),在这种情况下它会给我2。我为什么要加1呢?

            也就是说,如果我使用t.word_counts,当我打印它时,我没有看到任何未知词。

          • Jason Brownlee 2021年3月4日 上午5:44 #

            我们没有在计数上加1。我们没有触碰词的有序字典。

            我们只是在词汇表中添加了一个名为“未知”的词,它映射到嵌入中的第一个向量。

          • Niccola 2021年3月3日 下午5:29 #

            Tensorflow文档也说要加1,但我真的不确定为什么

            https://tensorflowcn.cn/api_docs/python/tf/keras/layers/Embedding

          • Jason Brownlee 2021年3月4日 上午5:46 #

            为了给“未知”词——词汇表中没有的词——留出空间。

            加1意味着在词汇表中增加一个词,第一个词映射到索引0——第零个词。

          • Niccola 2021年3月4日 上午8:05 #

            您知道有没有解释为什么我们必须加1的资源吗?我明白这是因为未知词,所以我们将给定词汇量增加1。但我就是不明白为什么。

          • Jason Brownlee 2021年3月4日 上午8:24 #

            我们不必这样做,我们可以简单地忽略词汇表中没有的词。

  86. Anna 2019年1月3日 下午4:13 #

    嗨,Jason,

    如果我有三列(字符串类型)多元数据,其中一列是分类数据,另外两列不是。我用LabelEncoding()对其进行整数编码,然后使用MinMax、StandardScaler等特征缩放方法对编码后的数据进行缩放,再将其输入异常检测模型,这可以吗?尽管ROC显示出令人印象深刻的结果。但是这样预处理文本数据是否有效?

    谢谢你。

    • Jason Brownlee 2019年1月4日 上午6:26 #

      也许可以尝试一下并比较性能。

      • Anna 2019年1月4日 下午2:49 #

        我试过了,它显示了接近100%的ROC。我的意思是,这样预处理文本数据是否准确?因为当我查看您关于预处理文本数据的帖子时,在将其编码为整数后,文本数据没有进行特征缩放(MinMax、StandardScaler等)。我担心我的数据预处理方式不准确。

        • Jason Brownlee 2019年1月5日 上午6:47 #

          通常文本被编码为整数,然后进行独热编码或映射到词嵌入。不需要其他数据准备(例如缩放)。

  87. Kafeel Basha 2019年1月6日 晚上7:46 #

    你好

    我尝试使用Keras在R和Python中对文本数据进行多类别分类。

    在Python中,我能够使用inverse_transform()方法从编码后的类别值获取预测标签。但是当我在R中使用CatEncoders库进行同样的操作时,会得到一些NA标签。有什么原因吗?

    • Jason Brownlee 2019年1月7日 上午6:28 #

      无需转换预测,模型可以直接进行类别或概率预测。

  88. Li Xiaohong 2019年1月7日 上午12:49 #

    嗨,Jason,

    感谢您的分享!我有一个关于词嵌入的问题。如果我错了,请纠正我:这里创建的词嵌入只包含训练/测试集中的词。我认为包含GloVE文件中所有词汇的词嵌入会更好?例如,如果在生产中,我们遇到一个训练/测试集中没有的新词,但它属于GloVE词汇表,在这种情况下,我们可以捕获生产词的含义,尽管我们在训练/测试集中没有看到它。我认为这会使情感分类问题在训练集较小的情况下受益?

    谢谢!
    此致
    小红

    • Jason Brownlee 2019年1月7日 上午6:36 #

      通常,您会仔细选择词汇表。如果您希望保留一个比项目所需的词汇表更大的词汇表,“以防万一”,那就去做吧。

  89. Rahul Sangole 2019年1月17日 上午5:12 #

    Jason,

    嵌入是否有非文本应用?例如,我有一大组分类变量,每个变量都有大量级别,这些变量输入到分类模型中。在这种情况下我可以使用嵌入吗?

    Rahul

  90. Dipawesh Pawar 2019年1月18日 上午2:11 #

    你好 Jason……

    非常感谢您这篇精彩的帖子。它极大地丰富了我的知识。

    我对keras提供的text_to_sequence和one_hot方法有一个疑问。它们都使用您的示例给出了相同的编码文档。如果它们给出相同的输出,那么我们何时应该使用text_to_sequence,何时应该使用one_hot?

    再次感谢您这篇精彩的帖子。

  91. Ritesh 2019年1月21日 晚上6:18 #

    嗨,Jason,

    您的帖子真的很棒。感谢您写出如此精彩的帖子。

    我有一个疑问,既然我们已经从word2vec或glove获得了词的向量表示,为什么人们还要使用嵌入层呢?使用这两个预训练模型,我们已经获得了每个词相同大小的向量表示,如果找不到词,我们可以分配相同大小的随机值。在获得向量表示之后,为什么我们还要传递给嵌入层?

    谢谢

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

      通常,神经网络中学习到的嵌入表现更好,因为它特定于模型和预测任务。

  92. Ritesh 2019年1月22日 下午4:54 #

    嗨,Jason,

    谢谢你的回复。

    如果我设置 trainable = False。那么,当我已经使用 word2vec 或 glove 在序列中为每个单词提供了向量表示时,还需要使用 Embedding 层吗?

    谢谢

    • Jason Brownlee 2019年1月23日 上午8:45 #

      是的,如果你愿意,可以在训练期间保持嵌入固定。根据我的经验,结果通常不如预期。

  93. hayj 2019年2月1日 晚上10:08 #

    你好Jason,非常感谢这篇非常好的教程。我有一个问题:我在IMBD情感分析数据集上训练了您的模型。模型的准确率达到了80%。但是我的嵌入效果非常差。

    首先一个简短的细节,我使用了 `one_hot`,它使用了哈希技巧,但我使用了 `md5`,因为默认的 `hash` 函数在不同运行中不一致,Keras 的文档中提到了这一点(所以要保存模型并预测新文档,这不好,对吗?)。

    但重要的是我的词嵌入非常差,我创建了一个将小写词和嵌入(大小为8)映射的字典。遵循这个:https://stackoverflow.com/questions/51235118/how-to-get-word-vectors-from-keras-embedding-layer 我暂时没有使用Glove向量。

    我测试了搜索最相似的词,结果“good”得到了随机的词(holt, christmas, stodgy, artistic, szabo, mandatory…)。我将词汇大小设置为100000。当然,由于哈希技巧,两个词可以有相同的索引,所以我没有考虑1.0的相似度。我认为糟糕的词向量嵌入是由于我们在整个文档而不是像word2vec那样在上下文中训练嵌入,您认为呢?

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

      一般来说,根据我的经验,模型学习到的嵌入比预训练的嵌入表现更好。

  94. Despoina 2019年2月7日 下午6:47 #

    你好,这是一篇很棒的教程。您的所有教程都非常有帮助!谢谢。

    我想找到三个不同希腊语句子的嵌入(用于分类)。然后我想对它们进行配对合并并拟合我的模型。
    我读过您的教程“如何使用Keras函数式API进行深度学习”,这对于合并非常有帮助。
    我的问题是:有没有办法在将其用作模型输入之前进行计算?我必须有三个不同的模型来计算嵌入吗?

    提前感谢您。

    • Jason Brownlee 2019年2月8日 上午7:46 #

      是的,如果你愿意,可以手动准备输入:每个词映射到一个整数,整数将是嵌入中的一个索引。从那里你可以检索每个词的向量,并将其用作模型的输入。

      • Despoina 2019年2月8日 晚上8:56 #

        谢谢!!!

  95. Mohit 2019年2月10日 上午12:19 #

    嗨,Jason,

    非常感谢您精彩的解释。在阅读了许多其他资源后,我直到阅读了这篇文章才理解嵌入层。我有一些问题,如果您能抽出时间回答,我将不胜感激。

    1) 在您的代码中,您在嵌入层之后和密集层之前使用了一个展平层。在其他一些地方,我注意到使用GlobalAveragePooling1D()层代替了展平。您能解释一下全局平均池化是什么,以及为什么它用于文本分类吗?

    2) 您在其中一个评论中解释说,每个单词在训练前后都只有一个向量表示。所以只是为了确认,当单词x输入到嵌入层时,输出总是更新代表x的同一个向量吗?例如,对于词汇量大小为500,嵌入维度为10([500, 10]输出形状),如果单词x是输出中的第一个向量([0,10]),那么每次输入单词x时,第一个向量([0, 10])都会更新,而不是如果单词不存在?

    3) 选择嵌入维度的直觉是什么?

    再次感谢您,Jason。我将等待您的回复。
    Mohit

    • Jason Brownlee 2019年2月10日 上午9:43 #

      这两种方法都可以使用,它们做的事情相同。也许可以尝试两种方法,看看哪种最适合您的特定数据集。

      给定词的向量是学习出来的。模型训练完成后,每个词的向量是固定的。如果在训练期间某个词不存在,模型将无法支持它。

      嵌入必须足够大,才能捕获词之间的关系。通常100到300对于大型词汇量来说已经足够了。

  96. vamsi 2019年2月15日 下午4:27 #

    对初学者非常有用的帖子。但我对嵌入向量的大小有一个疑问。正如您在帖子中提到的——
    “嵌入层有一个50的词汇表和4的输入长度。我们将选择一个8维的小嵌入空间。
    该模型是一个简单的二元分类模型。重要的是,嵌入层的输出将是4个8维向量,每个词一个。”

    我不明白为什么嵌入层的输出应该是4个向量。如果它与输入长度有关,请解释一下如何?另外,“每个词一个”这个短语,我也不明白。

    • Jason Brownlee 2019年2月16日 上午6:15 #

      一个好的经验法则是从长度50开始,然后尝试增加到100或200,看看是否会影响模型性能。

  97. Ratha 2019年2月21日 晚上9:14 #

    嗨Jason,我在CNN中使用词袋作为特征时遇到了麻烦。你有没有关于实现基于BoW的CNN的想法?

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

      我不太清楚你为什么/如何将BoW编码的文档传递给CNN——因为所有的空间信息都会丢失。听起来是个坏主意。

  98. Alexa 2019年2月21日 晚上10:17 #

    嗨!感谢您提供的好教程。我有一个关于嵌入的问题。使用嵌入层训练嵌入与使用预训练嵌入相比,性能如何?使用预训练嵌入时,训练是否更快,模型所需时间是否更少?

    感谢您的回答。

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

      根据我的经验,作为模型一部分训练的嵌入似乎表现更好。

  99. Despoina 2019年2月24日 晚上8:16 #

    你好,很棒的帖子!

    我想了解更多关于Keras嵌入层中词汇量大小的信息。我正在使用希腊语和意大利语。您有什么科学论文可以推荐吗?

    非常感谢!

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

      也许可以尝试几种不同的词汇量大小,看看它对您的数据集的模型性能有何影响?

      • Despoina 2019年2月25日 晚上10:45 #

        好的,非常感谢!

  100. Yoni Pick 2019年2月25日 上午6:48 #

    嗨 Jason

    在使用预训练嵌入矩阵的无监督模型时,需要改变什么?

    如果你想使用弱监督怎么办?

  101. ark 2019年3月5日 晚上9:58 #

  102. Hadij 2019年3月10日 上午7:47 #

    嗨,Jason,
    对于独热编码器,如果我们给出了新的测试集,我们如何使用one_hot函数来获得与训练集相同的矩阵空间?因为我们不能为测试集设置一个单独的one_hot编码器。
    非常感谢。

    • Jason Brownlee 2019年3月10日 上午8:19 #

      您可以保留用于准备数据的编码器对象,并将其用于新数据。

  103. Miguel Won 2019年3月31日 上午1:01 #

    你好,
    我经常看到像您这样的实现,其中嵌入层是根据包含所有词的word_index构建的,例如使用Keras预处理Tokenizer API构建。但是,如果我用Tokenizer和词汇量限制(使用num_words)拟合我的语料库,为什么我需要一个与总唯一词数量相同大小的嵌入层?这不会浪费空间吗?构建一个大小适合我所需词汇量限制的嵌入层有问题吗?

    • Jason Brownlee 2019年3月31日 上午9:31 #

      没关系,空间很小。

      这可以很好地激励您确保您的词汇表只包含做出准确预测所需的词。

  104. Leena Agrawal 2019年4月15日 晚上9:47 #

    嗨,Jason先生,

    确实是优秀的教程!

    我有一个关于嵌入层维度的问题,您能帮帮我吗?

    e = Embedding(200, 32, input_length=50)

    我们如何决定选择out_dim的大小,这里是32?这个值有什么特定的原因吗?

    提前感谢
    莉娜

    • Jason Brownlee 2019年4月16日 上午6:48 #

      您可以尝试不同的输出维度大小,并评估它们对您的特定数据集的模型性能有何影响。

      如果您不确定,50或100是一个很好的起点。

  105. Mohammad 2019年4月16日 下午3:28 #

    你好,
    我使用带有 glove 的词嵌入训练了我的模型,但请告诉我如何准备测试数据以使用训练好的权重预测结果。我仍然没有找到任何遵循整个过程的帖子。特别是带有 glove 的词嵌入

    • Jason Brownlee 2019年4月17日 上午6:51 #

      词嵌入不能预测任何东西。我不明白,也许你能详细说明一下?

  106. Alex 2019年4月19日 下午12:20 #

    您好,Jason,

    感谢您的帖子。我有一个关于您实际拟合的嵌入数据的问题。我在模型编译后打印了 padded_docs。在我看来,打印出的矩阵不是嵌入矩阵。它是一个整数矩阵。所以我认为您在CNN中拟合的不是嵌入,而是您定义的整数矩阵。您能帮我解释一下吗?非常感谢。

    • Jason Brownlee 2019年4月19日 下午3:05 #

      是的,padded_docs 是整数,它们被馈送到嵌入层,该层将每个整数映射到一个8元素的向量。

      这些向量的值然后通过训练网络来定义。

  107. Oscar 2019年4月21日 上午4:25 #

    嗨,Jason,

    我正在进行字符嵌入。我的数据集包含原始的HTTP流量,包括正常和恶意的。我使用了Tokenizer API对我的数据进行整数编码,每个字符都有一个分配给它的索引。

    请让我知道我是否理解正确

    我的数据被整数编码为1-55之间的值,因此我的input_dim是55。

    我将从输出维度32开始,并根据需要修改此值。

    现在对于input_length,我有点困惑如何设置这个值。
    我的数据集中数字字符串的长度不同,最长的是666。我是否将input-length设置为666?如果这样做,长度较短的序列会发生什么?

    感谢您的帮助!

    • Oscar 2019年4月21日 上午6:39 #

      另外,我应该将输入维度设置为大于55的值吗?

    • Jason Brownlee 2019年4月21日 上午8:27 #

      你是说词嵌入而不是字符嵌入吗?

      我没有任何嵌入字符的例子——我不确定它是否有效。

      • Oscar 2019年4月21日 下午5:34 #

        我指的是字符嵌入。我使用了分词器并将字符级别设置为True。
        我不知道如何对http流量的查询字符串使用词嵌入,因为它们不是由实际单词组成的,而只是一串字符。
        我正在设计一个字符级神经网络,用于检测http请求中的参数注入。
        结果将以二进制格式表示,如果请求正常则为0,如果恶意则为1。
        所以您不认为字符嵌入在这里有用?

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

          抱歉,我没有字符嵌入的例子。

          不过,您应该能够向模型中的嵌入层提供整数编码字符的字符串。它会很像词嵌入,只是基数较低(可能小于100个字符)。另外,我不期望得到好的结果。

          你到底遇到了什么问题?

  108. Mario 2019年5月2日 下午6:09 #

    我发现 `vocab_size = len(t.word_index) + 1` 是错误的。这个索引不仅忽略了 `Tokenizer(num_words=X` 参数,而且存储的单词比实际编码的单词更多。

    我没有词数限制地拟合了我的文本,然后使用分词器对相同的文本进行编码,结果 `word_index` 的长度大于 `max(max(encoded_texts))`。

  109. lamesa 2019年5月17日 下午6:46 #

    你好Jason,你好吗?
    我正在用词嵌入做我的文本摘要硕士论文,现在我有很多问题,我该如何使用这些特征,以及哪种神经网络算法最好。请问您能给些指导吗……

  110. lamesa 2019年5月20日 晚上9:36 #

    谢谢你 Jason…这真的很有帮助…

  111. Siddhartha 2019年6月9日 下午6:06 #

    嗨,Jason,

    这整篇文章都非常有用。它帮助我编写了我的初步实现。
    我有一个关于Keras中的Input()和Embedding()的问题。
    如果我有一个预训练的词嵌入。在这种情况下,我应该使用Embedding还是Input?

    • Jason Brownlee 2019年6月10日 上午7:36 #

      是的,嵌入向量被加载到Embedding层中,并且该层可能被标记为不可训练。

  112. alphabeta 2019年6月23日 晚上7:44 #

    如果在测试中我们遇到了一些训练文本中没有的新词怎么办?
    它就无法通过嵌入层,对吗?

  113. Zeinab 2019年6月29日 晚上10:53 #

    嗨,Jason
    我想问一下如何保存我学到的词嵌入?

  114. Zeinab 2019年7月2日 上午4:03 #

    我能构建一个只用于学习嵌入矩阵的网络吗?

  115. zeinab 2019年7月10日 下午6:28 #

    你好,
    我有一个文本相似性应用程序,我将皮尔逊相关系数作为 Keras 指标来衡量。
    在许多 epoch 中,我注意到相关系数值为 nan。
    这是正常的还是模型有问题?

    • Jason Brownlee 2019年7月11日 上午9:46 #

      您可能需要调试模型以找出 NAN 的原因。

      也许是梯度爆炸或梯度消失?

      • Zeinab 2019年7月12日 下午2:55 #

        你是说我必须调整激活函数吗?

        我使用elu激活函数和Adam优化函数,

        你是说我必须改变其中任何一个并查看结果吗?

        • Jason Brownlee 2019年7月13日 上午6:52 #

          也许可以。

          尝试relu。
          尝试批量归一化。
          尝试更小的学习率。

      • Zeinab 2019年7月13日 晚上10:19 #

        我能知道您所说的调试模型是什么意思吗?

        • Jason Brownlee 2019年7月14日 上午8:10 #

          是的,这里有一些想法

          – 考虑积极地将代码削减到最低限度。这将帮助您隔离问题并专注于它。
          – 考虑将问题削减到只有一个或几个简单示例。
          – 考虑寻找其他类似的代码示例,这些示例有效,并缓慢修改它们以满足您的需求。这可能会暴露您的错误。
          – 考虑将您的问题和代码发布到 StackOverflow。

  116. Leon 2019年7月20日 下午12:19 #

    vocab_size = len(t.word_index) + 1

    为什么我们需要将词汇量增加1???

    • Jason Brownlee 2019年7月21日 上午6:23 #

      这是为了我们可以将0保留给未知词,并将已知词从1开始。

  117. Zineb_Morocco 2019年7月26日 上午5:48 #

    非常感谢这项出色的工作……我们现在是2019年7月,仍在从中受益。

    • Jason Brownlee 2019年7月26日 上午8:33 #

      谢谢。我 стараюсь写出经久不衰的教程,使其保持有用。

  118. Christiane 2019年7月29日 上午5:24 #

    亲爱的 Jason,

    非常感谢您的详细解释和代码示例。

    然而,我仍然想知道的是,如何将嵌入与其他变量结合起来,即有一些数值或分类变量,然后有一个或两个文本变量。因为我看到您在 model.fit 中输入了填充文档(仅文本)。但是我如何添加其他变量呢?输入总是只有一个文本变量似乎不切实际。

  119. Zineb_Morocco 2019年7月30日下午11:43 #

    感谢 Jason 的精彩工作和示例。这真的很有帮助。

  120. Youssef MELLAH 2019年8月4日上午6:19 #

    谢谢你,Jason Brownlee,这非常有趣和清晰。

    如果我有两个输入呢?

    例如,我正在进行 Text-to-SQL 任务,这需要两个输入:用户问题和表模式(列名)。

    我该如何处理?如何进行嵌入?使用两个嵌入层吗?

    感谢您的帮助。

  121. Youssef MELLAH 2019年8月4日上午7:30 #

    啊,好的,这也很有趣,谢谢!

    您能确认一下上述架构,以便在同一个模型中编码用户问题和表模式吗?

    (1) userQuestion ==> One-hote-endoding ==> Embedding(GloVe) ==> LSTM
    (2) tableShema ==> One-hote-endoding ==> Embedding(GloVe) ==> LSTM

    (1) 连接 (合并) (2) ==> 模型的其余层……。

    谢谢 Jason。

    • Jason Brownlee 2019年8月5日上午6:42 #

      无需进行独热编码,文本可以编码为整数,整数通过嵌入映射到向量。

      • Youssef Mellah 2019年8月5日上午7:58 #

        好的,清楚了,谢谢。

        注意力机制只能通过合并来完成吗?

        • Jason Brownlee 2019年8月5日下午1:59 #

          不,如果您愿意,可以在每个输入上使用注意力。

          • Youssef MELLAH 2019年8月5日下午6:42 #

            我应该对两个输入(用户问题和表模式)分别进行注意力处理,还是可以在合并两个输入之后进行?

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

            测试多种不同的模型类型,看看哪种类型最适合您的特定数据集。

          • Youssef MELLAH 2019年8月15日上午12:41 #

            好的,谢谢你 Jason!!

          • Jason Brownlee 2019年8月15日上午8:12 #

            不客气。

  122. Elizabeth 2019年8月5日上午12:06 #

    我想知道预训练的 word2vec,目前还没有这么好的教程。我正在寻找实现预训练的 word2vec,但我不知道是应该遵循 Glove 的相同步骤,还是寻找其他资源?
    谢谢 Jason 先生,您在机器学习方面对我启发很大

  123. Dean 2019年8月7日上午1:06 #

    为什么你的嵌入层不使用 mask_zero=True?这似乎是必要的,因为你正在用0填充句子。

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

      很好的建议,不确定这个参数在我写这些教程的时候是否存在。我当时用的是掩蔽输入层。

  124. Nathalia 2019年8月9日上午8:04 #

    嗨,能帮我一个问题吗?

    我正在处理一个数据集,其中有一个城市列作为特征,并且有很多不同的城市。因此,我为这个特征创建了一个嵌入层。首先,我使用了这个命令
    data['city']= data['city'].astype('category')
    data['city']= data['city'].cat.codes
    之后,每个不同的城市都被分配了一个从0开始的值

    所以,我很困惑,当测试数据有一个未训练的输入时,这个嵌入层是如何工作的。我看到您说当这种情况发生时,我们必须将0作为输入,但是0
    它与某个城市有关。我应该从1开始给城市分配这些值吗?

    • Jason Brownlee 2019年8月9日上午8:20 #

      好问题。

      通常,未见类别被分配为 0,表示“未知”。

      0 应该保留,实际编号应该从 1 开始。

      • Nathalia 2019年8月9日上午8:25 #

        谢谢你,你总是帮我很多!

  125. ravi 2019年8月20日下午1:38 #

    嗨,Jason。

    感谢您如此精彩的教程。我困惑的是,当我们谈论学习到的词嵌入时,我们是考虑嵌入层的权重还是嵌入层的输出。

    换句话说,当我们使用预训练的嵌入,比如说“glove.6B.50d.txt”时,这些词嵌入是权重还是层的输出?

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

      它们是同一回事。整数被映射到向量,这些向量是嵌入的输出。

  126. Ralph 2019年8月23日下午7:39 #

    嗨,Jason,

    我是机器学习新手,尝试不同的东西,您的帖子是我遇到的最有帮助的,它对我理解帮助很大,谢谢!

    在这里我想我理解了过程,但我还有一个更深层的问题,关于嵌入。如果我理解正确的话,这种嵌入将一组词作为点映射到另一个维度空间。您的示例中令人惊讶的事实是,我们从一个维度为4的空间传递到一个维度为8的空间,所以乍一看可能不会被视为一种改进。

    但我仍然认为嵌入使得新空间中的点更均匀地分布,我说的对吗?那么我不明白几件事
    -一个词出现的上下文是如何发挥作用的?经常靠近的其他词也会在新空间中由更接近的点表示吗?
    -为什么它必须是整数?为什么它更适用于词编码?我的意思是我们可以想象同样的过程也可能对图像有帮助。或者它只是一个为词文档量身定制的降维技术?

    无论如何,感谢您的见解

    • Jason Brownlee 2019年8月24日上午7:50 #

      不是均匀分布,而是以一种保留或最佳捕捉它们关系的方式分布。

      上下文定义了嵌入中捕捉到的关系,例如哪些词与其他词一起出现。它们的亲近度。

      每个词都有一个向量。最简单的方法是将词映射到整数,并将整数映射到矩阵中向量的索引。没有其他原因。

      很好的问题!

  127. Anand 2019年8月24日下午4:43 #

    Jason,非常感谢您的时间和精力!

    我的问题与此行有关——
    “e = Embedding(vocab_size, 100, weights=[embedding_matrix], input_length=4, trainable=False)”

    这里您使用了 weights=[embedding_matrix],但是没有关系表明哪个词对应哪个向量。然后,它为每个文档生成一个 4*100 矩阵(例如 [ 6 2 0 0])。它将如何准确地提取与 6,2,0,0 相关的向量?

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

      向量是有序的,您可以使用数组索引检索每个词的向量,例如词 0、词 1、词 2、词 3 等。

  128. Youssef MELLAH 2019年9月2日上午12:36 #

    你好 Jason,

    我正在寻找关于 Python(numpy pandas…以及 ML DL 和 NLP 工具)和 Keras 的有趣培训!

    有什么建议吗?

  129. Emre Calisir 2019年9月3日下午6:32 #

    感谢您的文章,我将为意大利语文档运行它。有没有涵盖意大利语词汇的 GoogleNews 预训练 word2vec?

  130. Muhammad Usgan 2019年9月7日下午5:59 #

    哈喽 Jason,我可以在这个模型中加入 Dropout 吗?

  131. ASHWARYA ASHIYA 2019年9月19日下午6:49 #

    e = Embedding(vocab_size, 100, weights=[embedding_matrix], input_length=4, trainable=False)

    参数 – weights=[embedding_matrix] – 代表什么?是嵌入层的权重还是输入?

    • Jason Brownlee 2019年9月20日上午5:37 #

      权重就是向量,例如词汇表中每个词的向量。

  132. Munisha 2019年10月3日下午7:30 #

    _________________________________________________________________
    层(类型) 输出形状 参数 #
    =================================================================
    embedding_1 (Embedding) (None, 4, 8) 400
    _________________________________________________________________
    flatten_1 (Flatten) (None, 32) 0
    _________________________________________________________________
    dense_1 (Dense) (None, 1) 33
    =================================================================
    总参数:433
    可训练参数:433
    不可训练参数: 0
    _

    您能解释一下嵌入层学习到的权重数量吗?现在我们有10个文档,嵌入层从4到8。这里实际上会学习多少个权重参数。我的理解是应该只有 (4+1)*8 = 40 个权重需要学习,包括偏置项。为什么它会单独为所有文档学习权重 (10*(4+1)*8 = 400)?

    • Jason Brownlee 2019年10月4日上午5:40 #

      嵌入中的权重数量是向量长度乘以向量(词)数量。

  133. martin 2019年10月12日下午4:29 #

    嗨,Jason

    在这个例子中,这是哪种神经网络架构?它不是 LSTM,也不是 CNN。它是多层感知器模型吗?

    • Jason Brownlee 2019年10月13日上午8:26 #

      我们只是在处理嵌入。我想有了一个输出层,你可以称它为 MLP。

  134. Zafari 2019年10月13日上午5:52 #

    你好,感谢这篇优秀的文章。我尝试在一个基于 Keras 的分类器中使用预训练的词嵌入,而不是随机数。然而,在构建嵌入矩阵并按照以下方式将其添加到嵌入层后,在训练 epoch 期间,所有准确性值都相同,没有发生学习。但是,在删除“weights=[embedding_matrix]”后,它工作得很好,达到了 90% 的准确性。

    layers.Embedding(input_dim=vocab_size, weights=[embedding_matrix],
    output_dim=embedding_dim,
    input_length=max_len,trainable=True)

    这种奇怪行为的原因可能是什么?
    谢谢

    • Jason Brownlee 2019年10月13日上午8:35 #

      专门针对您自己的数据进行的嵌入通常比通用嵌入更好。

      • Hussain 2020年7月28日上午8:46 #

        快速提问。在使用预训练嵌入(MUSE)的嵌入层中,将 trainable=True 设置为可以吗?

        注意:当我设置 trainable=True 时,模型不会过拟合。如果我设置 trainable=False,模型预测得不好。

        • Jason Brownlee 2020年7月28日上午8:52 #

          是的,尽管您可能希望使用较小的学习率,以确保不会冲掉权重。

          • Hussain 2020年7月28日上午9:24 #

            非常感谢您的回复。目前我正在使用 0.0001 的学习率。

            “Adam(learning_rate=0.0001)”

          • Jason Brownlee 2020年7月28日上午10:54 #

            也许使用 SGD 代替 Adam,因为 Adam 会为每个模型参数改变学习率,并且可能会变得非常大。

            或者至少比较 Adam 和 SGD 的结果。

  135. Xuesong Wang 2019年10月13日下午8:32 #

    嗨,Jason,
    谢谢您的帖子。我有一个问题。我使用的数据包括分类和数值特征。比如说,有些特征是成本和时间,而另一些是邮政编码。我应该如何编写代码?构建单独的模型并将它们连接起来吗?谢谢

    • Jason Brownlee 2019年10月14日上午8:07 #

      很好的问题!

      这些特征必须单独准备,然后聚合。

      我喜欢这样做的两种方法是:

      1. 手动。单独准备每种特征类型,然后连接成输入向量。
      2. 多输入模型。单独准备特征,并将不同的特征输入到模型的不同输入中,让模型连接特征。

      这有帮助吗?

      • martin 2019年10月15日下午4:39 #

        分类变量是否应该使用独热编码转换为数值变量?

      • Franz Götz-Hahn 2019年10月28日下午9:04 #

        如果您有多变量时间序列,并且您知道它们有意义地连接(例如 x 和 y 的轨迹),那么在将它们馈入嵌入之前放置一个 Conv 层是否有意义?

        您所说的“准备”特征是什么意思?

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

          通常情况下,嵌入是第一步,例如对输入的解释。

          “准备”意味着以您想要的任何方式进行转换,例如编码或缩放。

          • Franz Götz-Hahn 2019年10月29日下午5:03 #

            谢谢您的回答!如果我能再问一个问题:多变量数值数据的嵌入是否不常见?我见过很少使用它的工作。

          • Jason Brownlee 2019年10月30日上午5:57 #

            嵌入用于分类数据,而不是数值数据。

  136. Zineb_Morocco 2019年10月16日上午1:28 #

    嗨,Jason,

    我使用了一个例子,其中词汇量大小设置为200,训练样本包含大约20个不同的词。
    当我使用 ** layers[0].get_weights()[0]** 检查嵌入(向量)时,我得到一个包含200行的数组。

    1/ 我如何知道每个词(从我得到的20个词中)对应的向量?
    2/ 既然我只使用了20个词,那180个(200-20)向量是从哪里来的?

    提前感谢。

    • Jason Brownlee 2019年10月16日上午8:08 #

      词汇量大小和词数是同一个东西。

      我想你可能混淆了嵌入的大小和词汇量?

      每个词都被分配一个数字(0, 1, 2 等),向量的索引映射到词,向量 0 是词 0,以此类推。

  137. Zineb_Morocco 2019年10月16日下午11:38 #

    感谢您的回答,Jason,
    我将澄清我的问题
    词汇量大小是 200,这意味着词的数量是 200。
    但实际上我只处理了 20 个词(我的训练样本中的词):比如说 word[0] 到 word[19]。
    那么,在嵌入之后,vector[0] 对应于 word[0],依此类推。但是 vector[20].. vector [30] … 它们对应什么呢?
    我没有 word[20] 或 word[30]。

    • Jason Brownlee 2019年10月17日上午6:37 #

      如果您定义了200个词的词汇表,但在训练集中只有20个词,那么不在训练集中的词将具有随机向量。

      • Zineb_Morocco 2019年10月18日上午12:22 #

        好的。谢谢你。

  138. Elizabeth 2019年10月27日上午7:28 #

    我想以 GloVe 保存其模型为文本文件(词后跟其向量)的相同方式保存我自己的预训练模型。我该怎么做?
    谢谢你

    • Jason Brownlee 2019年10月28日上午6:00 #

      您可以从嵌入层通过 layer.get_weights() 提取权重,然后枚举向量并以您喜欢的格式保存到文件中。

  139. Elizabeth 2019年10月28日上午7:47 #

    我是Python新手,我不明白你说的枚举是什么意思……我应该从哪个层获取权重?

    • Jason Brownlee 2019年10月28日下午1:16 #

      您可以从嵌入层获取向量。

      您可以保留对构建模型时嵌入层的引用,或者通过索引(例如 model.get_layers()[0])或名称(如果您命名它)检索该层。

      枚举意味着循环。

  140. Michael 2019年11月19日上午4:47 #

    你好,杰森!

    谢谢你的文章!
    我一直在思考可学习嵌入层的 input_dim。
    您将其设置为 vocab_size,在您的示例中是 50(哈希技巧的上限),这比实际词汇量 15 大得多。

    Keras 中 Embedding 的文档写道:
    “词汇表的大小,即最大整数索引 + 1。”
    这很模糊。

    我用了一些数字来实验 vocab_size,但没有发现任何系统性的差异。

    对于更实际的例子,这真的有关系吗?

    您能简单说几句吗?
    再次感谢

    • Jason Brownlee 2019年11月19日上午7:50 #

      较小的词汇量意味着您将拥有较少的单词/词向量,从而模型更简单,学习速度更快/更容易。代价是它的性能可能会更差。

      这是一个权衡:大/慢但好,小/快但稍差。

      • Michael 2019年11月19日下午7:48 #

        谢谢你,Jason!

        我可能没有解释清楚
        词汇表中的*实际*单词数量是相同的 (14)。
        区别在于 Embedding() 的 input_dim 值。

        在示例中,您选择了 50,这个值足够高以防止编码冲突,但同时也
        在其中一个案例中将其用作 input_dim。

        Michael

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

          我明白了。

          • martin 2019年11月22日下午6:28 #

            我以为问题是“词汇表的大小,即最大整数索引 + 1”。既然这个例子中有 14 个词,为什么词汇表大小不是 15,而是 50?

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

            词汇量的大小,也是嵌入空间的大小。它们是不同的——以防引起混淆。

            嵌入中必须有 size(vocab) + 1 个向量,以便为“未知”留出空间,例如索引 0 处的向量。

  141. martin 2019年11月22日下午5:52 #

    Jason:在这个例子中,使用了“one_hot”函数而不是“to_categorical”函数。第二个是真正的独热表示,第一个只是为每个词创建一个整数。为什么这里没有使用 to_categorical?它们是不同的,对吧?

  142. moSaber 2019年11月24日上午11:11 #

    非常感谢 Jason!在第 3 节“学习嵌入示例”中,您能详细说明嵌入层中正在训练的 400 个参数是什么吗?谢谢

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

      是的,每个向量都映射到一个 8 元素向量,词汇表有 50 个词。因此是 50*8 = 400。

      • Mohit 2020年9月26日下午6:54 #

        Jason,为什么嵌入层的输出形状是:(4,8)?
        它应该是 (50,8),因为词汇量大小是 50,我们正在为词汇表中的所有词创建嵌入。

        • Jason Brownlee 2020年9月27日上午6:51 #

          词汇量大小是层中向量的总数——支持的词的数量,而不是输出。

          输出是输入词的数量 (8),其中每个词具有相同的向量长度 (4)。

          • Sean 2023年2月11日下午8:57 #

            这是笔误吗?输出是输入词的数量(4),其中每个词的向量长度相同(8)。

          • James Carmichael 2023年2月12日上午9:26 #

            嗨 Sean……我们不认为这是笔误。当您执行代码时会发生什么?

  143. criz 2019年12月30日上午3:13 #

    嗨,我运行文件时需要一些帮助。

    (wordembedding) C:\Users\Criz Lee\Desktop\Python Projects\wordembedding>wordembedding.py
    回溯(最近一次调用)
    文件 “C:\Users\Criz Lee\Desktop\Python Projects\wordembedding\wordembedding.py”, 第 1 行,在
    from numpy import array
    文件 “C:\Users\Criz Lee\Anaconda3\lib\site-packages\numpy\__init__.py”, 第 140 行,在
    from . import _distributor_init
    文件 “C:\Users\Criz Lee\Anaconda3\lib\site-packages\numpy\_distributor_init.py”, 第 34 行,在
    from . import _mklinit
    ImportError: DLL 加载失败:找不到指定的模块。

    请指导..谢谢

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

      看起来您的开发环境有问题。

      这个教程可能会有所帮助
      https://machinelearning.org.cn/setup-python-environment-machine-learning-deep-learning-anaconda/

      • criz 2019年12月31日上午3:20 #

        嗨 Jason,我尝试了您提供的网址,但仍然无法解决问题。

        我基本上输入了
        1. conda create -n wordembedding
        2. activate wordembedding
        3. pip install numpy (安装版本 1.16)
        4. 运行 wordembedding.py

        错误显示
        文件 “C:\Users\Criz Lee\Desktop\Python Projects\wordembedding\wordembedding.py”, 第 2 行,在
        from numpy import array
        ModuleNotFoundError: 没有名为 'numpy' 的模块

        请指导..谢谢

        • Jason Brownlee 2019年12月31日上午7:35 #

          听到这个消息我很难过。我不是调试工作站的专家,也许可以尝试在 stackoverflow 上发帖。

  144. martin 2019年12月30日上午8:23 #

    嗨,Jason:如何使用在训练数据上拟合的 Tokenizer 对象编码新文档?似乎没有函数可以从 tokenizer 对象返回编码器。

    • Jason Brownlee 2019年12月31日上午7:24 #

      您可以保存分词器,并以与分词器拟合后处理训练数据相同的方式使用它来准备新数据。

  145. congmin min 2019年12月31日上午11:59 #

    “保存分词器”是什么意思?分词器是一个对象,而不是模型。

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

      它和模型一样重要,从这个意义上说,它是模型的一部分。

      您可以使用 pickle 将 Python 对象保存到文件。

  146. Sintayehu 2020年1月3日下午5:08 #

    简短的帖子……我对阅读用于序列标注任务的预训练词嵌入很感兴趣。

  147. Rishang 2020年1月25日下午4:56 #

    你好先生,

    我无法理解向量空间的意义?
    您为第一个问题给出了 8,glove 向量为每个词有 100 维度。
    这些向量空间背后的思想是什么,每个维度的值告诉我们什么?

    谢谢你 :)

    • Jason Brownlee 2020年1月26日上午5:15 #

      向量空间的大小并不太重要。

      更重要的是,模型学习到了一种表示,其中相似的词在向量空间中将具有相似的表示(坐标)。我们无需指定这些关系,它们是自动学习的。

      • Rishang 2020年2月3日上午1:07 #

        谢谢先生的回答。我清楚地理解了向量空间。
        我还有一个问题——如果我将词汇量大小声明为 50,而我的训练数据中有超过 50 个词,那些额外的词会发生什么?

        出于同样的原因,我无法理解 glove 向量的这一行——
        “最小的嵌入包是 822MB,名为“glove.6B.zip”。它在一个包含十亿个 token(单词)的数据集上训练,词汇量为 40 万个单词。”
        那 60 万个词呢?

  148. asma 2020年1月31日下午4:22 #

    你好,
    我有一个词列表作为我的数据集/训练数据。因此,我按照以下方式运行您的 glove 代码

    —-错误是——
    ValueError 回溯 (最近一次调用)
    in ()
    8 values = line.split()
    9 words = values[0]
    —> 10 coefs = asarray(values[1:], dtype='float32')
    11 embeddings_index[words] = coefs
    12 f.close()

    /usr/local/lib/python3.6/dist-packages/numpy/core/_asarray.py in asarray(a, dtype, order)
    83
    84 “””
    —> 85 return array(a, dtype, copy=False, order=order)
    86
    87

    ValueError: could not convert string to float: '0.1076.097748'
    ————————————————————————————-

    能帮帮我吗

  149. Sanpreet Singh 2020年2月5日下午5:46 #

    您好,Jason Brownlee

    希望您一切安好,感谢您撰写如此精彩的文章。我想向您请教一个我遇到的问题。

    我使用 glove 词嵌入在 imdb 电影数据集上创建了 keras 深度学习模型。我使用了 50 维,但在验证过程中,训练和验证数据的准确性之间存在很大差距。我非常仔细地使用自定义方法进行了预处理,但仍然出现过拟合。

    在预测阶段,我没有使用测试数据集,而是获取了实时文本并进行预测,但是如果我一遍又一遍地对相同的输入数据进行预测,结果会有所不同。我正在尽力找出为什么我的结果会不同。

    我有 8 个类别,它们描述了每个评论的分数,数据是分类的。Softmax 层每次向训练好的模型输入相同数据时都会预测出不同的结果。

  150. Saad Farooq 2020年2月7日上午2:40 #

    我有一个数据集,其中训练数据是不同文件中的测试数据。我如何将测试数据传递给模型进行评估?

    • Jason Brownlee 2020年2月7日上午8:22 #

      将它们分别加载到内存中,然后一个用于训练,一个用于测试/验证。

      也许我没理解问题所在?

  151. sachin 2020年2月24日下午10:58 #

    如何将文本输入到一个输入层形状为 (200, ) 的预训练 LSTM 模型中。
    我想知道如何转换文本输入并将其作为模型的输入。

  152. Nati 2020年2月26日下午10:07 #

    非常感谢这篇详细的教程。我想我漏掉了一些东西……当使用预训练的 GloVe 嵌入时,如果您想进行训练测试拆分,什么时候是执行它的正确时机?
    我是否需要在创建权重矩阵之后进行?

    • Jason Brownlee 2020年2月27日上午5:47 #

      抱歉,我不太明白你的问题——嵌入和训练/测试拆分有什么关系?你能详细说明一下吗?

      • Nati 2020年2月27日下午9:27 #

        当然。我想使用嵌入来创建一个模型,该模型将预测 30 个不同类别中的一个类别。我使用的数据框包含一个文本列,我希望用它来预测类别。为了做到这一点,我考虑使用预训练的嵌入(与您所做的一样,但类别更多)。现在,为了测试模型,我想进行拆分,所以我的问题是您建议何时进行?我尝试为所有数据创建权重矩阵,然后将其拆分为训练集和测试集,但它在测试集上给出了非常差的结果。

        有什么想法是我做错了吗?

        • Jason Brownlee 2020年2月28日上午6:07 #

          如果您自己训练嵌入,它是在训练数据集上准备的。

          如果您使用预训练的嵌入,则没有拆分是合理的,因为它已经在不同的数据上训练过。

          • Nati 2020年2月28日上午10:23 #

            谢谢,我想我明白了(抱歉,我有点新手)。假设我想使用训练好的模型来预测未见数据上的标签,输入应该是什么?它应该是一个相同形状的填充文档吗?

          • Jason Brownlee 2020年2月28日下午1:27 #

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

  153. Despoina M 2020年3月19日上午9:01 #

    你好,又一篇很棒的帖子!

    我想问一下,关于使用预训练嵌入的示例,是否可以减少词汇量大小?我有一个 300 维的预训练嵌入。我的词汇量大小是 7000。
    当我将词汇量大小设置为 300 时,我得到了这个错误

    embedding_matrix[i] = embedding_vector

    IndexError: index 300 is out of bounds for axis 0 with size 300

    提前感谢

    • Jason Brownlee 2020年3月19日上午10:14 #

      是的,但您必须在 Tokenizer 中设置词汇量大小。

      • Despoina M 2020年3月20日上午1:59 #

        感谢您的快速回复。我做到了。

  154. Tyler 2020年3月20日上午6:57 #

    感谢教程!我正在为我的图像到字幕模型使用 300d 嵌入,但过滤掉词汇表中的稀有词。假设我有 10k 个词,我应该只用

    tokenizer.word_index.get(word, vocab_size + 1) <= vocab_size

    来过滤掉我不想要的词吗?

    另外,您认为在训练后期重新训练嵌入权重以进行微调值得吗?我正在从冻结预训练编码器,然后随着解码器达到一定有效性逐渐解冻层的角度思考这个问题。

  155. Aman Savaria 2020年3月22日上午6:23 #

    嗨,Jason,
    我有一个关于代码的问题。您将 vocab_size 设置为比唯一词的数量大 1。我无法理解您为什么这样做,您能告诉我吗?
    我完全是新手,也不是编程背景出身,所以如果这是个愚蠢的问题,我很抱歉。
    谢谢你

    • Jason Brownlee 2020年3月22日上午6:59 #

      是的,我们对词使用 1 的偏移量,并将索引 0 保留给“未知”词。

  156. Aman Savaria 2020年3月24日上午6:41 #

    哦……谢谢 Jason

  157. Ahmed B. 2020年3月27日 凌晨2:43 #

    嗨,Jason,
    我正在处理一个包含类别特征和数值特征的多元时间序列。我使用了3年的数据:20支股票作为训练窗口期30天,20支股票作为目标X_train,持续7天。X_train.shape = (N_samples, 20*30, N_features),y_train.shape = (N_samples, 20*7, N_features)。我的问题是,如何为这3个3D数组中的3个类别变量应用嵌入层?
    我尝试使用这部分代码,但它不起作用

    cat1_input = Input(shape=(1,), name='cat1')
    cat2_input = Input(shape=(1,), name='cat2')
    cat3_input = Input(shape=(1,), name='cat3')

    cat1_emb = Flatten()(Embedding(33, 1)(cat1_input))
    cat2_emb = Flatten()(Embedding(18, 1)(cat2_input))
    cat3_emb = Flatten()(Embedding( 2, 1)(cat3_input))

  158. Ahmed B. 2020年3月27日 上午7:24 #

    感谢您的及时回复,Jason。本教程是关于2D数组的嵌入,但在我的情况下,我需要构建一个模型,以3D数组(N_samples, time_steps, N_features)作为输入,并以(time_steps,N_stocks)作为输出。

  159. Despina M 2020年4月12日 凌晨1:50 #

    再次问好,

    我这次想知道,比较两种不同语言的两个嵌入矩阵是否值得。我想找出两种不同语言的两个矩阵之间的相似性。

    非常感谢

  160. sangam 2020年4月16日 中午12:07 #

    你好,Jason,这篇文章真的帮到我了,我觉得参数已经变了,
    Keras 文档中,weights 参数现在是“Embedding_initializer”。

  161. Charles 2020年4月20日 上午6:08 #

    嗨,Jason,我遇到了内存问题,因为我的词汇量约为400,000。我有大约195847个训练样本,每个句子的输出最大长度为5个词。

    所以当我尝试为解码器输出创建一个one_hot时,因为它试图创建一个195847、400000、5的矩阵,所以它显然会耗尽内存。

    我该如何解决这个问题?

    • Jason Brownlee 2020年4月20日 上午7:35 #

      好问题。

      尝试减少词汇量。
      尝试缩小数据集的大小。
      尝试缩小模型的大小。
      尝试使用其他表示,例如哈希。
      尝试在具有更多内存的 EC2 实例上运行。

      • Charles 2020年4月22日 晚上10:56 #

        另外一点是可以使用 keras 的 fit_generator 进行批量运行。

        我还有一个问题,我知道这可能听起来很傻,但是

        为什么测试需要推断模型或解码模型?那么训练模型有什么帮助呢?我唯一能看到的是它有助于决定编码器输入。我是否遗漏了什么?在我看来,训练的全部目的都失去了。

        • Jason Brownlee 2020年4月23日 上午6:06 #

          我不明白。你训练一个模型,然后用它来推断。没有训练,它是无用的。没有推断,你训练也就没有意义。

          也许你可以详细说明一下?

  162. Mohamed 2020年4月21日 上午11:02 #

    你好,

    我想问一下,如果我的标签不仅有积极和消极,还有中性,我该如何将其添加到y_training中?

  163. Charlène 2020年4月25日 上午5:38 #

    你好,

    感谢这篇解释得非常清楚的文章。

    我不明白嵌入层中嵌入是如何学习的。这是常见的反向传播吗?

  164. Rahim 2020年5月5日 凌晨1:28 #

    亲爱的Jason
    感谢您精彩有用的指导。当我运行本页第4部分(使用预训练GloVe嵌入的示例)中您建议的代码时,我收到以下错误,而我已经从您上面提供的URL下载了glove.6B.100d文件。您能帮我找到错误原因吗?

    回溯(最近一次调用)
    文件“C:/Users/Dehkhargani/PycharmProjects/test2/test2.py”,第40行,在
    coefs = asarray(values[1:], dtype=’float32′)
    文件“C:\Users\Dehkhargani\Anaconda\lib\site-packages\numpy\core\_asarray.py”,第85行,在asarray
    返回数组(a, dtype, copy=False, order=order)
    ValueError: 无法将字符串转换为浮点数:'ng'

  165. Mohammad 2020年5月17日 晚上9:50 #

    嗨,Jason,感谢您的有用帖子。

    GloVe 或 Google news 等预训练词嵌入在非英语文本上仍然有效吗?

    谢谢

  166. Roshan Nayak 2020年5月18日 凌晨3:36 #

    谁能告诉我,我们为什么要将词汇量加1。
    vocab_size = len(t.word_index) + 1
    请告诉我。谢谢!!

    • Jason Brownlee 2020年5月18日 上午6:21 #

      为“0”留出空间,它代表“未知”词汇。

  167. Tanay Gupta 2020年5月19日 下午5:00 #

    “该模型是一个简单的二元分类模型。重要的是,嵌入层的输出将是4个8维向量,每个向量对应一个单词。”

    你是怎么知道输出将是4个向量的?

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

      我们可以通过调用 model.summary() 来检查模型的形状。

  168. JG 2020年6月22日 晚上9:46 #

    嗨 Jason

    很棒的教程!这是我第一次接触NLP,特别是“文本分类/情感分析”。因此,我对技术定义、程序、它们的含义等有点困惑。

    让我用我自己的想法,为大家总结一下,以便分享并期待您的更正/评论。

    1º) 从一个由文本文档列表组成的数据集中,我们将针对文本分类问题(例如)进行训练,我们读取它们并获取每个文档的单词列表(例如,使用keras API “text_to_word_sequence()”)。

    2º) 然后我们可以应用某种词语清理/整理过程,使用字符串对象方法只获取字母词,或抑制词语标点符号,或消除最小词长或词语重复等。
    使用 keras “Tokenizer” 对象(例如),我们可以定义一个词汇表(或构成整个数据集文档的不同单词的最小公共数量),此外,通过分词器方法“fit_on_texts”(应用于所有文档单词)来定义一个单词计数器。

    3º) 现在我们有了所有文档的所有词(已清理),我们必须执行机器学习中最重要的问题。那就是,将词(标记)转换为数字,以便通过机器学习模型进行训练。如何转换?通过编码它们!
    这些数字必须排列成张量(或数组),由样本(张量的行)、列(每个文档的不同特征或数字词或词汇词的数量),甚至张量的第三维度(例如,深度轴?),通过将它们嵌入到词向量空间(任意维度)中。

    为了执行这种编码工作(数字转换),我们可以使用keras分词器方法,例如“texts_to_matrix()”、“texts_to_sequences()”或其他keras方法,例如“one_hot()”,始终借助keras的“pad_sequences()”方法来使所有文档的所有词(特征)具有相同的长度,例如使用每个文档的最大词长,或者仅仅因为我们想将完整的词汇表大小表示作为每个文档的特征长度。

    所有这些过程的结果是,我们必须有一个干净的输入数据集,一个2D维度(文档,特征)或3D维度(文档,特征,一个额外的嵌入维度)的数字X张量,如果我们使用深度学习技术(例如嵌入)。

    4) 我们还可以利用“迁移学习”的优势,当我们应用嵌入式深度学习层时,如果我们加载其他地方训练过的嵌入式层的预训练权重(例如 GloVe 词典,包含 400,000 个不同的词及其各自的 100 个坐标权重),我们必须将其适应于我们自己文档中使用的词汇表(例如,我们自己任意选择的 100 个不同的词,以及 100 个坐标作为每个词的向量词空间)。

    5º) 所以现在我们已经将文档列表(词语列表)转换为一个单一的数字张量X,除了关联的Y标签之外,我们必须定义模型,其中包含一个输入层,以及embedding()、Conv1D()和MaxPool1D()层(例如),如果我们正在使用深度学习技术,再加上一个最终的flatten()层,以便将特征词提取呈现给头部全连接层(主要包括Dense()层),这些层最终将学习与每个文档标签关联的数字模式提取(代表每个文档的词语集合)。

    这是我对NLP文本分类问题的总结理解。谢谢。

    • Jason Brownlee 2020年6月23日 上午6:21 #

      不错的总结,从我粗略一看,基本准确。

  169. JG 2020年6月23日 凌晨3:21 #

    抱歉评论太长了,Jason!

    ——我还要分享我的代码结果,基于您精彩的教程。因为我喜欢您教导我们的方式……不是理论学习,而是通过最终和可操作的代码进行实践和实验……再次感谢!

    ——我首要关注的是,即使我们有字符串方法、“分词器”对象(类)等……我们仍然需要编写许多行代码……我可以想到,可能已经存在更高级别的API文本处理和编码,以便为它们提供适当的参数,例如(要读取的文档、清理文档单词的方式过滤器、要应用于单词的编码类型,包括是否要使用预训练权重)……以便获得主要的输出数据集准备,即“X”输入张量……而不是经历这些繁琐的代码行!

    ——无论如何,我完成了它,得到了以下结果

    ——我使用一个基本的ML模型(非深度学习)在评估中获得了100%的准确率,该模型通过keras的“texts_to_matrix()”进行词编码,但使用2D的X数据集输入(10个不同的文档样本行和2个不同的vocab_size选项50(您的)甚至更少(15),与其中使用的词语更少相关)。我使用了一个全连接模型,包含2个Dense层(输出层和前一个10个节点的层)。

    ——我还获得了100%的准确率,但现在使用的是带有“one_hot()”编码(您建议的)的DL嵌入层,而不是GloVe预训练权重,并且除了嵌入层之外,我还添加了Conv1D层、MaxPool1D和Flatten层(CNN部分!)。我使用了一个2D的X张量,其中有两个选项作为特征列,最大长度为4,甚至后来应用了50个词汇列特征(使用“pad-sequences()”方法)。我随后使用可训练的GloVe预训练权重(设置为False和True)训练嵌入层。以及相同的全连接头模型(带有2个Dense层)。

    ——作为第三个主要选项,我也获得了100%的准确率,但使用的是带有keras的“texts_to_sequences()”编码方法的DL嵌入层,并且针对两个选项(最大长度和应用50个词汇量(在应用pad_sequences()之后))。我还使用GloVe训练嵌入(可训练为false和可训练为true),以及不使用GloVe权重。并且头部模型使用相同的全连接模型。

    我的结论是,最稳定和最快达到最大水平的方法是应用带有预训练GloVe(trainable = true)的嵌入层,并使用编码“texts_to_sequences()”。我通过减少50个epochs或者在我的第二个Dense层中使用更少的单元来获得相同的100%准确率来衡量最佳性能。

    致敬

    我希望这能帮到Jason!

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

      精彩的总结!

      是的,在过去的3-4年里,文本数据准备可能已经取得了长足的进步,自从我写下这些东西以来。

  170. JG 2020年6月24日 晚上9:43 #

    是的……我认为“spaCY”……是新的强大机器学习/深度学习NLP库之一

    https://spacy.io/

  171. Vivek 2020年6月25日 凌晨3:06 #

    嗨 Jason

    好文章!我想对这个有更清楚的了解

    我们为什么要设置 trainable = False?

    如果我们想使用嵌入矩阵中存在的 GloVe 100-D 权重,我们不应该将其设置为“True”吗?

    我不太明白将其设置为“True”和“False”之间的区别

    谢谢
    维韦克

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

      这意味着如果设置为“False”,集合中的权重在训练期间无法更改。也就是说,无法进行训练。

  172. Murat Karakaya 2020年7月13日 晚上9:41 #

    我认为这里有一个错别字:“例如,下面我们定义一个词汇量为200的嵌入层(例如,从0到199(包含0和199)的整数编码单词),……”因为,既然0(零)用于填充,单词是从1(不是零!)到199(包含1和199)编码的。此致,

    • Jason Brownlee 2020年7月14日 上午6:20 #

      错别字是什么,您能详细说明一下吗?

  173. Fa 2020年7月21日 凌晨3:32 #

    对于多标签分类器,其中每个文本可以链接到一个或多个主题,上述示例需要进行哪些更改?

    例如,假设我有一个主题列表,如 [“politics”, “sports”, entertainment”, “finance”, “health”]。

    一篇提到医疗保健和立法的文档将被标记为 [1,0,0,0,1]。

    将“y”标签编码为上述二进制数组格式是否足够?

    • Jason Brownlee 2020年7月21日 上午6:12 #

      通常在多分类中,我们会对标签进行整数编码,然后进行one-hot编码,并在输出层使用softmax激活函数。

  174. Ramesh Ravula 2020年7月27日 晚上9:09 #

    在“学习嵌入的例子”部分,为什么是8维?

  175. Keshav Rawat 2020年8月1日 下午6:11 #

    你好,

    在预训练GloVe嵌入部分,您使用了 vocab_size = len(t.word_index) + 1。

    为什么加1?我不明白原因。

    • Jason Brownlee 2020年8月2日 上午5:40 #

      为索引0留出空间,0表示未知词,所以词汇从索引1开始。

  176. dvl 2020年8月4日 晚上11:10 #

    嗨,Joson Brownlee,
    您认为哪种更好?

  177. Ramki 2020年8月10日 下午1:06 #

    是否有适用于日志文件(syslogs、应用程序日志等)的良好词或标记嵌入模型?

    您能否推荐一些关于日志文件机器学习应用的链接?例如:
    – 日志文件是否包含敏感数据?例如个人数据、IP地址等拓扑数据?
    – 日志文件中包含哪些类型的敏感数据?

    • Jason Brownlee 2020年8月10日 下午1:38 #

      我建议为您的特定数据集训练一个模型。

  178. SJ 2020年8月11日 凌晨3:11 #

    我可以在哪里获取全部代码?

  179. Andre 2020年8月27日 下午1:14 #

    你好 jason,

    您能给我一些关于这篇论文的见解吗 https://www.researchgate.net/publication/327173446

    我的意思是,当他们将模型的输出用于NCRF++时,我有一些困惑,他们说:“为了将实例转换为嵌入,使用了两个特征,即MNN的sigmoid输出(fe1),以及大小为30的字符嵌入(fe2)”。他们是什么意思以及如何实现?

    也许如果您有一些关于使用NCRF++进行序列标记的教程,那将非常有帮助。谢谢您。

    • Jason Brownlee 2020年8月27日 下午1:38 #

      这是我在这里回答的一个常见问题
      https://machinelearning.org.cn/faq/single-faq/can-you-explain-this-research-paper-to-me

      • Andre 2020年8月27日 下午4:55 #

        啊,抱歉,让我解释一下。

        长话短说,作者使用了一个深度学习模型,其输出是 sigmoid 概率。

        然后作者将其输入到NCRF++中,作者说“为了将实例转换为嵌入,使用了两个特征,即MNN的sigmoid输出(fe1),以及大小为30的字符嵌入(fe2)”。

        基本上我想问的是,你有没有关于NCRF++如何工作的文章?谢谢

  180. Elvin Aghammadzada 2020年9月13日 上午7:49 #

    各位,请考虑为网站添加深色模式(主题)

  181. MATHAV RAJ J 2020年9月17日 下午6:37 #

    你好,我正在尝试在 Keras 中连接两个嵌入层,一个将是固定的,另一个将进行训练,
    model = Sequential()
    fixed_weights = np.array([word2glove[w] for w in words_in_glove])

    e1 = Embedding(input_dim = fixed_weights.shape[0], output_dim = EMBEDDING_DIM, weights = [fixed_weights], input_length = MAX_NEWS_LENGTH, trainable = False)

    e2 = Embedding(input_dim = len(word2index) – fixed_weights.shape[0],output_dim = EMBEDDING_DIM, input_length = MAX_NEWS_LENGTH)
    # model.add()
    model.add(concatenate([e1, e2]))

    但这似乎不成功,我收到错误,('NoneType' object is not subscriptable).. 您能指导我哪里错了吗?

    • Jason Brownlee 2020年9月18日 上午6:42 #

      也许可以为模型设置2个输入,每个输入一个嵌入层和LSTM,然后连接LSTM的输出。

  182. singularityISnear 2020年9月25日 晚上7:44 #

    嗨,我想编写一个通用的python函数来构建一个模型,该模型既适用于自定义嵌入层,也适用于GloVe的预训练嵌入。

  183. Par 2020年9月30日 下午2:05 #

    嗨,Jason,

    感谢这些精彩的教程。总是很有帮助。

    我有一个问题。我正在尝试从一些带注释的症状(来自对话)中提取特征。所以我的序列是“头痛程度重,头痛频率有时”,每个序列长度不同,并分配了一个时间点。

    我想提取特征,以便稍后用于时间序列分类(所以在扁平化之后,我将添加一个大小为100的密集层)。问题是我不想在这里使用相同的标签进行嵌入(在model.fit中)。我担心当我使用这些特征训练主分类器时,会与包含这些样本的时间点分配相同的标签,这会导致偏差。

    有没有办法在不为每个样本分配标签的情况下进行嵌入?

    谢谢你,

    • Jason Brownlee 2020年9月30日 下午2:16 #

      也许你可以使用独立的doc2vec技术,例如独立的word2vec方法的等效物。

  184. Cre 2020年10月28日 上午9:01 #

    嗨,Jason,
    关于准确率和预测方法的一个简短问题。当我使用
    model.predict(pad_sequences([one_hot(‘poor work’, vocab_size)], maxlen=max_length, padding=’post’))
    我得到的输出是 0.5076578 {array([[0.5076578]], dtype=float32)},根据我的理解,这意味着它既不好也不坏。如果我运行 model.evaluate,我得到的准确率是 100%,但这不可能是真的,因为“poor work”在我的测试集中,我得到的分数是 0.50…而不是 0。
    这怎么可能?

    非常感谢

  185. Mahesh Chauhan 2020年10月29日 下午3:56 #

    谢谢 Jason,
    运行2-3次后,我能够像你说的达到100%的准确率。

  186. Tanmay 2020年11月6日 晚上8:53 #

    嗨,Jason,

    我正在尝试使用此代码训练后预测输出。当我查看输出时,它总是预测 [[0.72645265]]。为什么会这样?

    我使用以下模型调用进行预测:
    output = model.predict(padded_docs)

    以下是获取 padded_docs 的代码:
    t = Tokenizer()
    t.fit_on_texts([“good job”])
    vocab_size = len(t.word_index) + 1
    encoded_docs = t.texts_to_sequences(docs)
    max_length = 4
    padded_docs = pad_sequences(encoded_docs, maxlen=max_length, padding=’post’)

    还是我哪里出错了?我不确定应该在 predict() 中传递什么。

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

      看起来不错,它正在预测文档属于类别1的概率。

      例如,P(class=1) = 70%

      更多关于使用 Keras 模型进行预测的信息,请参见此处
      https://machinelearning.org.cn/how-to-make-classification-and-regression-predictions-for-deep-learning-models-in-keras/

      • Tanmay 2020年11月8日 凌晨5:44 #

        是的,进展顺利。但并非所有情况都如此。当我在输入“poor job”上进行测试时,它预测的输出与“[[0.72645265]]”相同(所有测试用例都相同)。我想我提供了错误的输入,每次都只是填充数据([[1,2,0,0]]),而不是确切的单词。我应该如何为model.predict()函数构建输入?

        • Jason Brownlee 2020年11月8日 上午6:43 #

          新的输入数据必须以与训练数据集相同的方式准备——相同的编码、词汇等。

          • Juan 2020年12月14日 中午12:15 #

            我也有同样的错误,您能向我们展示正确预测的代码吗?

          • Jason Brownlee 2020年12月14日 下午1:36 #

            抱歉,我不明白。您具体遇到了什么错误?

          • Juan 2020年12月14日 下午2:45 #

            我回答我自己和Tammay

            try=[“太棒了!”]
            encoded_try = t.texts_to_sequences(try)
            padded_try = pad_sequences(encoded_try, maxlen=4, padding=’post’)
            model.predict(padded_try)

            只有经过训练的词才有效***

            贾森的博客很棒,下次也请像评估模型一样,我们是新手????

            psdt:(问题是我们不知道如何评估文本“model.predict”,因为我们总是认为结果相同)

  187. Pratik Sen 2020年11月12日 凌晨5:21 #

    你好,
    嵌入层的输出是3D(参考:https://tensorflowcn.cn/api_docs/python/tf/keras/layers/Embedding),但您的博客中写道输出是2D

    • Juan 2020年12月14日 下午2:42 #

      我回答我自己和Tammay

      try=[“太棒了!”]
      encoded_try = t.texts_to_sequences(try)
      padded_try = pad_sequences(encoded_try, maxlen=4, padding=’post’)
      model.predict(padded_try)

      只有经过训练的词才有效***

      杰森的博客很棒,下次也请像评估模型一样,我们是新手 😉

  188. Dipankar Porey 2020年11月14日 晚上11:32 #

    模型中的嵌入层是什么意思?

    • Jason Brownlee 2020年11月15日 上午6:26 #

      抱歉,我不明白您的问题,您能详细说明一下吗?

  189. Dipankar Porey 2020年11月14日 晚上11:34 #

    我的意思是为什么我们在模型中使用嵌入层????

  190. Sheema Egbert 2020年11月19日 凌晨1:04 #

    嗨,Jason,感谢您精彩的教程。

    您如何向嵌入添加偏差?

    提前感谢

    • Jason Brownlee 2020年11月19日 上午7:46 #

      不客气!

      您说的“向嵌入添加偏差”是什么意思?

  191. Sheema Egbert 2020年11月20日 下午3:16 #

    我的意思是,在您训练嵌入时,为每个学习到的嵌入设置一个单一的偏差项是否有利?

    感谢您的关注!

  192. Sheema Egbert 2020年11月21日 下午3:45 #

    感谢Jason澄清了这一点。

  193. Puneesh Khanna 2020年12月10日 下午4:38 #

    嗨,Jason,
    有没有办法将2D输入转换为嵌入。基本上,我有一个表示图的邻接矩阵(2D数组),并且训练将发生在批量图作为数据点上。有没有办法可以将图的每个节点(基本上由邻接矩阵中的每一行表示)转换为更有意义的嵌入?

  194. vian 2020年12月12日 凌晨3:36 #

    谢谢,Jason先生,请帮助我。
    1- 如果我每句话只有一个词,并且它们之间没有关系,那么我如何表示类别标签,我真的不知道这里类别标签有什么好处?
    2- 嵌入过程背后的数学模型是什么?

  195. SULAIMAN KHAN 2020年12月29日 晚上10:54 #

    预训练意味着测试数据

    • Jason Brownlee 2020年12月30日 上午6:38 #

      不。预训练是指使用不同的算法进行训练,并生成一个独立的模型,该模型可以用作后续模型(如神经网络)的一部分。

  196. Arwinder Singh 2021年1月3日 凌晨2:39 #

    你好……我想将隐藏状态与词嵌入连接起来……我们怎么做呢?

    • Jason Brownlee 2021年1月3日 上午5:57 #

      也许可以尝试在keras中使用合并或连接层,看看是否能达到您想要的效果?

      • Arwinder Singh 2021年1月3日 下午3:48 #

        谢谢……我试了以下方法,结果出现维度错误

        latent_dim=128
        encoder_inputs = Input(shape=(None,))
        enc_emb = Embedding(eng_vocab_size, latent_dim, mask_zero = True)(encoder_inputs)
        encoder_lstm = LSTM(latent_dim*4, return_sequences=True, return_state=True)
        encoder_outputs, state_h, state_c = encoder_lstm(enc_emb)
        state_h=Concatenate()([state_h,enc_emb])
        encoder_states = [state_h, state_c]

        错误是
        ValueError: 一个`Concatenate`层需要输入具有匹配的形状,除了连接轴。得到的输入形状为:[(None, 512), (None, None, 128)]

  197. Anil Rahate 2021年1月10日 凌晨4:21 #

    嗨,Jason,我正在尝试理解如何提取嵌入特征?例如,对于每个训练样本,我如何获取文本特征(例如300维x 50序列长度)。这样我就可以在序列模型中不需要使用嵌入层,并且可以直接使用LSTM和其他层。任何指导都会非常有帮助。

    • Jason Brownlee 2021年1月10日 上午5:46 #

      每个单词都被映射到一个向量。直接检索您单词的向量。

  198. vycki 2021年1月11日 晚上9:32 #

    你好,如果我有一个包含30万个句子的文档,并且文档中最长的句子有451个单词,那么嵌入层中的vocab_size和input_length会是多少?我还是不太明白。

    • Jason Brownlee 2021年1月12日 上午7:51 #

      您可以选择词汇量和单词数量。

      它可以任意选择,也可以根据从您的数据中计算出的摘要统计数据选择。

  199. Patrick 2021年1月18日 下午2:08 #

    不知道嵌入的底层算法,让人费解输出维度可以是任意大小。

    请告诉我 input_length 实际上应该是最长句子的长度。如果 input_length 可以填充到超过最长句子,我不会感到惊讶,但那有什么意义呢?

    • Jason Brownlee 2021年1月19日 上午6:32 #

      没有算法——它只是词汇表中每个词的权重向量,这些权重在训练期间像网络中的任何其他权重一样更新。

      输入长度是您希望在样本中传入的单词数量。它可以随心所欲地短或长,并用零填充以使其具有相同的长度。

      也许可以进行实验,找出最适合您的数据集和模型的方案。

  200. Ebtesam Almansor 2021年1月19日 下午3:36 #

    Keras中嵌入层和Elom嵌入有什么区别???

  201. Ebtesam Almansor 2021年1月20日 上午11:49 #

    那,准确率是为了什么?
    我将它们用于分类问题

  202. Dinesh 2021年1月20日 下午5:03 #

    你好 jason,
    您将词汇量解释为:“这是文本数据中词汇量的大小。例如,如果您的数据被整数编码为0-10之间的值,那么词汇量的大小将是11个单词。”

    请向我解释一下词汇和词汇量。

    您在词汇量的解释中提到了“整数编码”。但是当我们使用整数编码时,它会基于我们数据中的单词数量,对吗?那么为什么我们将其设置为200呢?请向我解释一下。我是机器学习新手,如果我的问题很傻,请原谅。

    谢谢你

    • Jason Brownlee 2021年1月21日 上午6:44 #

      词汇表是模型已知词的数量,每个词都有一个您分配的唯一编号。

      哪一部分让您感到困惑?

  203. Dinesh 2021年1月21日 下午4:54 #

    感谢您的善意回复。

    我的疑问是,在上面的例子中,“doc”有12个独特的词。那么我们为什么将“vocab_size”设置为50呢?词汇量是基于数据中存在的词的数量吗?
    50这个值是怎么来的?
    请给我举例解释一下词汇量是什么。

    谢谢你

  204. Lele 2021年1月30日 凌晨5:35 #

    你好,

    一个疑问:在给出的例子中,嵌入层有“vocab_size”x 8 = 400个参数。

    就好像我们有50个输入和8个处理单元(向量)。

    当向嵌入层提供一串不同的词(长度=4,如例子所示)作为输入时,我们是否只会“激活”嵌入层的32个权重?

    32 = 4(输入字符串中的单词数)x 8(向量的维度)

    • Jason Brownlee 2021年1月30日 上午6:41 #

      如果您提供一个包含4个单词的序列,并且嵌入的维度是8,那么嵌入将为每个单词输出一个8元素的向量,例如一个4x8矩阵。

  205. ADITYA GHOSH 2021年2月13日 晚上9:10 #

    如果在分词器中添加 oov_token='UNK',我仍然需要添加 ,vocab_size = len(t.word_index) + 1 吗?

    t=tf.keras.preprocessing.text.Tokenizer(
    filters='!"#$%&()*+,-./:;?@[\\]^`{|}~\t\n',
    lower=True, split=' ', char_level=False,oov_token='UNK'

    )

    • Jason Brownlee 2021年2月14日 凌晨5:06 #

      是的,0总是保留给未知/缺失的,无论您是否使用它。

  206. Marco Cetraro 2021年3月2日 凌晨6:25 #

    你好 Jason,

    非常感谢您的精彩文章。

    我几乎查看了这篇文章中的所有问题和答案,我注意到有好几个人问了和我一样的问题,但您的答案与他们所问的问题无关。

    你提到了
    “该模型是一个简单的二元分类模型。重要的是,嵌入层的输出将是4个8维向量,每个向量对应一个单词。”

    我明白8个维度是一个任意的数字。但我不明白的是4个向量是什么意思?如果文档有10个,每个文档都被翻译或转换为一个4维向量,为什么嵌入层的输出会是4个向量呢?

    谢谢你。

    • Jason Brownlee 2021年3月2日 上午8:13 #

      文档不会被翻译成向量,单词会被翻译成向量。每个单词都将是一个长度为8的向量,文档将是由这些向量组成的矩阵。10个文档将是10个这样的向量矩阵。

      这有帮助吗?

      运行代码,亲眼看看!

  207. MS 2021年3月22日 凌晨12:24 #


    在GloVe嵌入的情况下,我们可以使用Tf-idf向量化器或ohe来将字符转换为向量,而不是test_to_sequence()吗?

    • Jason Brownlee 2021年3月22日 凌晨5:30 #

      当然,试试看,然后比较结果。

      • MS 2021年3月22日 晚上9:36 #

        谢谢

  208. David 2021年3月23日 晚上7:49 #

    非常感谢Jason,您的博客文章写得非常精彩。

  209. Harsha 2021年3月31日 晚上8:59 #

    例如,我有一个数据框,假设有3列:评论、有趣与否、积极或消极。我将评论列转换为填充序列列,使用该列从Word2Vec获取结果嵌入矩阵,并将“有趣与否”列二值化。好的,现在除了填充序列之外,我如何将另一列作为特征发送到我的模型?

    • Jason Brownlee 2021年4月1日 上午8:13 #

      抱歉,我没听懂你的问题。

      也许你可以总结或重新表述一下?

  210. Meriem 2021年4月22日 上午11:59 #

    谢谢你,Jason!!

    那么,一般来说(不只针对文本),当我们使用Keras中的嵌入层将类别特征转换为数值向量时,是只需在我们的主机器学习模型中添加一个嵌入层(且嵌入层只转换类别特征)吗?还是我们分别训练两个不同的模型,第一个模型带嵌入层用于生成数值特征(转换类别特征),第二个模型用于预测(我们的主要问题),我们将嵌入作为特征输入?

    谢谢!

    • Jason Brownlee 2021年4月23日 上午4:57 #

      不客气。

      是的,嵌入只是将序数编码值转换为实值向量,适用于任何你喜欢的模型。神经网络允许你将嵌入作为模型的一部分进行训练。

  211. Mitra 2021年4月26日 下午2:34 #

    您好,感谢您创建了出色的博客。我有一个关于嵌入来源的问题。考虑到像BERT这样的模型学习上下文嵌入,我们有没有可能在翻译模型中使用它们的tokenizer和嵌入?我已经针对我的特定领域数据预训练了波斯语BERT模型,现在我想知道是否可以在翻译模型中使用这些嵌入。

  212. RESEENA MOL 2021年4月30日 下午5:00 #

    先生,
    当我尝试运行这段代码时,我得到了这个错误。这段代码有什么问题?提前感谢。
    embeddings_index = dict()
    f = open(‘glove.6B.100d.txt’, ‘r’, errors = ‘ignore’, encoding=’utf8′)
    for line in f
    values = line.split()
    word = values[0]
    coefs = asarray(values[1:], dtype=’float32′)
    embeddings_index[word] = coefs
    f.close()
    print(‘Loaded %s word vectors.’ % len(embeddings_index))

    TypeError Traceback (most recent call last)
    in ()
    4 values = line.split()
    5 word = values[0]
    —-> 6 coefs = array(values[1:], dtype=’float32′)
    7 embeddings_index[word] = coefs
    8 f.close()

    TypeError: array.array() takes no keyword arguments

  213. Alok 2021年6月18日 晚上8:04 #

    嗨,感谢您精彩的博客。有没有办法验证我的嵌入效果如何?

    • Jason Brownlee 2021年6月19日 上午5:51 #

      也许可以在模型中使用它,并比较使用和不使用它,或者使用不同编码/嵌入的模型性能。

  214. Amardeep 2021年7月11日 上午5:00 #

    我正在研究结合数值和文本特征进行预测的方法。有没有办法通过神经网络利用词嵌入来实现这一点?

  215. Radhika 2021年7月20日 上午2:12 #

    你好 Jason,

    感谢您写得如此精彩的文章。关于第三种情况,我有一个问题:
    “如何在神经网络中使用预训练词嵌入”

    在本教程中,我们使用GloVe词嵌入作为嵌入层的“权重”。我们能否改为用相应的GloVe词嵌入来表示/编码输入(训练数据)中的每个词,然后训练神经网络?在这种情况下,我们根本不需要嵌入层了,对吗?

    • Jason Brownlee 2021年7月20日 上午5:35 #

      不客气。

      是的,这是同一个意思。嵌入要么直接在模型中使用,要么作为输入数据的预处理。都是一样的。

      • Radhika 2021年7月21日 上午12:56 #

        谢谢你的回复!我会试试看的!

  216. saba 2021年8月9日 上午4:07 #

    嗨,Jason,
    我正在使用BERT进行词嵌入,我正在对新闻标题进行情感分析,并将数据分为积极和消极两类。只使用CLS token的嵌入然后进行分类可以吗?我正在使用带有BERT嵌入的SVM分类器。我得到了84%的准确率,这不是我想要的,我想要更高的准确率。有没有其他的解决方案会很感激。谢谢。

    • Jason Brownlee 2021年8月9日 上午5:59 #

      也许可以尝试替代的嵌入方式、替代的数据准备方式、替代的预测模型和配置等。

  217. Parita Shah 2021年8月11日 晚上9:43 #

    Keras 提供了 one_hot() 函数,它将每个单词哈希为一个高效的整数编码。我们将估计词汇量大小为 50,这比所需的大得多,以减少哈希函数冲突的可能性。

    对于上面的句子,我不明白为什么在词汇量大约为15的时候,我们却取了50的词汇量大小?您能用通俗易懂的方式解释一下吗?我们总是需要取比实际词汇量大的值吗?

    • Adrian Tam
      Adrian Tam 2021年8月12日 上午5:55 #

      词汇量应该足够大,以捕捉数据集的复杂性。

  218. Francesco 2021年8月28日 上午2:27 #

    你好,Jason,感谢你的教程,它们对我帮助很大。我有一个关于你在本教程中解决的问题的疑问。
    我正在做一个文本摘要的项目,我有一个数据框,包含两列:第一列是文本,第二列是摘要。我想在将文本输入到我的seq2seq模型进行摘要之前学习词嵌入(我想为嵌入创建一个单独的模型,否则一个模型要学习的参数太多了)。

    在预处理阶段,我对文本和摘要都进行了独热编码,然后进行了填充。现在每个文本序列的长度为462,而每个摘要序列的长度为140。

    我的问题是:既然我想学习数据集中所有词汇的嵌入,我是否需要拉伸摘要序列的长度,使其达到462,以便所有序列都具有相同的长度并可以输入到嵌入模型中?

    • Adrian Tam
      Adrian Tam 2021年8月28日 上午4:12 #

      通常你需要进行你所描述的对齐,但有很多方法可以做到。填充(Padding)是其中之一。如果你有Word2Vec嵌入,你也可以对每个单词的向量求和,这样无论你的句子有多长,你都会得到一个长度为N的词向量,而不是长度为462或140。我相信你可以想到许多不同的方法。这里由你来决定选择的方法并给出理由。

  219. Arwa 2021年9月2日 上午1:51 #

    亲爱的朋友您好,
    感谢您的本教程

    我尝试了代码,但最终陷入了我想要解决的问题,我有疑问

    问题是:比较两个句子,看它们是否具有相同的含义
    所以训练数据包括 [句子1, 句子2],以及标签 [0 或 1]

    1- 我从训练数据和测试数据中提取词嵌入,这是正确的吗?
    2- 如何将输入传递给模型,我找到的所有方法都只传递一个文档/句子
    但我需要传递两个句子

    你能帮忙吗?

  220. Arwa 2021年9月2日 晚上8:14 #

    非常感谢您的回复

    是的,我已经做了词嵌入,我的数据集已经准备好了,但我卡在了模型的拟合上!!
    如何输入两个嵌入的句子?
    我的数据看起来像这样
    x_trine_data = [ [ [0.2 , 0.3, 0.9], [0.7, …,],[…],..] [ [0.4,0.3..],[0.32,..] ] ]
    其中
    x_trine_data[0] 代表 sen1
    x_trine_data [1] 代表 sen2

    sen1 sen 2 标签
    [0] hello word there [0]welcome to class 0
    [1] A went to school [1] A in the school 1

    ....

  221. Syed Ali Raza Hamdani 2021年9月11日 晚上11:11 #

    Francois Chollet 图61 从文本到标记到向量,其中有零点,不理解零点

  222. Sergey 2021年9月14日 晚上10:06 #

    非常感谢本教程!解释得简单明了!

    • Adrian Tam
      Adrian Tam 2021年9月15日 晚上10:57 #

      很高兴你喜欢。谢谢。

  223. Sourabh 2021年9月18日 晚上7:42 #

    嗨,我不太理解嵌入层如何将权重矩阵映射到其各自的键(单词)。另外,您传递给padded_docs模型中,但GloVe向量单词中不存在的单词怎么办?

    • Adrian Tam
      Adrian Tam 2021年9月19日 上午6:42 #

      对于预训练向量中未知的单词,你可以预定义一个替换嵌入(或者你可以在查找嵌入之前进行一些预处理来替换这些未定义的单词)。

  224. Julia 2021年10月6日 上午4:40 #

    嗨,Jason!
    感谢您的本教程。
    我的问题是:Keras 嵌入层只能用于文本数据吗?

    谢谢!

    • Adrian Tam
      Adrian Tam 2021年10月6日 上午11:29 #

      并非仅限于文本数据,但英语单词最容易,因为有很多可供下载的嵌入数据。但从技术上讲,这并不意味着它是唯一的应用。只要你能够证明其合理性,你可以将嵌入层用于任何事物。

  225. Rania 2021年11月13日 上午2:49 #

    亲爱的布朗利博士,

    我想感谢您的宝贵文章,我确实学到了很多。

    我的问题是:我们可以像使用GloVe一样使用FastText预训练嵌入吗?

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

      应该可以。只是维度会不同。

  226. Raja 2021年12月29日 下午4:24 #

    谢谢Jason,这篇好文章。我有以下疑问

    # 整数编码文档
    vocab_size = 50
    # 将文档填充到最大长度为 4 个单词
    max_length = 4

    该方法难道不能自动找出输入中词语的总数并决定vocab_size吗?我们可能不知道实际的vocab_size,因此可能会提供错误的值。例如,我们可能传入5而不是50。这样许多词语就可能具有相同的数字。

    同样,填充最大长度,该方法难道不能根据每个句子中的词语数量来找出吗?就像上面提到的,我们传入这个值时也可能会犯错误。

    请对此阐明一下。谢谢。

    • James Carmichael 2022年2月28日 下午12:13 #

      嗨,Raja……请您缩小问题范围或提供更具体的疑问,以便我们更好地协助您。

  227. sam 2022年1月1日 上午12:46 #

    谢谢Brownlee博士的这篇很棒的博客。我使用glove作为字幕模型中的嵌入层,通过获取嵌入矩阵,但如果我需要使用BERT,我该如何开始,请指教。

  228. Will 2022年1月6日 晚上11:54 #

    嗨 Jason

    我很困惑为什么第三节中嵌入层的输出是4乘8?

    如果句子是1乘4的向量,而嵌入矩阵是8乘50的矩阵,
    如果我们将它们相乘,您不会得到一个4乘8的矩阵,您会得到一个错误,因为它混淆了矩阵乘法的定律。

    那么输出维度为什么会是这样呢?我肯定我遗漏了一些东西!非常感谢。

  229. Dev 2022年3月10日 晚上9:43 #

    正是我在找的!爱你,老兄!

    • James Carmichael 2022年3月11日 下午1:01 #

      太棒了 Dev!

  230. zi 2022年5月13日 上午2:49 #

    在这个例子中,
    这有点像迁移学习,对吗?

  231. Majida 2022年9月14日 晚上6:44 #

    嗨,Jason,

    请指导——我如何将预训练词嵌入模型用于那些在预训练模型中不可用的本地语言?或者我是否必须使用一个嵌入层来生成嵌入矩阵?

    我如何从预训练模型中受益于本地语言?

    • James Carmichael 2022年9月15日 上午5:39 #

      嗨,Majida……请您澄清“本地语言”的含义,以便我们更好地协助您。

  232. Majida 2022年9月20日 下午1:29 #

    你好,感谢你的善意回复。

    英文句子:“He is a good boy”
    罗马乌尔都语:“ye acha larka ha”

    “ye”表示“he”。
    “ha”表示“is”。
    “acha”表示“good”
    “larka”表示“boy”。

    实际上,这不是巴基斯坦、印度和世界各地所说的正宗乌尔都语。但这种写法在社交媒体用户中很流行。
    此致

  233. Silvio 2022年9月20日 下午4:47 #

    嗨 Jason

    tf.keras.preprocessing.text.one_hot 已被弃用,建议使用 tf.keras.layers.Hashing 并设置 output_mode=’one_hot’。
    但我使用时,它显示:“('Keyword argument not understood:', 'output_mode')”

    你有什么想法吗?
    谢谢

    • James Carmichael 2022年9月21日 上午5:28 #

      嗨,Silvio……请您澄清您所指的建议来源和错误,以便我们更好地协助您。

  234. Subodh 2022年10月31日 上午2:55 #

    你好!我正在构建一个模型,使用嵌入层后接 GlobalAveragePooling1D() 层和其他层,如下所示:

    tf.keras.layers.Embedding(vocab_size=10000, embedding_dim=300, input_length=16),
    tf.keras.layers.GlobalAveragePooling1D(),
    tf.keras.layers.Dense(32, activation=’tanh’),
    tf.keras.layers.Dense(16, activation=’tanh’),
    tf.keras.layers.Dense(1, activation=’sigmoid’)

    我的理解是,在嵌入层之后,后续层获取相应单词的数据或特征向量。然后,该特征向量用于其他层中的进一步处理。因此,嵌入层本身足以生成特征向量。

    但从这篇文章(尽管信息量很大)中,我的理解是,为了生成特征向量,它需要通过所有其他层传播。如果数据通过整个层来生成特征向量,那么该特征向量是如何使用的呢?

    我的另一个问题是,如果我使用RNN层,我是否必须使用嵌入层?

  235. Iraj Koohi 2022年11月24日 上午9:03 #

    很棒的文章,谢谢。
    例如,下面我们定义了一个嵌入层,其中词汇表大小为 200(例如,整数编码的词语从 0 到 199,包括在内),词语将被嵌入的向量空间为 32 维,输入文档各有 50 个词。
    关于嵌入层的以下设置
    e = Embedding(200, 32, input_length=50)
    如果我们想同时处理三个独立的输入而不是上面一个输入,嵌入层或层的设置会是怎样?
    例如,我有三个输入,每个输入都有100个词汇量大小?

  236. Iraj Koohi 2022年11月24日 上午9:17 #

    为了澄清我的问题:
    我有三个子地址,每个都是唯一的整数0-99,这三个的组合将构成一个唯一的地址。我没有使用一个带有100*100*100=1000000个输入的密集层,而是使用了三个嵌入层,每个嵌入层都在输入层之后,并且是相同的。接下来将嵌入层的输出连接起来,最后处理密集层的输出。
    我的问题是,我是否可以使用单个密集层?如果可以,密集层的设置会是怎样的?
    谢谢

  237. Tao 2022年11月29日 上午8:48 #

    已知:每个案例最多3个单词,嵌入大小=8。展平后,每个案例最终将有3 x 8 = 24个“特征”用于模型中的任何下游架构。

    考虑句子“cat sat mat”、“mat cat sat”、“sat mat cat”等。每个句子都有相同的24个特征,只是顺序/块不同。

    这似乎意味着“特征X”或“列X”在概念上并不是逐案相同的。例如,有时特征9是CAT的第一个潜在嵌入值,有时是SAT的第一个潜在嵌入元素,有时是MAT的。这与标记无关,而与该案例中“恰好存在”(词袋)的标记有关。

    这些24个新特征的下游学习如何获得一致的结果?我觉得我遗漏了一些概念上的东西。

    谢谢
    Tao

  238. Sandeep 2024年3月12日 晚上11:23 #

    如果我使用 tokenizer = Tokenizer(oov_token = oov_token),那么我就不必将 vocab_size 加 1 了……对吗?

    • James Carmichael 2024年3月13日 上午8:59 #

      嗨,Sandeep……请您继续您的想法,并告诉我们您的发现。

  239. KSaeed 2024年6月1日 晚上9:37 #

    您好 Jason 和团队,

    我正在尝试在训练数据集(Ubuntu对话语料库)上实现动态嵌入,而不是使用预训练的GloVe/Word-2-vec嵌入。我的目标是创建能够不仅仅一次(即,最初在嵌入层)学习的嵌入,而且通过整个NLP模型反向传播的权重可以用于更新嵌入层本身的初始嵌入。

    您的文章中标题为“学习嵌入的示例”的第3节是否是正确的起点?

    • James Carmichael 2024年6月2日 上午4:52 #

      嗨 KSaeed……是的,实现可以通过反向传播更新的动态嵌入是现代NLP模型中的一种基本方法。如果文章中“学习嵌入的示例”的第3节涵盖了动态创建和更新嵌入的过程,那么它确实是一个很好的起点。以下是更详细的解释和步骤,以帮助您实现此功能:

      ### 实施动态嵌入的步骤

      1. **准备数据集:**
      – 预处理 Ubuntu 对话语料库:对文本进行分词,处理词汇表外单词,并创建词汇索引。

      2. **初始化嵌入层:**
      – 不使用预训练嵌入,而是用随机权重初始化嵌入层。
      – 这可以使用 TensorFlow 或 PyTorch 等库完成。例如,在 PyTorch 中:
      python
      import torch.nn as nn
      embedding = nn.Embedding(num_embeddings=vocab_size, embedding_dim=embedding_dim)

      3. **构建 NLP 模型:**
      – 创建您的 NLP 模型,该模型将包含嵌入层作为第一层。嵌入将在训练期间更新。
      – 例如,一个简单的模型可能看起来像这样:
      python
      class NLPModel(nn.Module):
      def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim):
      super(NLPModel, self).__init__()
      self.embedding = nn.Embedding(vocab_size, embedding_dim)
      self.rnn = nn.LSTM(embedding_dim, hidden_dim)
      self.fc = nn.Linear(hidden_dim, output_dim)

      def forward(self, x):
      embedded = self.embedding(x)
      output, (hidden, cell) = self.rnn(embedded)
      return self.fc(hidden[-1])

      4. **训练模型:**
      – 定义损失函数和优化器。交叉熵损失通常用于分类任务。
      python
      criterion = nn.CrossEntropyLoss()
      optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

      – 通过前向传播输入、计算损失、反向传播和更新权重来训练模型。
      python
      for epoch in range(num_epochs):
      for inputs, labels in dataloader:
      optimizer.zero_grad()
      outputs = model(inputs)
      loss = criterion(outputs, labels)
      loss.backward()
      optimizer.step()

      5. **更新嵌入:**
      – 在反向传播过程中,梯度将流经嵌入层,根据模型的误差动态更新嵌入权重。
      – 嵌入将变得更有意义,因为它们在训练期间会根据您的特定任务进行调整。

      ### PyTorch 示例
      这是一个完整的示例,以进行说明:

      python
      import torch
      import torch.nn as nn
      import torch.optim as optim
      from torch.utils.data import DataLoader, Dataset

      class UbuntuDataset(Dataset)
      # 用于加载 Ubuntu 对话语料库的自定义数据集
      def __init__(self, data, vocab)
      self.data = data
      self.vocab = vocab

      def __len__(self)
      return len(self.data)

      def __getitem__(self, idx)
      return self.data[idx]

      class NLPModel(nn.Module)
      def __init__(self, vocab_size, embedding_dim, hidden_dim, output_dim)
      super(NLPModel, self).__init__()
      self.embedding = nn.Embedding(vocab_size, embedding_dim)
      self.rnn = nn.LSTM(embedding_dim, hidden_dim, batch_first=True)
      self.fc = nn.Linear(hidden_dim, output_dim)

      def forward(self, x)
      embedded = self.embedding(x)
      output, (hidden, cell) = self.rnn(embedded)
      return self.fc(hidden[-1])

      # 示例数据和词汇表(替换为实际数据和预处理)
      data = [('hello how are you', 0), ('i am fine thank you', 1)]
      vocab = {'hello': 0, 'how': 1, 'are': 2, 'you': 3, 'i': 4, 'am': 5, 'fine': 6, 'thank': 7}
      vocab_size = len(vocab)
      embedding_dim = 50
      hidden_dim = 100
      output_dim = 2
      num_epochs = 5

      # 将数据转换为索引
      data = [([vocab[word] for word in text.split()], label) for text, label in data]

      dataset = UbuntuDataset(data, vocab)
      dataloader = DataLoader(dataset, batch_size=2, shuffle=True)

      model = NLPModel(vocab_size, embedding_dim, hidden_dim, output_dim)
      criterion = nn.CrossEntropyLoss()
      optimizer = optim.Adam(model.parameters(), lr=0.001)

      for epoch in range(num_epochs)
      for inputs, labels in dataloader
      inputs = torch.tensor(inputs, dtype=torch.long)
      labels = torch.tensor(labels, dtype=torch.long)

      optimizer.zero_grad()
      outputs = model(inputs)
      loss = criterion(outputs, labels)
      loss.backward()
      optimizer.step()

      print(f'Epoch {epoch+1}, Loss: {loss.item()}')

      通过遵循这些步骤,您将能够创建并动态更新特定于您的数据集和任务的嵌入,从而提高您的 NLP 模型的性能。

  240. KSaeed 2024年6月2日 下午5:13 #

    谢谢 James!这非常有帮助,我一定会尝试一下并告诉您性能!

发表回复

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