我正在观察我的 word2vec 模型将上下文单词学习为最相似而不是相似上下文中的单词。我不明白为什么它(一般来说是 word2vec,而不是我的模型)会表现得像这样,我想知道为什么。
我已经在 keras 中实现了原始的 word2vec。我选择了带有点积层的变体,而不是分层的 softmax,并在我拆分为 5 克的 Wikipedia 转储上训练了模型。对于每个单词,我构造了 8 对带有二进制目标标签的训练项。我使用标签为 True 的 4 个上下文词,并选择 4 个随机词,它们不是标签为 0 的上下文词之一。
直观地说,该模型应该学习相似上下文中单词的相似表示,因为它以相似的方式修改这些单词的表示,因为它使用相似的上下文单词独立地优化它们。因此,这些相似的词不是直接相似,而是间接相似,因为它们由于相似的上下文而受到相似的推动。
模型是这样的:
input_target = Input((1,))
input_context = Input((1,))
embedding = Embedding(vocab_size, vector_dim, input_length=1, name='embedding')
target = embedding(input_target)
target = Reshape((vector_dim, 1))(target)
context = embedding(input_context)
context = Reshape((vector_dim, 1))(context)
dot_product = Dot(axes=1)([target, context])
dot_product = Reshape((1,))(dot_product)
output = Dense(1, activation='sigmoid')(dot_product)
model = Model(inputs=[input_target, input_context], outputs=output)
model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
然而,我从训练这个模型中观察到,当我对给定某个单词的最相似的单词进行排名时,我会得到出现在该单词上下文中的单词,而不是出现在相似上下文中的单词,作为最相似的单词字。
例如:
words most similar to "plant":
rank | word
0 | amount
1 | surface
2 | electron
3 | mass
4 | plant # also: Why is plant not most similar to plant? How can that happen?
5 | fluid
6 | air
7 | metal
8 | molecule
9 | cell
10 | electric
11 | per
12 | oxygen
13 | demonstrate
14 | smooth
对我来说,这看起来更像是出现在植物上下文中的单词,而不是出现在与其相似的上下文中的单词。
计算这些的函数是:
def get_most_similar(word_vector, embeddings, n=15):
"""
find the `n` words that are most similar to `word_vector` in `embeddings`
measured by their cosine similarity
"""
v = word_vector
m = embeddings
cosines = (np.dot(v, m.T))/(np.linalg.norm(m.T, axis=0)*np.linalg.norm(v))
ranked_by_similarity = np.argpartition(cosines, -n)[-n:]
return reversed(ranked_by_similarity)
有一个简单的原因吗?
我有以下其他参数:
word vector size: 300
batch size: 128
vocabulary size: 169161 (distinct lemmas)
training sample count: 27793586 (5-grams, overlapping within sentences)
我对模型进行了 1 个 epoch 的训练,并且只观察到边缘进一步收敛到第二个 epoch。