如何在网页上训练我自己的自定义单词嵌入



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

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

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

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

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

我建议您使用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)

EDIT:如果您想在Keras中实现自己的模型,您确实可以按照建议使用带有trainable = True(默认行为)的嵌入层。这里有一个关于如何做到这一点的好指南。

  1. 若要仅进行训练,必须在嵌入层中将可训练标志设置为True。但他会从一开始就训练-
  2. 要初始化矩阵,可以使用您认为的矩阵此处的示例:https://www.kaggle.com/lystdo/lstm-with-word2vec-embeddings(其中使用了Google300否定词,而且只使用了它们是从原始矩阵中使用的)。在嵌入构造函数类中使用weights参数(weights=[…])。此矩阵应为单词数x嵌入维数的大小

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

当您设置为可训练=真时:

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

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

当你在这个层中激活可训练时,你可以全权让Keras在考虑这个嵌入时进行调整。这也意味着必须优化更多的参数。

在某些情况下,由于所涉及的成本或由于要守恒,对修改初始嵌入没有兴趣。

编辑:此任务对应于Keras内部的Tensorflow。但这一原则并不取决于框架,而仅仅取决于理论。定义trainable=false时,表示权重不应更新。

这意味着中间层必须只计算相对于输入的梯度,因为其中一个权重是无用的(即使计算了它们,也不会获得任何结果,并且不存在可训练标志)。它们相对于入口进行计算,因为梯度必须继续传播。

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

在Tensorflow中,可训练标志将变量添加或不添加到GraphKeys.trainable_VARIABLES集合,无论是否考虑变量。https://www.tensorflow.org/api_docs/python/tf/trainable_variables