word2vec词向量学习笔记

原文地址:http://blog.csdn.net/hjimce/article/details/51564783

个人微博:黄锦池-hjimce

一、使用原版word2vec工具训练

1、英文编译测试

(1)到官网到下载:https://code.google.com/archive/p/word2vec/,然后选择export 到github,也可以直接到我的github克隆:

 git clone https://github.com/hjimce/word2vec.git

(2)编译:make

(3)下载测试数据http://mattmahoney.net/dc/text8.zip,并解压

(4)输入命令train起来:

time ./word2vec -train text8 -output vectors.bin -cbow 1 -size 200 -window 8 -negative 25 -hs 0 -sample 1e-4 -threads 20 -binary 1 -iter 15

(5)测试距离功能:

./distance vectors.bin

 2、中文训练测试

(1)中文词向量:下载数据msr_training.utf8,这个数据已经做好分词工作,如果想要直接使用自己的数据,就需要先做好分词工作

(2)输入命令train起来:

time ./word2vec -train msr_training.utf8 -output vectors.bin -cbow 1 -size 200 -window 8 -negative 25 -hs 0 -sample 1e-4 -threads 20 -binary 1 -iter 15

(3)启动相似度距离测试:

./distance vectors.bin

(4)输入相关中文词:中国,查看结果:

hjimce@hjimcepc:~/workspace/word2vec$ ./distance vectors.bin
Enter word or sentence (EXIT to break): 中国Word: 中国  Position in vocabulary: 35Word       Cosine distance
------------------------------------------------------------------------中国人民        0.502711美国      0.480650中国政府        0.463177我国      0.447327亚太地区        0.444878加勒比     0.418471两国      0.408678各国      0.392190独立自主        0.391517世界      0.387604国际      0.382578中美      0.382208欧美      0.379807古巴      0.378412

二、算法学习阶段

因为这个算法是半年前所学的算法,最近只是简单复习一下,所以不打算写详细的算法流程笔记,原理等也不打算啰嗦。word2vec网络结构可以分成两种:CBOW、Skip-Gram,其实网络结构都非常简单,不过是一个三层神经网络罢了。本文只讲解CBOW网络结构算法、算法流程。

CBOW又有两种方案,一种叫层次softmax,另一种叫:negative sample。这两种方法如果看不懂也没关系,你完全可以用原始的softmax替代网络的最后一层,进行训练,只是训练速度比较慢。

1、CBOW+层次softmax算法总体流程

先讲解层次softmax的算法实现过程:

(1)根据训练语料库,创建词典,并对词典每个单词进行二叉树霍夫曼编码。

如下图所示,比如经过编码后,可能汉语词典中的“自”就被编码成了:110,“我”对应的编码就是:001。这个算法与word2vec的实现过程关系不大,具体霍夫曼编码过程代码怎么写,不懂也没关系。我们只需要记住,字典中的每个单词都会被编码,每个单词对应二叉树的叶节点,每个单词的编码结果对应于:从跟节点到达当前单词,所经过的节点路径。编码中的1、0表示右节点、左节点。

这边需要知道的是每一位编码的用处,因为每位的编码节点刚好可以对应到0、1输出标签,而且这颗二叉树节点就是神经网络的输出层神经元,具体可以看下面的图。假如在训练的时候,最后一层训练数据的输出是“自”,那么其实我们只需要训练节点root、node1、node3使得这三个节点的激活值分别为:1、1、0,这样就可以了。

因此对于层次softmax来说,神经网络的隐藏层其实是连接到二叉树的每个非叶子节点上(如果是原始的sotfmax,是直接连接到叶子节点上),然后对这些非叶子节点,根据输出单词的编码路径,对路径上的每个节点,根据对应的编码进行训练。

(2)根据定义窗口大小,截取出一个窗口内的单词作为一个样本,进行训练

这一步在word2vec里面,其实我们给出的参数值是一个max window size,然后word2vec底层生成一个随机大小的窗口,只要满足其范围在max window size 即可,这个可能是为了数据扩充吧。

(3)输入层-》隐藏层:对窗口内的左右单词(不包含自己)对应的词向量,进行累加,并求取平均向量Vavg。

(4)隐藏层-》非叶子节点:每个二叉树非叶子节点,链接到Vavg都有一个可学习的参数W,然后通过sigmoid可以得到每个非叶子节点的激活值(也表示概率值):

也就是说网络的参数除了词向量之外,还有隐藏层链接到二叉树结点的参数向量(从word2vec代码上看,我没有看到偏置参数b)。

(5)反向求导:根据输出文字的节点路径,更新路径上的每个非叶子节点链接到隐藏层的参数值w;并更新窗口内各个单词的词向量。

具体网络结构图如下所示:

采用层次softmax的优点在于加快训练速度,参数个数、预测速度没啥差别。

2、CBOW+Negative Sample

这个比较简单,所谓的Negative Sample,就是除了正样本标签之外,还需要随机抽取出词典中的其它单词作为负样本(以前是把整个词典的其它单词都当成负样本),这个还是具体看源码实现吧。

三、源码阅读阶段

    word = sen[sentence_position];//当前单词if (word == -1) continue;for (c = 0; c < layer1_size; c++) neu1[c] = 0;//隐藏层神经元激活值初始化为0for (c = 0; c < layer1_size; c++) neu1e[c] = 0;//隐藏层反向求导的误差值next_random = next_random * (unsigned long long)25214903917 + 11;b = next_random % window;//b是一个介于0~window size之间的随机数值//cbow算法,网络第一层:直接把左右窗口内的单词相加起来//sentence_position是当前单词if (cbow) {cw = 0;//算法第一步:除了当前单词之外,把上下文窗口单词的词向量相加起来for (a = b; a < window * 2 + 1 - b; a++)if (a != window){c = sentence_position - window + a;//遍历sentence_position窗口内的上下文单词if (c < 0) continue;//边界越界处理,因为一个文档的长度是0~sentence_lengthif (c >= sentence_length) continue;last_word = sen[c];if (last_word == -1) continue;for (c = 0; c < layer1_size; c++)//把左右窗口内的单词的词向量全部相加,其中layer1_size表示词向量的维度{neu1[c] += syn0[c + last_word * layer1_size];//syn0是词向量表}cw++;}if (cw){//算法第二步:平均,把上面左右单词的词向量加起来后再平均for (c = 0; c < layer1_size; c++){neu1[c] /= cw;}if (hs)//vocab[word].codelen表示当前单词的霍夫曼编码长度,下面也就遍历当前词的路径节点for (d = 0; d < vocab[word].codelen; d++){//算法第三步:启用了层次sorfmax模式,计算每个节点的概率//f是二叉树节点的输出值,下面是计算f,f是每个节点的逻辑回归概率值f = 0;l2 = vocab[word].point[d] * layer1_size;for (c = 0; c < layer1_size; c++) f += neu1[c] * syn1[c + l2];//syn1是从隐藏层到二叉树节点连接参数矩阵(可以把二叉树节点看成是神经元)//节点的label被定义为:1-code,而不是code,这个可能是为了方便计算吧// 那么节点损失函数为-[(1-code)*log(f)+code*log(1-f)]if (f <= -MAX_EXP) continue;else if (f >= MAX_EXP) continue;else f = expTable[(int)((f + MAX_EXP) * (EXP_TABLE_SIZE / MAX_EXP / 2))];//算法第四步:反向求导// 'g' is the gradient multiplied by the learning rateg = (1 - vocab[word].code[d] - f) * alpha;//梯度×学习率// Propagate errors output -> hiddenfor (c = 0; c < layer1_size; c++) neu1e[c] += g * syn1[c + l2];// Learn weights hidden -> outputfor (c = 0; c < layer1_size; c++) syn1[c + l2] += g * neu1[c];}//如果采用了negative sampleif (negative > 0)for (d = 0; d < negative + 1; d++){//正样本if (d == 0){target = word;label = 1;}//随机采样出负样本else{next_random = next_random * (unsigned long long)25214903917 + 11;target = table[(next_random >> 16) % table_size];if (target == 0) target = next_random % (vocab_size - 1) + 1;if (target == word) continue;label = 0;}l2 = target * layer1_size;f = 0;for (c = 0; c < layer1_size; c++) f += neu1[c] * syn1neg[c + l2];//同样计算输出单词,逻辑回归概率值//似然函数为-[label*log(f)+(1-label)*log(1-f)]//更新链接到当前类别(单词)节点的权值向量if (f > MAX_EXP) g = (label - 1) * alpha;else if (f < -MAX_EXP) g = (label - 0) * alpha;else g = (label - expTable[(int)((f + MAX_EXP) * (EXP_TABLE_SIZE / MAX_EXP / 2))]) * alpha;for (c = 0; c < layer1_size; c++) neu1e[c] += g * syn1neg[c + l2];for (c = 0; c < layer1_size; c++) syn1neg[c + l2] += g * neu1[c];}//从隐藏层到词向量层反向传播,更新词向量层for (a = b; a < window * 2 + 1 - b; a++) if (a != window){c = sentence_position - window + a;if (c < 0) continue;if (c >= sentence_length) continue;last_word = sen[c];if (last_word == -1) continue;for (c = 0; c < layer1_size; c++) syn0[c + last_word * layer1_size] += neu1e[c];}}}

参考文献:

1、《Efficient Estimation of Word Representations in Vector Space

2、《word2vec Explained: Deriving Mikolov et al.'s Negative-Sampling Word-Embedding Method

3、https://code.google.com/archive/p/word2vec/

深度学习(四十二)word2vec词向量学习笔记相关推荐

  1. Java多线程学习四十二:有哪些解决死锁问题的策略和哲学家就餐问题

    线上发生死锁应该怎么办 如果线上环境发生了死锁,那么其实不良后果就已经造成了,修复死锁的最好时机在于"防患于未然",而不是事后补救.就好比发生火灾时,一旦着了大火,想要不造成损失去 ...

  2. MATLAB强化学习实战(十二) 创建自定义强化学习算法的智能体

    创建自定义强化学习算法的智能体 创建环境 定义策略 自定义智能体类 智能体属性 构造函数 相关函数 可选功能 创建自定义智能体 训练自定义智能体 自定义智能体仿真 本示例说明如何为您自己的自定义强化学 ...

  3. Caffe学习记录(十二) ICNet分割网络学习二

    在ICNet分割网络训练的过程中,发生了很郁闷的事情, 首先ICNet的训练数据准备,和segnet一样,需要准备原始数据,mask 已经对应的txt文件,格式为pathofdata 空格 patho ...

  4. OpenCV学习笔记(四十一)——再看基础数据结构core OpenCV学习笔记(四十二)——Mat数据操作之普通青年、文艺青年、暴力青年 OpenCV学习笔记(四十三)——存取像素值操作汇总co

    OpenCV学习笔记(四十一)--再看基础数据结构core 记得我在OpenCV学习笔记(四)--新版本的数据结构core里面讲过新版本的数据结构了,可是我再看这部分的时候,我发现我当时实在是看得太马 ...

  5. 词向量学习笔记(一)Word2vec

    词向量学习笔记(一)Word2vec 文章目录 词向量学习笔记(一)Word2vec 一.概述 二.词向量 2.1词的独热表示one-hot 2.2 词的分布式表示 三.原理--Skip-gram和C ...

  6. 花书+吴恩达深度学习(十二)卷积神经网络 CNN 之全连接层

    目录 0. 前言 1. 全连接层(fully connected layer) 如果这篇文章对你有一点小小的帮助,请给个关注,点个赞喔~我会非常开心的~ 花书+吴恩达深度学习(十)卷积神经网络 CNN ...

  7. 系统学习NLP(十三)--词向量(word2vec原理)

    词向量简介 自然语言是一套用来表达含义的复杂系统.在这套系统中,词是表义的基本单元.在机器学习中,如何使用向量表示词? 顾名思义,词向量是用来表示词的向量,通常也被认为是词的特征向量.近年来,词向量已 ...

  8. Tensorflow深度学习之十二:基础图像处理之二

    Tensorflow深度学习之十二:基础图像处理之二 from:https://blog.csdn.net/davincil/article/details/76598474   首先放出原始图像: ...

  9. 前几帧预测 深度学习_使用深度学习从十二导联心电图预测心律失常

    上集讲到 使用深度学习 从单导联预测房颤 这一集 将继续讨论该问题 单导联心电图 对心律失常的预测作用 非常有限 因为 单导联的信号很有限 临床上需要结合 多导联心电图 判断 心律失常的类型 这一集的 ...

最新文章

  1. shardingjdbc全局表_Sharding-JDBC 分库分表概述
  2. 地址总线是单向还是双向_三端双向交流开关(TRIAC)
  3. vuex登录后设置token
  4. css注释_CSS注释示例–如何注释CSS
  5. 优秀小程序demo 源码
  6. 今日SGU 5.20
  7. IEEE期刊论文模板的查找,下载方法--
  8. 微信API接口访问慢
  9. 【初等概率论】 01
  10. 第二章:HLK-7621开发板介绍
  11. SQL Server 2008 下载及版本说明
  12. Unity中录制VR全景视频(可录制UGUI)
  13. 5G学习之路——认识CU、DU
  14. C语言编程-7_4 字符统计
  15. 微信小程序图书管理系统
  16. Microsemi Libero系列教程(全网首发)
  17. IDEA 类中找不到main方法请将main方法定义为public static void main. 否则 JavaFX 应用程序类必须扩展javafx.application.Applicati
  18. Python初学者:元组数据操作,输出元组内7的倍数以及个位是7的数
  19. C语言低配版扫雷游戏
  20. win2003 由于可用空间计算失败_幼儿编程启蒙怎么做?智能家居+ai 玩空间是最佳教具...

热门文章

  1. aspjpeg已过期_Persits.Jpeg.1错误’800a0004′ AspJpeg组件过期解决方法 - YangJunwei
  2. neostrack服务器无响应,捷安特GPS码表NeosTrack试用评测
  3. Java程序中fix time_Java Position.setFixTime方法代码示例
  4. 复制release文件到另一台电脑.exe文件无法运行_电脑技巧:电脑版微信双开(或微信多开)?用start指令可以解决...
  5. system volume information是什么文件_如何扩展Unity URP的后处理Volume组件
  6. [crypto][ipsec] 简述ESP协议的sequence number机制
  7. CodeForces - 868F Yet Another Minimization Problem
  8. vmware工具克隆linux系统步骤及配置
  9. avast从隔离区恢复后,仍无法打开被误杀文件的解决方案
  10. spring Mvc 执行原理 及 xml注解配置说明 (六)