【问题标题】:How to train a model with only an Embedding layer in Keras and no labels如何在 Keras 中训练只有一个嵌入层且没有标签的模型
【发布时间】:2019-04-20 18:18:58
【问题描述】:

我有一些没有任何标签的文本。只是一堆文本文件。我想训练一个嵌入层来将单词映射到嵌入向量。到目前为止我看到的大多数例子都是这样的:

from keras.models import Sequential
from keras.layers import Embedding, Flatten, Dense

model = Sequential()
model.add(Embedding(max_words, embedding_dim, input_length=maxlen))
model.add(Flatten())
model.add(Dense(32, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.summary()
model.compile(optimizer='rmsprop',
    loss='binary_crossentropy',
    metrics=['acc'])
model.fit(x_train, y_train,
    epochs=10,
    batch_size=32,
    validation_data=(x_val, y_val))

他们都假设嵌入层是试图预测标签的更大模型的一部分。但就我而言,我没有标签。我不想对任何东西进行分类。我只想训练从单词(更准确地说是整数)到嵌入向量的映射。但是模型的fit 方法要求x_trainy_train(如上面给出的示例)。

如何训练一个只有嵌入层而没有标签的模型?

[更新]

根据我从@Daniel Möller 得到的答案,Keras 中的嵌入层正在实施一种监督算法,因此无法在没有标签的情况下进行训练。最初,我认为它是 Word2Vec 的变体,因此不需要训练标签。显然,事实并非如此。就个人而言,我最终使用了与 Keras 或 Python 无关的 FastText

【问题讨论】:

  • 好吧,在这种情况下,您只需要一个只有嵌入层的模型medium.com/@satnalikamayank12/…
  • @desertnaut 感谢您的链接。这绝对是一篇有趣的文章。但据我所知,他们仍在处理提供标签的分类问题。如果我错了,请纠正我,但我认为情况不同。
  • 我也在尝试同样的事情,从语料库创建嵌入。用 Keras 找不到任何东西。但是我发现了这个博客,他们在其中使用 Tensorflow 从一个巨大的语料库中创建嵌入。 word embeddings using tensorflow

标签: python machine-learning keras word-embedding


【解决方案1】:

在没有标签/目标的情况下这样做有意义吗?

如果没有目标,您的模型将如何确定向量中的哪些值适用于任何事情?

所有嵌入都是为了某个目的而“训练”的。没有目的就没有目标,没有目标就没有训练。

如果您真的想在没有任何目的/目标的情况下转换向量中的单词,您有两个选择:

  • 制作 one-hot 编码向量。您可以为此使用 Keras to_categorical 函数。
  • 使用预训练嵌入。有一些可用的,例如 glove、来自 Google 的嵌入等。(所有这些都在某个时候出于某种目的而接受过训练)。

基于我们聊天的非常幼稚的方法,考虑到单词距离

警告:我对 Word2Vec 一无所知,但我将尝试展示如何使用一些简单的词距离添加嵌入规则,以及如何使用虚拟“标签”来满足 Keras'训练方式。

from keras.layers import Input, Embedding, Subtract, Lambda
import keras.backend as K
from keras.models import Model

input1 = Input((1,)) #word1
input2 = Input((1,)) #word2

embeddingLayer = Embedding(...params...)

word1 = embeddingLayer(input1)
word2 = embeddingLayer(input2)

#naive distance rule, subtract, expect zero difference
word_distance = Subtract()([word1,word2])

#reduce all dimensions to a single dimension
word_distance = Lambda(lambda x: K.mean(x, axis=-1))(word_distance)

model = Model([input1,input2], word_distance)

既然我们的模型直接输出一个单词距离,我们的标签将是“零”,它们并不是监督训练的真正标签,但它们是模型的预期结果,这是 Keras 工作所必需的。

例如,我们可以将mae(平均绝对误差)或mse(均方误差)作为损失函数。

model.compile(optimizer='adam', loss='mse')

并且用 word2 作为 word1 之后的词进行训练:

xTrain = entireText
xTrain1 = entireText[:-1]
xTrain2 = entireText[1:]
yTrain = np.zeros((len(xTrain1),))

model.fit([xTrain1,xTrain2], yTrain, .... more params.... ) 

虽然这对于 Word2Vec 的真正作用可能是完全错误的,但它显示了以下要点:

  • 嵌入层没有特殊属性,它们只是可训练的查找表
  • 创建嵌入的规则应由模型和预期输出定义
  • Keras 模型需要“目标”,即使这些目标不是“标签”而是预期结果的数学技巧。

【讨论】:

  • 感谢您的回答。我相信嵌入层的底层算法类似于 Word2Vec(或者可能是 GloVe)。如果是这样的话,学习 Word2Vec 不需要数据有标签。 Word2Vec 还有其他实现(在其他编程语言中),它们都是这样的。另外,我也研究过算法。 Word2Vec 依赖于文本中单词的接近度,它没有用于标签。在所有使用嵌入层的示例中,标签用于其他层,而不是嵌入层。
  • 请看这篇文章。它指出我的请求是有效的,但它没有提供解决方案:machinelearningmastery.com/…
  • 您说的是“预训练”嵌入。标签也用于嵌入,除非嵌入是预训练的,并且您明确告诉模型您不希望它可训练。
  • 您可以使用预训练的嵌入层这一事实表明,训练嵌入层并不依赖于标签。考虑一下。如果嵌入层是基于某些特定问题进行训练的,您将无法在不同的问题中使用它们。预训练映射起作用的唯一原因是它们只依赖于语料库而不是任何特定问题。请相信我。 Word2Vec 仅依赖于文本中单词的接近程度,不涉及标签。也许这就是为什么嵌入必须是 Kersa 的第一层。这实际上不是培训的一部分。
  • 相信我对 Keras 的看法。嵌入层针对特定目的进行训练。而这句话是错误的:“你可以使用预训练的嵌入层这一事实表明,训练嵌入层并不依赖于标签。” - 它表明可以在许多问题中使用的预训练嵌入是在一个非常普遍的问题中训练的。
猜你喜欢
  • 2019-10-23
  • 2018-12-21
  • 2021-08-13
  • 2020-09-03
  • 1970-01-01
  • 1970-01-01
  • 2020-07-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多