Word2vec 和 GloVe 是两个最知名的词嵌入方法。许多工作指出这两个模型实际上彼此非常接近,并且在某些假设下,它们对语料库中单词共现的 pPMI 进行矩阵分解。
尽管如此,我还是不明白为什么我们实际上需要两个矩阵(而不是一个)来用于这些模型。我们不能对 U 和 V 使用同一个吗?是梯度下降的问题还是有其他原因?
有人告诉我这可能是因为一个词的嵌入 u 和 v 应该足够远来表示一个词很少出现在它自己的上下文中的事实。但我不清楚。
Word2vec 和 GloVe 是两个最知名的词嵌入方法。许多工作指出这两个模型实际上彼此非常接近,并且在某些假设下,它们对语料库中单词共现的 pPMI 进行矩阵分解。
尽管如此,我还是不明白为什么我们实际上需要两个矩阵(而不是一个)来用于这些模型。我们不能对 U 和 V 使用同一个吗?是梯度下降的问题还是有其他原因?
有人告诉我这可能是因为一个词的嵌入 u 和 v 应该足够远来表示一个词很少出现在它自己的上下文中的事实。但我不清楚。
可能不是您正在寻找的答案,但我仍然会尝试:
首先,快速回顾一下 word2Vec,假设我们使用的是 skip gram。
一个典型的 Word2Vec 可训练模型包括 1 个输入层(例如,10 000 长的 one-hot 向量)、一个隐藏层(例如 300 个神经元)、一个输出(10 000 长的 one-hot 向量)
Input-Hidden 之间有一个矩阵E,描述了使你的 one-hot 成为嵌入的权重。该矩阵很特殊,因为每一列(或行,取决于您的首选符号)代表这 300 个神经元中的预激活 - 对相应传入 1-hot 向量的响应。
您无需对这 300 个神经元执行任何激活,并且可以立即将它们的值用作任何未来任务的嵌入。
然而,简单地将 one-hot 压缩到 300 维表示中是不够的——它必须有意义。我们使用额外的第二个矩阵来确保这个含义是正确的 - 它将隐藏连接到输出
我们不想激活隐藏层,因为在运行时不需要激活函数,但是,在这种情况下,我们将需要第二个矩阵,从隐藏到输出。
第二个矩阵将与您的嵌入完全不同。这样的 one-hot 将代表一个最有可能在您的原始 one-hot 附近(根据上下文)的词。换句话说,这个输出不会是你原来的 one-hot。
这就是为什么需要第二个矩阵的原因。在输出端,我们执行 softmax,就像在分类问题中一样。
这允许我们表达一个关系 "word"-->embedding-->"context-neighbor-word"
现在,可以进行反向传播,以纠正Input-Hidden权重(您的第一个矩阵 E)——这些是我们真正关心的权重。那是因为 Matrix E 可以在运行时使用(我认为),可能作为第一个全连接层插入到一些循环神经网络中。
在那种情况下,你不会使用这个:
您无需对这 300 个神经元执行任何激活,并且可以立即将它们的值用作任何未来任务的嵌入
但是,您只需在运行时从该矩阵中获取适当的列(或行,取决于您的首选符号)。这样做的好处是,通过这种方式,您可以获得一个非常便宜的预训练全连接层,旨在与 one-hots 一起使用。通常,由于梯度消失的问题,第一层的训练时间最长。
为什么在训练期间需要第二个矩阵:
再次回想一下,隐藏层没有激活。
我们可以指示网络必须创建什么“one-hot”以响应您原来的“input one-hot”,并且如果网络未能生成正确答案,我们可以惩罚它。
我们不能将 softmax 直接放在隐藏层之后,因为我们有兴趣调用一种机制来转换为嵌入。这已经是第一个矩阵 E 的责任了。因此,我们需要一个额外的步骤(一个额外的矩阵),这将为我们提供足够的空间,以便现在在输出层就不同但相似的(上下文相关的)邻词得出结论
在运行时,您丢弃第二个矩阵。但如果您需要返回并继续训练您的模型,请不要永久删除它。
为什么我们实际上需要两个矩阵(而不是一个)来用于这些模型。我们不能对 U 和 V 使用同一个吗?
原则上,你是对的,我们可以。但是我们不想这样做,因为参数数量的增加在实践中是有好处的,但是向量的含义呢?
报纸怎么说?
Word2vec:只有一次提到输入/输出向量只是为了引入变量。
GloVe:“单词和上下文单词之间的区别是任意的,我们可以自由地交换这两个角色”。
弱理由:
向量对(单词,上下文),也称为(目标,源)或(输出,输入),用于反映单个单词将扮演的两种不同角色。然而,由于一个词会在同一个句子中同时扮演“目标”和“上下文”的角色,所以理由很弱。例如,在句子“I love deep learning”中,在, 是一个目标,但接下来,它是一个上下文,尽管事实上在整个句子中具有相同的语义。我们可以得出结论,这种分离没有数据支持。
所以在词嵌入的情况下,这种分离只是我们通过增加参数数量来提高性能的一个故事,没有任何更深层次的东西。
坚实的理由:
然而,在像节点嵌入有向网络这样的任务中,理由是可靠的,因为角色反映在数据级别。例如,对于一个链接, 是在语义上不同于链接接收端的源 . 源节点永远不会扮演“目标”角色,除非它是另一个链接中的目标。因此,您可以期望通过对目标(源)节点使用目标(源)表示来实现有意义的语义分离。对于与词嵌入相同的无向图,这种证明失败了。
在一些论文中,作者甚至根据实体在数据级别所扮演的额外角色选择四种表示,这在语义上是合理的,并进一步提高了性能。
结论:
整个前提是“如果增加参数数量有回报,那就去做。如果它在语义上是合理的,那就更好了。”
W
仅使用一个形状向量空间实现 word2vec CBOW ,(V, D)
其中V
是词汇D
的数量,是词向量中的特征数量。
简而言之,它没有很好地工作。
Let(word, context)
是一对并从上下文中创建BoW(词袋)。例如,一个句子的对I love dogs that meaw
是(dogs, I love that meaw)
当上下文长度为 4 时。
使用粗斜体字表示它是(word, context)
成对的字。
训练的步骤如下所示,将成对的N
数量(word, context)
作为一个批次进行喂养。
从上下文中提取的词向量计算BoW ,并将与该词的词W
向量的点积作为正分数。
E-1。提取一个词向量We
,We = W[index_of_word]
其中单词index_of_word
的索引在哪里。
E-2。提取上下文向量where并创建BoW。
E-3。计算和作为的分数。
E-4。计算损失。
E-5。反向传播到as 。
E-6。反向传播到as 。W
Wc
Wc = W[indices_of_context]
Bc = sum(Wc, axis=0)
We
Bc
Ye = dot(Bc, We)
Le = -log(sigmoid(Ye))
dLe/dYe
We
dLe/dWe = dLe/dYe * dYe/dWe = dLe/dYe * Bc
dLe/dYe
Wc
dLe/dWc = dLe/dYe * dYe/dWc = dLe/dYe * We
在实际的自差计算中,sum
需要考虑 的导数来应用*
运算。
取负样本词的个数,并以BoWSL
为负分数,以点积计算每个负样本的负分数。结果是负分的数量。SL
S-1。取SL
负样本词的数量,不包括 中的那些词(word, context)
。
S-2。提取负样本的词向量,Ws
其中Ws = W[indices_of_samples]
.
S-3。Ws
从和计算负分数,Bc
因为Ys = einsum("nd,nsd->ns",Bc, Ws)
*n
代表批量大小N
,d
代表词向量大小D
,s
代表负样本大小SL
。
S-4。计算损失Ls = -log(1 - sigmoid(Ys))
。
S-5。反向传播dLs/dYs
到Ws
as dLs/dWs = dLs/dYs * dYs/dWs = dLs/dYs * Bc
。
S-6。反向传播dLe/dYe
到Wc
as dLe/dWc = dLs/dYs * dYs/dWs = dLs/dYs * Ws
。
在实际的自差分计算中,需要考虑einsum的导数来应用*
运算。
我认为单个不工作的原因是同时 在一批中使用多个反向传播W
更新相同的结果:W
dLe/dWe
和dLe/dWc
dLs/dWs
和dLs/dWc
.在具有多(word, context)
对的批次中,一对可能具有X
作为正分数的词。但它可以用作同一批次中其他对的负样本。因此,在批次中的梯度下降期间,单词X
将用于正分数和负分数。
因此,反向传播将同时更新W[X]
正负两个词向量。
假设在一个批次的第 1 行,这个词dogs
是一个对的词(word, context)
,并且用于一个正分数。W[index_for_dogs]
由 更新dLe/dWe
。
然后对于批次中的第二对,dogs
作为负样本进行采样。然后W[index_for_dogs]
由 更新dLs/dWs
。可以(word, context)
在一个批次中成对地排除所有单词,但这会导致负样本可用的单词集狭窄或倾斜。
此外,相同的词向量 inW
将是一对词context
,在另一对中是 a,并且是另一对的负样本。
我相信这些混合物可能是一种混淆行为
W
因此,将需要分离成不同的向量空间以给出明确的作用,例如,一个向量空间Wc
用于上下文。
可能有一个单独的向量空间用于单词,一个用于负样本。对两者使用一个向量空间也会同时导致正负反向传播。我认为这可能是为什么用于负样本的向量空间不用作 word2vec 的结果模型的原因。