keras - 如何在具有共享嵌入层和负采样的 keras 中实现 word2vec CBOW?

标签 keras embedding word2vec

我想创建一个词嵌入预训练网络,在 word2vec CBOW 之上添加一些东西。因此,我首先尝试实现 word2vec CBOW。因为我对 keras 很陌生,我无法弄清楚如何在其中实现 CBOW。

初始化 :

我已经计算了词汇量,并将单词映射到整数。

输入(尚未实现)网络 :
2*k + 1名单整数(代表中心词和上下文中的 2*k 个词)

网络规范

一个共享Embedding层应该采用这个整数列表并给出它们相应的向量输出。进一步的平均值 2*k将采用上下文向量(我相信这可以使用 add_node(layer, name, inputs=[2*k vectors], merge_mode='ave') 来完成)。

如果有人可以分享一个小代码片段,这将非常有帮助。

附言 : 我在看word2veckeras ,但无法遵循其代码,因为它也使用了 gensim。

更新 1 :

我想在网络中共享嵌入层。嵌入层应该能够获取上下文词 (2*k) 和当前词。我可以通过在输入中获取所有 2*k + 1 个单词索引并编写一个自定义的 lambda 函数来做到这一点。但是,在那之后,我还想添加负采样网络,为此我必须嵌入更多的单词和点积与上下文向量。有人可以提供一个示例,其中嵌入层是 Graph() 中的共享节点网络

最佳答案

Graph()已被弃用 keras可以使用 keras functional API 创建任意网络.
以下是创建 word2vec cbow 模型的演示代码,并在随机输入上测试了负采样

from keras import backend as K
import numpy as np
from keras.utils.np_utils import accuracy
from keras.models import Sequential, Model
from keras.layers import Input, Lambda, Dense, merge
from keras.layers.embeddings import Embedding

k = 3 # context windows size
context_size = 2*k
neg = 5 # number of negative samples
# generate weight matrix for embeddings
embedding = []
for i in range(10):
    embedding.append(np.full(100, i))
embedding = np.array(embedding)
print embedding

# Creating CBOW model
word_index = Input(shape=(1,))
context = Input(shape=(context_size,))
negative_samples = Input(shape=(neg,))
shared_embedding_layer = Embedding(input_dim=10, output_dim=100, weights=[embedding])

word_embedding = shared_embedding_layer(word_index)
context_embeddings = shared_embedding_layer(context)
negative_words_embedding = shared_embedding_layer(negative_samples)
cbow = Lambda(lambda x: K.mean(x, axis=1), output_shape=(100,))(context_embeddings)

word_context_product = merge([word_embedding, cbow], mode='dot')
negative_context_product = merge([negative_words_embedding, cbow], mode='dot', concat_axis=-1)

model = Model(input=[word_index, context, negative_samples], output=[word_context_product, negative_context_product])

model.compile(optimizer='rmsprop', loss='mse', metrics=['accuracy'])

input_context = np.random.randint(10, size=(1, context_size))
input_word = np.random.randint(10, size=(1,))
input_negative = np.random.randint(10, size=(1, neg))

print "word, context, negative samples"
print input_word.shape, input_word
print input_context.shape, input_context
print input_negative.shape, input_negative

output_dot_product, output_negative_product = model.predict([input_word, input_context, input_negative])
print "word cbow dot product"
print output_dot_product.shape, output_dot_product
print "cbow negative dot product"
print output_negative_product.shape, output_negative_product
希望能帮助到你!
更新1:
我已经完成了代码并上传了here

关于keras - 如何在具有共享嵌入层和负采样的 keras 中实现 word2vec CBOW?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41888085/

相关文章:

python - ValueError : logits and labels must have the same shape ((None, 14)与(无,1))

python - 图形连接句子

python - doc2vec 如何聚类 DocvecsArray

templates - 模板对象字段强制执行

javascript - 嵌入谷歌地图减去固定的页眉和页脚

java - 是否可以在 deeplearning4j.word2vec 中使用 gensim word2vec 模型?

python - ValueError : The last dimension of the inputs to `Dense` should be defined. 发现 `None`

tensorflow - Keras 中按小数因子进行上采样

python - TensorFlow 2.0 中神经网络的问题

c++ - 跨平台 NPAPI 接口(interface)/集成