【问题标题】:How to train my own custom word embedding on web pages?如何在网页上训练我自己的自定义词嵌入?
【发布时间】:2019-01-24 04:19:44
【问题描述】:

我在多个网页上有大量关于我有兴趣出售给客户的产品的文本数据。我尝试使用在 Wikipedia 上训练的预训练 fasttext 词嵌入,但它并没有给我的分类任务带来好的结果。可能是因为网站上的文本数据包含很多技术细节,并且与维基百科的文本数据不同。所以我想做一些词嵌入的迁移学习,保持预训练的快速文本词嵌入为基础。

  1. 如何使用 Keras 在这些网页上训练我自己的自定义词嵌入?
  2. 如何使用 fasttext 预训练嵌入和训练初始化自定义词嵌入?这种初始化真的有助于提供更好的词嵌入吗?

我更喜欢使用 Keras 来训练词嵌入的解决方案。
我知道 Embedding 有 trainable=True 选项,不知道如何使用它。

Embedding(voc_size, emb_dim, weights=[embedding_matrix], input_length, trainable=True)

应该为此 Keras 或 Gensim 推荐哪个框架,为什么?

【问题讨论】:

    标签: python tensorflow keras deep-learning nlp


    【解决方案1】:

    我建议您使用 fastText 的 gensim 实现来训练您自己的词嵌入。这应该比您自己的 Keras 实现更容易和更快。您可以从加载预训练模型开始,然后使用您自己的数据继续训练。

    from gensim.models import FastText
    
    model = FastText.load_fasttext_format('cc.en.300.bin')
    
    data = [['Hello', 'world'], ...] # Your own training data, a list of sentences
    model.build_vocab(data, update=True)
    model.train(sentences=data, 
                total_examples=model.corpus_count,
                epochs=5)
    

    编辑:如果您想在 Keras 中实现自己的模型,您确实可以按照您的建议使用带有 trainable = True 的嵌入层(默认行为)。 There is a good guide on how to do this here.

    【讨论】:

    • +1 所以这段代码实际上是根据新的训练数据更新预训练的快速文本嵌入的权重?
    • 是的。如果您有大量数据,也可以尝试从头开始训练自己的模型。
    • 您的意思是说 Keras 默认情况下没有用于训练自定义词嵌入的类似功能,除非我使用 tensorlfow 开发自己的实现?为什么 Embeddin(trainable=True) 不起作用?
    • Keras 也适用于您建议的嵌入层。但是,您需要对数据进行更多预处理,因为您不能像在 Gensim 中那样只传递单词列表。您需要将每个单词编码为整数索引。此外,您需要创建共享相同上下文的单词对以及随机对,然后在嵌入层之上创建一个分类器来区分它们。我尝试使用 Keras 和 Gensim 训练我自己的嵌入,Gensim 的实现速度更快,实际上在我的情况下也提供了更好的嵌入。
    • 我认为 model.build_vocab(data, update=True) 行涵盖了这一点。但是我自己并没有真正尝试过,我只是尝试从头开始训练。
    【解决方案2】:
    1. 要仅训练,您必须在嵌入层中将可训练标志设置为 True。但他会从一开始就训练——
    2. 要初始化矩阵,您可以使用您考虑的矩阵,您有 这里有一个例子: https://www.kaggle.com/lystdo/lstm-with-word2vec-embeddings(在哪里 使用了 Google300Negatives 并且只使用了这样的词 它们是从原始矩阵中使用的)。在嵌入构造函数类中使用权重参数 (weights=[...])。这个矩阵的大小应该是词数 x 嵌入的维数。

    在 Keras 中,任何具有参数的层都可以训练或不可训练。 当您只想训练层的子集(仅全连接等)以避免参数爆炸时,此标志很有用。

    当你设置为trainable=true时:

    • 如果该层位于网络中间,则仅传播 输入梯度,但不校正任何权重。
    • 如果该层是网络的第一个层,则不会传播任何梯度。

    在嵌入层的情况下,您可以将此层初始化为默认嵌入矩阵(例如 gensim Gooogle300Negative)。

    当您在该层中激活可训练对象时,您将全权委托 Keras 在您考虑此嵌入时进行调整。这也意味着必须优化更多参数。

    在某些情况下,修改初始嵌入没有兴趣,要么是因为涉及的成本,要么是因为它要被保留。

    编辑: 这个任务对应于 Keras 内部的 Tensorflow。但这个原则不依赖于框架,而只依赖于理论。 当您定义一个 trainable = false 时,您表示不应该更新权重。

    这意味着中间层必须只计算相对于输入的梯度,因为其中一个权重是无用的(如果它们被计算,则什么也得不到,并且可训练标志也不存在)。因为梯度必须继续传播,所以它们相对于入口进行计算。

    第一层还具有输入是您的数据的特殊性,因此没有必要继续传播,因此如果 trainable = false 您不必做任何事情。

    在 Tensorflow 中,trainable 标志是否将变量添加到 GraphKeys.TRAINABLE_VARIABLES 集合中,这样它们是否会被考虑在内。 https://www.tensorflow.org/api_docs/python/tf/trainable_variables

    【讨论】:

    • 您能否详细说明以下“当您设置为 trainable=true 时:如果该层位于网络中间,则仅传播输入梯度但不校正任何权重。如果该层是第一个这个网络不会传播任何梯度。”
    • 是否有任何支持此规则的 keras 文档?
    • 我已经更新了答案。如果您注意到两种情况下的行为相同,则第一层永远不会传播到输入(它是无用的,并且计算永远不会使用的导数的成本)。
    猜你喜欢
    • 1970-01-01
    • 2018-02-04
    • 2015-08-14
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 2016-09-05
    • 2019-03-02
    • 2017-03-31
    相关资源
    最近更新 更多