之前文章介绍了skip-gram的原理,这篇文章给出模型的实现细节以及pytorch和tensorflow的实现。
回顾 #
假如用余弦相似度来计算两个词的one-hot编码得到0,即不能编码词之间的相似性,所以有了word2vec的方法,包括skip-gram和CBOW。
接前文,假如我们拥有10000个单词的词汇表,想嵌入300维的词向量,那么我们的输入-隐层权重矩阵和隐层-输出层的权重矩阵都会有 10000 x 300 = 300万个权重,在如此庞大的神经网络中进行梯度下降是相当慢的。更糟糕的是,你需要大量的训练数据来调整这些权重并且避免过拟合。百万数量级的权重矩阵和亿万数量级的训练样本意味着训练这个模型将会是个灾难。1 所以在具体实践上有一些计算技巧。
计算 #
,即最大化以下概率
用softmax来计算
其中
在skip-gram实际算法中使用多种策略来减少模型的资源使用(内存)以及提高词向量表征质量2
- 负采样
- 从隐藏层到输出的Softmax层的计算量很大,因为要计算所有词的Softmax概率,再去找概率最大的值。例如当我们用训练样本 ( input word: “fox”,output word: “quick”) 来训练我们的神经网络时,“ fox”和“quick”都是经过one-hot编码的。如果我们的vocabulary大小为10000时,在输出层,我们期望对应“quick”单词的那个神经元结点输出1,其余9999个都应该输出0。在这里,这9999个我们期望输出为0的神经元结点所对应的单词我们称为“negative” word。当使用负采样时,我们将随机选择一小部分的negative words(比如选5个negative words)来更新对应的权重, 我们也会对我们的“positive” word进行权重更新3。在实践中,通常使用的是unigram分布的平方根,即词汇表中每个词的概率的0.75次方除以归一化常数来挑选负样本。
- 高频词进行抽样原因:高频词相对于低频词来说提供的信息少;高频词随着样本增多本身表示也不会发生太大变化使用概率P来丢掉一定的单词
其中t为设定的阈值,
- 单词组合成词组作为单个词处理原因:组合词有特定的意思,不是简单把单个词的表示聚合起来如何从文本中提取出词组研究不少,skip-gram文章选用了
其中
skip-gram PyTorch实现 #
Word2vec skip-gram pytorch4
skipgram-pytorch.ipynb
skip-gram Tensorflow实现 #
Word2vec skip-gram tensorflow5
skipgram-tf.ipynb
- 理解 Word2Vec 之 Skip-Gram 模型 - 知乎 ↩︎
- Distributed Representations of Words and Phrases and their Compositionality ↩︎
- 关于skip-gram和负采样 - 简书 ↩︎
- 14.1. 词嵌入(word2vec) — 动手学深度学习 2.0.0 documentation ↩︎
- word2vec | TensorFlow Core ↩︎