【腾讯TMQ】Tensorflow 的 word2vec详细解释——basic篇
Word2Vec即Word to vector(词汇转向量)。
我们希望词义相近的两个单词,在映射之后依然保持相近,词义很远的单词直接则保持很远的映射距离。
关于Word2Vec实例总结为6步:
1、下载数据;
2、将原词汇数据转换为字典映射;
3、为 skip-gram模型 建立一个扫描器;
4、建立并训练 skip-gram 模型;
5、开始训练模型;
6、结果可视化。
现在来详细解说。
1、下载数据
打开下载进来的word词汇数据,由于是无监督学习,并没有标签,就只是整整100M大小文本数据。
这是第一步下载得到的数据:
2、将原词汇数据转换为字典映射
然后开始第二步将原词汇数据转换为字典映射,比如我取出这段文本的头一句,它会进行如下变换:
现在我们的词汇文本变成了用数字编号替代的格式以及词汇表和逆词汇表。逆词汇只是编号为key,词汇为value。
3、为skip-gram 模型建立一个扫描器
首先看一下扫描器函数:
defgenerate_batch(batch_size, num_skips, skip_window):
batch_size是指一次扫描多少块,skip_window为左右上下文取词的长短,num_skips输入数字的重用次数。假设我们的扫描器先扫这大段文字的前8个单词,左右各取1个单词,重用次数为2次。我们就会观察到如下结果:
关于参数设置:
Batch_size每次sgd训练时候扫描的数据大小, embedding_size 词向量的大小,skip_window窗口大小。
Num_skips = 2 表示input用了产生label的次数限制。
demo中默认是2,可以设置为1。
对比下:
默认2的时候:
4
设置1的时候:
5
就是对于一个中心词 在window范围 随机选取num_skips个词,产生一系列(input_id, output_id) 作为(batch_instance, label)这些都是正样本。
4、建立图形
这里谈得都是嵌套,那么先来定义一个嵌套参数矩阵。我们用唯一的随机值来初始化这个大矩阵。
6
对噪声-比对的损失计算就使用一个逻辑回归模型。对此,我们需要对语料库中的每个单词定义一个权重值和偏差值。(也可称之为输出权重 与之对应的 输入嵌套值)。定义如下。
7
我们有了这些参数之后,就可以定义Skip-Gram模型了。简单起见,假设我们已经把语料库中的文字整型化了,这样每个整型代表一个单词。Skip-Gram模型有两个输入。一个是一组用整型表示的上下文单词,另一个是目标单词。给这些输入建立占位符节点,之后就可以填入数据了。
8
然后我们需要对批数据中的单词建立嵌套向量,TensorFlow提供了方便的工具函数。
9
embed = tf.nn.embedding_lookup(embeddings, train_inputs)
好了,现在我们有了每个单词的嵌套向量,接下来就是使用噪声-比对的训练方式来预测目标单词。
10
我们对损失函数建立了图形节点,然后我们需要计算相应梯度和更新参数的节点,比如说在这里我们会使用随机梯度下降法,TensorFlow也已经封装好了该过程。
11
训练模型
训练的过程很简单,只要在循环中使用feed_dict不断给占位符填充数据,同时调用 session.run即可。
12
现在通过上面一步,我们构造出了input和label,就可以进行监督学习,下面
13
5、NCE Loss
这里为什么不用更为常见的Softmax + Cross-Entropy 呢?
14
因为如果在这里使用Softmax + Cross-Entropy作为损伤函数会有一个问题,Softmax当有几万+的分类时,速率会大大下降。
其速度对比如下:
10000 个类,Softmax每秒处理 10000 个样本,NCE每秒处理 30000 个样本。
100000 个类,Softmax每秒处理 1000 个样本,NCE每秒处理 20000 个样本。
这里再整理出其他同学关于 NCE LOSS 源码的理解,下面就是一段 NCE LOSS 的实现代码,但不得而知 Tensorflow 是否使用该NCE LOSS的实现。
15
NCE的主要思想是,对于每一个样本,除了本身的label,同时采样出N个其他的label,从而我们只需要计算样本在这N+1个label上的概率,而不用计算样本在所有label上的概率。而样本在每个label上的概率最终用了Logistic的损失函数。
这里可谓是整个 Word2Vec 的关键。
至此,已经搭建好训练模型,然后便可以进行分批次的训练即可。那么下一个问题是完成训练后,我们如何判断两个词汇的相似度呢?
16
这里我们使用 cos 来表示相似度会比使用 l2 向量差值会好一些。
这是根据训练方式所决定的,因为向量的长度与分类无关。
6、最后调用 skitlearn的TSNE模块进行降维到2元,(plot_with_labels函数)绘图展示:
关注腾讯移动品质中心TMQ公众号,获取更多测试干货:
版权所属,禁止转载