如何在 Keras 中训练只有嵌入层且没有标签的模型

How to train a model with only an Embedding layer in Keras and no labels

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

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

没有 label/target 这样做有意义吗?

如果没有 objective,您的模型将如何决定向量中的哪些值对任何事情都有好处?

所有嵌入都是 "trained" 的目的。没有目的就没有目标,没有目标就没有训练。

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

  • 制作单热编码向量。您可以为此使用 Keras to_categorical 函数。
  • 使用预训练嵌入。有一些可用的,例如手套、来自 Google 的嵌入等(所有这些都在某个时候出于某种目的进行了训练)。

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

警告:我对 Word2Vec 真的一无所知,但我会尝试展示如何使用一些朴素的词距离为您的嵌入添加规则,以及如何使用虚拟 "labels"满足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)

既然我们的模型直接输出一个单词距离,我们的标签将是"zero",它们并不是真正的监督训练标签,但它们是模型的预期结果,一些必要的东西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 模型将需要 "targets",即使这些目标不是 "labels" 而是预期结果的数学技巧。