word2vec 将上下文单词学习为最相似而不是相似上下文中的单词的可能原因

数据挖掘 神经网络 深度学习 nlp word2vec 词嵌入
2022-02-14 12:17:10

我正在观察我的 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。

2个回答

在 Keras 中使用嵌入的好例子。

如果我解释正确,那么您的实现与“原始 word2vec”之间存在很大差异。原始框架不像您的情况那样使用一个“嵌入” vector_sizexvector_dim权重矩阵,而是使用两个矩阵(或层):将输入映射到维度向量的“投影层”vector_dim和映射这个的“隐藏层”向量到所有词汇的概率。

隐藏层或预测层通常在训练后被丢弃,尽管它可能很有用。

如果您的代码确实强制这些层共享权重,那么我们也会得到一些有趣但不同的东西,嵌入反映共现是合理的 - 请参阅这个问题,它具体询问如果两个层共享会发生什么

无论哪种方式,“植物”都应该与“植物”的余弦相似度最相似——或者有些向量完全相同(归一化)。

根据原始word2vec论文,分层softmax用于加速训练。所以如果你不使用它并且有两个权重层,你的版本可能会变得太慢。例如,我可以推荐使用gensim实现 soft-max 的库,并且应该在您的设置可管理的时间内在现代笔记本电脑上运行。

神经网络与其他机器学习技术的不同之处在于它们必须通过重复来学习。在神经网络用语中,重复称为一个时期。在一个时期内,每个实例,在您的情况下,每个单词都会被评估,并且错误会通过层向后应用,并且权重会被调整。根据超参数,权重的变化或多或少会发生积极的变化,但它们往往一次只移动一点。

您已经对word2vec模型进行了两个时期的训练。我没有看到您如何初始化模型的权重,但通常它们被设置为随机值或设置为零。鉴于您的结果看起来有点随机,我相信这是因为模型刚刚开始学习。

为了获得训练有素的词嵌入模型或任何其他神经网络,您可能需要训练数百、数千甚至数百万个 epoch。这就是为什么预训练的词嵌入模型即使免费提供也如此有价值的原因。如果您只想要一个训练有素的嵌入模型,请下载它。如果您需要合并一些特定领域的用法,您可以进一步训练下载的嵌入。

高温高压