Python Tensorflow下的Word2Vec代码解释

前言:

作为一个深度学习的重度狂热者,在学习了各项理论后一直想通过项目练手来学习深度学习的框架以及结构用在实战中的知识。心愿是好的,但机会却不好找。最近刚好有个项目,借此机会练手的过程中,我发现其实各大机器学习以及tensorflow框架群里的同学们也有类似的问题。于是希望借项目之手分享一点本人运行过程中的理解以及经验,希望在有益大家工作的基础上抛砖引玉,得到行业内各位专业人士的批评指点,多谢大家支持!

第一章博客我将会分为两个部分,这一部分将讲述Word2Vec在tensorflow中官方提供的basic版本的构造原理以及如何搭建一个CBOW模型来弥补提供版本里缺失的模型构架。于下一个部分里,我会重点对比tensorflow下basic, optimised以及gensim三个版本的Word2Vec的运行结果情况。

代码解析:

首先,Tensorflow提供的基础教程已经讲解了什么是Word2Vec以及Tensorflow是如何构建这个网络来训练的。教程的地址请看这里。另外这个basic版本的代码可以在这里找到。

代码的结构看似混乱,其实很直白。首先,第61行限制了这个demo可以学习一共50000个不同的单词。之后,在build_dataset(words)函数里,第65行展示了Python语言的强劲,即一行整理整个输入。在count的UNK(也就是unknown单词,即词频率少于一定数量的稀有词的代号)后用extend函数嵌入count数为从高网低数第vocabulary_size-1个,这样所有的重复数量少于49999个词儿的就只能对不住了,count将会把它排挤在外。形成count后dictionary来自于对count里的词频进行整理,除去重复次数但换做排行顺序作为这个dict结构的key。单词本身即成为了dict结构的value。之后,将输入的单词转化为他们在dictionary中的代码以及最后,统计下输入数据里有多少词不在这个dictionary里,按照个数增加UNK的数量,并把dictionary函数按照由高频到低频的排序方法排好顺序。由此,build_dataset函数成功的重建了输入数据以及形成了代码单词对照表,其中data将会被用于训练模型而dictionary将可以最为最后查询矢量及单词关系的翻译本。如果大家不希望限定dictionary里的vocabulary_size怎么办呢?其实答案很简单。Mikolov原文里表示只要除去频率少于3到10的词儿就好,那么我们可以对该函数做以下修改将可以达成:

def build_dataset(words, min_cut_freq):
  count_org = [[‘UNK‘, -1]]
  count_org.extend(collections.Counter(words).most_common()) #这里我们收集全部的单词的词频
  count = [[‘UNK‘, -1]]
  for word, c in count_org:
    word_tuple = [word, c]
    if word == ‘UNK‘:   #保留UNK的位置已备后用
        count[0][1] = c
        continue
    if c > min_cut_freq: #这里定义一个para为min_cut_freq,少于这个数量的将会被咔掉
        count.append(word_tuple)
  dictionary = dict()
  for word, _ in count:
    dictionary[word] = len(dictionary)
  data = list()
  unk_count = 0
  for word in words:
    if word in dictionary:
      index = dictionary[word]
    else:
      index = 0  # dictionary[‘UNK‘]
      unk_count += 1
    data.append(index)
  count[0][1] = unk_count
  reverse_dictionary = dict(zip(dictionary.values(), dictionary.keys()))
  return data, count, dictionary, reverse_dictionary

之后,源代码第91行的generate_batch其实就是构建skip-gram模型的入口,而不是自第137行with graph.as_default()之后的框架。137行之后的为建立一个简单的MLP模型以便tensor在模型里flow。而这个tensor以及其target的形式才是构建模型的要素。如果大家仔细阅读后会发现在一个输入为“蝙蝠侠战胜了超人,美国队长却被钢铁侠暴打”这句中,在build_dataset函数转换后可能蝙蝠侠被它的在dictionary中的代码3替代,战胜了被90替代,超人被600替代,美国队长为58,被为77,钢铁侠为888以及暴打为965。于是这句话变成了[3,90,600,58,77,888,965]. 假设window size是3, 这里的模型是skip-gram,这个generate_batch函数从90出发,输出的batch为[90,90,600,600,58,58,77,77,888,888], 输出的target为[3,600,90,58,600,77,58,888,77,965]. 那么,如何构建CBOW模型呢?其实很简单,注意到CBOW模型的输入以及预测跟SkipGram正好相反,那么我们把第109行的batch和第110行的labels对调不就okay了么?具体代码如下:

def generate_cbow_batch(batch_size, num_skips, skip_window):
  global data_index
  assert batch_size % num_skips == 0
  assert num_skips <= 2 * skip_window
  batch = np.ndarray(shape=(batch_size), dtype=np.int32)
  labels = np.ndarray(shape=(batch_size, 1), dtype=np.int32)
  span = 2 * skip_window + 1 # [ skip_window target skip_window ]
  buffer = collections.deque(maxlen=span)
  for _ in range(span):
    buffer.append(data[data_index])
    data_index = (data_index + 1) % len(data)
  for i in range(batch_size // num_skips):
    target = skip_window  # target label at the center of the buffer
    targets_to_avoid = [ skip_window ]
    for j in range(num_skips):
      while target in targets_to_avoid:
        target = random.randint(0, span - 1)
      targets_to_avoid.append(target)      #这里的batch和labels是skipgram模型的
      #batch[i * num_skips + j] = buffer[skip_window]
      #labels[i * num_skips + j, 0] = buffer[target]      #这里的batch和labels是CBOW模型的,原理是对掉上面skipgram模型的两行。
      batch[i * num_skips + j] = buffer[target]
      labels[i * num_skips + j, 0] = buffer[skip_window]
    buffer.append(data[data_index])
    data_index = (data_index + 1) % len(data)
  return batch, labels

由此,我们只需要在后面的batch_inputs, batch_labels = generate_batch(batch_size, num_skips, skip_window)函数更换函数为你的CBOW模型函数就好了。

时间: 2024-12-30 03:07:54

Python Tensorflow下的Word2Vec代码解释的相关文章

word2vec代码解释

以前看的国外的一篇文章,用代码解释word2vec训练过程,觉得写的不错,转过来了 原文链接 http://nbviewer.jupyter.org/github/dolaameng/tutorials/blob/master/word2vec-abc/poc/pyword2vec_anatomy.ipynb Hashed Vocabulary In the C implementation, the vocab is a combination of hashed vocabulary and

linux下Python tab补全功能代码

1.在学习linux的童鞋都用惯了tab补全功能,从而在学习Python的同时,一是为了方便,二是可以看到更多的关于Python命令下的知识. 2.配置步骤: (1) 在linux下键入这样的代码: vim tab.py #!/usr/bin/python # python tab file import sys import readline import rlcompleter import atexit import os #tab completion readline.parse_an

Deep Learning入门视频(下)之关于《感受神经网络》两节中的代码解释

代码1如下: #深度学习入门课程之感受神经网络(上)代码解释: import numpy as np import matplotlib.pyplot as plt #matplotlib是一个库,pyplot是其中一个模块 #%matplotlib inline 适用于在ipython notebook中进行绘图内嵌说明,由于我在Pycharm上写的,应此不需要这条以及下面的几个命令 plt.rcParams['figure.figsize'] = (10.0,8.0) #创建一个10*8大小

从零开始Windows环境下安装python+tensorflow

从零开始Windows环境下安装python+tensorflow 2017年07月12日 02:30:47 qq_16257817 阅读数:29173 标签: windowspython机器学习tensorflowAnaconda 更多 个人分类: machine-learning 前言 安装环境 tensorflow Anaconda 安装步骤 1.安装Anaconda 2.安装tensorflow 3.测试是否安装成功 总结 前言 本文介绍在Windows平台下,使用Anoconda简单安

Windows下使用Word2vec继续词向量训练

word2vec是Google在2013年提出的一款开源工具,其是一个Deep Learning(深度学习)模型(实际上该模型层次较浅,严格上还不能算是深层模型,如果word2vec上层再套一层与具体应用相关的输出层,如Softmax,便更像是一个深层模型),它将词表征成实数值向量,采用CBOW(Continuous Bag-Of-Words Model,连续词袋模型)和Skip-Gram(Continuous Skip-GramModel)两种模型.具体原理,网上有很多. 本文是在window

python 单下划线/双下划线使用总结(转载)

python 单下划线/双下划线使用总结 时间:2013-10-08 10:56来源:www.chengxuyuans.com Python 用下划线作为变量前缀和后缀指定特殊变量/方法. 主要存在四种情形1.    1. object # public    2. __object__ # special, python system use, user should not define like it    3. __object # private (name mangling duri

python中if __name__ == &quot;__main__&quot;:的解释

当你打开一个.py文件时,经常会在代码的最下面看到if __name__ == '__main__':,现在就来介 绍一下它的作用. 模块是对象,并且所有的模块都有一个内置属性 __name__.一个模块的 __name__ 的值取决于您如何应用模块.如果 import 一个模块,那么模块__name__ 的值通常为模块文件名,不带路径或者文件扩展名.但是您也可以像一个标准的程序样直接运行模块,在这 种情况下, __name__ 的值将是一个特别缺省"__main__". //////

【python gensim使用】word2vec词向量处理中文语料

word2vec介绍 word2vec官网:https://code.google.com/p/word2vec/ word2vec是google的一个开源工具,能够根据输入的词的集合计算出词与词之间的距离. 它将term转换成向量形式,可以把对文本内容的处理简化为向量空间中的向量运算,计算出向量空间上的相似度,来表示文本语义上的相似度. word2vec计算的是余弦值,距离范围为0-1之间,值越大代表两个词关联度越高. 词向量:用Distributed Representation表示词,通常

Python自学之旅 #新手#MacBook #《“笨办法”学Python》#第六章:常用的简易Python命令、符号、代码、格式化字符串

第六章:常用的简易Python命令.符号.代码.字符串 <“笨办法”学Python>这本书中,确实用了较多篇幅来介绍Python的一些常用简单的命令.符号.代码和字符串等,对于像我这样的自学新手,真的是非常棒,因为它们可以帮我建立接着学下去的信心和兴趣.但我在这个系列的博客当中,不打算写的这么精细,首先因为这不符合我写博的初衷和习惯,其次因为我不打算靠这写书来挣钱,最后因为我确实没有那个实力去挖掘简单东西中更深奥复杂的应用.所以,我写的这个博客,只适合像我这样的自学新手,如果想要成为大神,还是