本文介绍了如何在 TensorFlow 中实现 skim-gram 模型,并用 TensorBoard 进行可视化。
GitHub 地址:https://github.com/priya-dwivedi/Deep-Learning/blob/master/word2vec_skipgram/Skip-Grams-Solution.ipynb
本教程将展示如何在 TensorFlow 中实现 skim-gram 模型,以便为你正在处理的任意文本生成词向量,然后用 TensorBoard 进行可视化。我发现这个练习 1)有助于理解 skim-gram 模型是的工作原理;2)在 CNN 或 RNN 中使用词向量之前,先熟悉词向量捕获文本的关系。
我在 text8 数据集上训练了一个 skim-gram 模型,该数据集是英文维基百科文章的集合。我用 TensorBoard 来可视化这些嵌入。TensorBoard 允许使用 PCA 选择 3 主轴来投影数据,进而看到整个文字云。超级酷!你可以输入任何单词,它会显示相邻的单词。你也可以隔离最靠近它的 101 个点。
看看下面的片段。
完整代码:https://github.com/priya-dwivedi/Deep-Learning/blob/master/word2vec_skipgram/Skip-Grams-Solution.ipynb
为了可视化训练过程,我还持续跟踪一组随机单词在模型中最靠近的预测单词。在第一次迭代中,最接近的预测单词看起来非常随机。这很合理,因为所有词向量都是随机初始化的。
训练结束时,该模型已经能更好地找到单词之间的关系。
Word2Vec 和 Skip-Gram 模型
创建词向量是基于大型文本语料库,为每个单词创建向量的过程,且语料库中语境相似的单词所对应的向量在向量空间中非常接近。
这些词向量可以很好地捕捉单词之间的上下文关系(例如,黑色、白色和红色的示例向量会紧密地结合在一起),而且使用这些向量(而不是单词本身)来完成文本分类或新文本生成等自然语言处理(NPL)任务,会得到更好的结果。
有两个主要的模型来生成这些词向量——连续词袋(CBOW)和 Skip-Gram 模型。CBOW 模型试图根据给定语境词预测中心词,而 skip-gram 模型试图根据给定中心词预测语境词。我们可以看一个简化的例子:
CBOW: The cat ate _____. Fill in the blank, in this case, it's「food」.
CBOW:这只猫吃了________。(句子填充)本例中,应该填「食物」。
Skip-gram: ___ ___ ___ food. Complete the word's context. In this case, it's「The cat ate」
Skip-gram:_______________食物。(句子填充)本例中,可以填「这只猫吃了」
如果你对这两种方法的详细对比感兴趣,请参见此链接:https://iksinc.wordpress.com/tag/continuous-bag-of-words-cbow/。
大量论文发现,skip-gram 模型能产生更好的词向量,所以我将重点放在实现这个模型上。
在 Tensorflow 中实现 Skip-Gram 模型
这里我只列出构建模型的主要步骤。详情请查看我的 GitHub repo。
1. 数据预处理
首先清理数据,删除标点、数字,并将文本分割成单个单词。比起单词,程序能更好地处理整数,因此我们创建一个「词汇转整数」字典,将每个单词映射到一个整数上。代码如下:
2. 子采样
经常出现的单词,如「the」、「of」和「for」,并没有给附近的单词提供太多的语境。如果丢弃一些,我们就可以消除数据中的的部分噪声,实现更快的训练和更好的表示。这个过程被 Mikolov 称为子采样(subsampling)。
3. 创建输入和目标
skip-gram 模型的输入是每个单词(编码为整数),而目标是围绕该窗口的单词。Mikolov 等人发现,如果这个窗口的大小是可变的,同时更接近中心词的单词被采样次数较多时,性能会更好。
「由于距离更远的词通常不如距离更近的词与目标单词的关系那么紧密,我们从远距离的词中采样较少的单词作为训练样本,以降低其权重……如果选择窗口大小= 5,那么我们将为每一个训练词随机选择一个 1 和窗口大小 5 之间的数字 R,然后将目标单词在句子中的前后 R 个单词纳入训练,作为正确的标签。」
4. 构建模型
下图展示了我们将要构建网络的一般结构(图片来源:http://mccormickml.com/2016/04/19/word2vec-tutorial-the-skip-gram-model/)。
我们把一个输入词如「ants」(蚂蚁)表示为独热向量。这个向量有 10000 个分量(每个分量都对应于词汇表中的一个单词),我们将单词「ants」对应的分量设为「1」,所有其他分量都为 0。网络的输出也是一个单向量(也包含 10000 个分量)。
训练结束时,隐藏层将会有经过训练的词向量。隐藏层的大小相当于向量中的维数。在上面的例子中,每个单词都有一个长度为 300 的向量。
你可能已经注意到,skip-gram 神经网络包含大量的权重……在我们的例子中有 300 个特征和包含 10000 个单词的词汇表,也就是说在隐藏层和输出层都有 3 百万个权重数!在大型数据集上进行这样的训练令人望而却步,因此 word2vec 的作者引入了一些调整来使训练变得可行。详情请查看:http://mccormickml.com/2017/01/11/word2vec-tutorial-part-2-negative-sampling/;Github 代码:https://github.com/priya-dwivedi/Deep-Learning/blob/master/word2vec_skipgram/Skip-Grams-Solution.ipynb。
5. 用 TensorBoard 进行可视化
使用 TensorBoard 中的「嵌入投影机」可视化嵌入。要实现这个功能,你需要完成以下步骤:
- 在检查点目录的训练结束时保存你的模型
- 创建一个 metadata.tsv 文件包含每个整数转换回单词的映射关系,这样 TensorBoard 就会显示单词而不是整数。将这个 tsv 文件保存在同一个检查点目录中
- 运行这段代码:
- 打开 TensorBoard,将其指向检查点目录
大功告成!
原文链接:https://towardsdatascience.com/training-and-visualising-word-vectors-2f946c6430f8