machine-learning-notes
  • 封面
  • 目录
  • 前言
  • 个人前言
  • 机器学习前言
    • 什么是机器学习和模式识别
    • 机器学习的应用
    • 机器学习的流程
    • 不同的机器学习算法对相同数据预测效果不同
    • 快速入门机器学习
    • 机器学习需要参考哪些书
    • 机器学习的学习路径
    • 深度学习的学习路径
    • 互联网机器学习特定岗位所需技能
  • 机器学习面试
  • 数学基础
  • 微积分
    • 泰勒展开
    • e的直观认识
    • 傅里叶变换
    • 希尔伯特空间
  • 线性代数
    • 范数
    • 矩阵求导
    • 特征值
    • 奇异值分解
  • 概率与信息论
    • 综述概率论基本定义
    • 概率论与贝叶斯先验
    • 正态分布
    • 贝叶斯概率
    • 概率符号说明
    • 共轭先验
    • 信息论
  • 数值计算与优化
    • 最小二乘法
    • 等式约束的拉格朗日乘子法
    • 凸优化
      • 凸集和凸函数
      • 凸优化问题
  • 梯度下降算法
    • 随机梯度下降SGD
    • 动量法Momentum
    • 牛顿动量Nesterov
    • AdaGrad
    • RMSprop
    • Adadelta
    • Adam
    • Nadam
    • AMSGrad
    • AdasMax
  • 概率图模型
    • 概率图模型概论
    • 概率图简介
  • 编程基础
  • linux
    • linux常用命令
    • shell
      • 输入输出重定向
  • python
    • python简介
    • python语法
      • 基础语法
      • 数据结构
      • 过程控制
      • 函数
      • 类和对象
      • 文件操作
      • 正则表达式
    • python库
      • numpy
      • pandas
      • scipy
      • matplotlib
      • scikit-learn
    • python应用
      • 排序算法
  • 数据结构与算法
    • 数据结构
    • 算法思想
      • 排序
        • 堆排序
        • 归并排序
        • 快速排序
      • 递归
    • 剑指offer
      • 链表
      • 二叉树
      • 数组
      • 字符串
      • 栈和队列
      • 递归
      • 动态规划
      • 其他
    • leetcode
    • 编程语言
      • c++
  • Hadoop
    • Hadoop简介
    • MapReduce
  • Hive
  • Spark
  • TensorFlow
    • TensorFlow1.0
      • TensorFlow基础
      • TensorFlow基础概念解析
      • TensorFlow机器学习基础
      • Tensorflow分布式架构
    • TensorFlow2.0
  • PyTorch
  • 机器学习
  • 机器学习概论
  • 特征工程
  • 感知机
  • k近邻
  • 朴素贝叶斯
  • 线性模型
    • 最大熵模型
    • 指数族分布与广义线性模型
    • 线性回归
      • Ridge回归(岭回归)
      • Lasso回归
    • Logistic回归-对数几率回归
  • 决策树
  • 支持向量机
    • 线性可分支持向量机与硬间隔最大化
    • 线性支持向量机与软间隔最大化
    • 非线性支持向量机与核函数
    • 序列最小最优化算法SMO
    • SVM总结
  • 集成学习
    • Bagging
      • 随机森林
    • Boosting
      • AdaBoost
      • GradientBoosting
        • GBDT
        • XGBoost
          • XGBoost理论
          • XGBoost实践
    • Stacking
  • 降维
    • PCA主成分分析
    • 流形学习
  • EM算法
  • HMM隐马尔科夫模型
  • CRF条件随机场
  • 聚类
    • k均值聚类
    • 高斯混合模型
  • 主题模型
    • LDA隐狄利克雷分布
  • 知识点
    • 损失函数
    • 负采样
  • 机器学习算法总结
  • 深度学习
  • 深度学习概论
  • ANN人工神经网络
  • 知识点
    • Batch Normalization
  • CNN卷积神经网络
  • 深度学习优化算法
  • RNN循环神经网络
  • LSTM长短期记忆网络
  • GRU门控循环单元
  • GNN图神经网络
    • GNN图神经网络综述
    • GCN图卷积网络
      • GCN图卷积网络初步理解
      • GCN图卷积网络的numpy简单实现
      • GCN图卷积网络本质理解
      • GCN图卷积网络全面理解
      • SEMI-SUPERVISED CLASSIFICATION WITH GRAPH CONVOLUTIONAL NETWORKS ICLR2017
  • 神经网络架构搜索
    • Weight-Agnostic-Neural-Networks Google2019
  • 强化学习
  • 强化学习概论
  • 马尔科夫决策过程
  • 动态规划
  • 无模型方法一:蒙特卡洛
  • 无模型方法二:时间差分
  • 无模型方法三:多步自举
  • 函数近似和深度网络
  • 策略梯度算法
  • 深度强化学习
  • 基于模型的强化学习
  • 强化学习前景
  • 自然语言处理
  • 自然语言处理概论
  • 自然语言
  • 语言模型和中文分词
  • word2vec
    • word2vec概述
    • word2vec算法原理
    • word2vec源码分析
    • word2vec实践
  • Seq2Seq模型和Attention机制
  • Self-Attention和Transformer
  • 知识图谱
  • 推荐系统
  • 推荐系统概论
  • 基础知识
  • 进阶知识
    • 机器学习
      • Factorization Machines ICDM2010
    • embedding
      • Network Embedding
        • LINE: Large-scale Information Network Embedding
    • 深度学习
      • DeepFM: A Factorization-Machine based Neural Network for CTR Prediction 2017
      • DSSM: Learning Deep Structured Semantic Models for Web Search using Clickthrough Data CIKM2013
    • 图卷积网络
      • Graph Convolutional Neural Networks for Web-Scale Recommender Systems KDD2018
    • 强化学习
      • DRN基于深度强化学习的新闻推荐模型
  • 业界应用
    • YouTube
      • Deep Neural Networks for YouTube Recommendations RecSys2016
    • Alibaba
      • Learning Tree-based Deep Model for Recommender Systems KDD2018
      • Deep Interest Network for Click-Through Rate Prediction KDD2018
      • DSIN:Deep Session Interest Network for Click-Through Rate Prediction IJCAI2019
Powered by GitBook
On this page
  • word2vec源码解析
  • word2vec源码
  • word2vec流程图
  • 预处理
  • 构建词库
  • 构建词库的过程
  • 对词的哈希处理
  • 对低频词的处理
  • 根据词频对词库中的词排序
  • 初始化网络结构
  • 初始化网络参数
  • Huffman树的构建
  • 负样本选中表的初始化
  • 多线程模型训练
  • TensorFlow上构建Word2Vec词嵌入模型
  • 参考资料
  • 代码

Was this helpful?

  1. word2vec

word2vec源码分析

Previousword2vec算法原理Nextword2vec实践

Last updated 5 years ago

Was this helpful?

word2vec源码解析

在阅读本文之前,建议首先阅读上一小节的“word2vec的算法原理”,掌握如下的几个概念:

  • 什么是统计语言模型

  • 神经概率语言模型的网络结构

  • CBOW模型和Skip-gram模型的网络结构

  • Hierarchical Softmax和Negative Sampling的训练方法

  • Hierarchical Softmax与Huffman树的关系

有了如上的一些概念,接下来就可以去读word2vec的源码。在源码的解析过程中,对于基础知识部分只会做简单的介绍,而不会做太多的推导,原理部分会给出相应的参考地址。

在wrod2vec工具中,有如下的几个比较重要的概念:

  • CBOW

  • Skip-Gram

  • Hierarchical Softmax

  • Negative Sampling

其中CBOW和Skip-Gram是word2vec工具中使用到的两种不同的语言模型,而Hierarchical Softmax和Negative Sampling是对以上的两种模型的具体的优化方法。

word2vec源码

word2vec流程图

在word2vec工具中,主要的工作包括:

  • 预处理。即变量的声明,全局变量的定义等;

  • 构建词库。即包含文本的处理,以及是否需要有指定词库等;

  • 初始化网络结构。即包含CBOW模型和Skip-Gram模型的参数初始化,Huffman编码的生成等;

  • 多线程模型训练。即利用Hierarchical Softmax或者Negative Sampling方法对网络中的参数进行求解;

  • 最终结果的处理。即是否保存和以何种形式保存。

对于以上的过程,可以由下图表示:

在接下来的内容中,将针对以上的五个部分,详细分析下在源代码中的实现技巧,以及简单介绍我在读代码的过程中对部分代码的一些思考。

预处理

构建词库

在word2vec源码中,提供了两种构建词库的方法,分别为:

  • 指定词库:ReadVocab()方法

  • 从词的文本构建词库:LearnVocabFromTrainFile()方法

构建词库的过程

从指定词库生成词库

从词的文本构建词库

在这里,我们以从词的文本构建词库为例(函数LearnVocabFromTrainFile())。构建词库的过程如下所示:

对词的哈希处理

对低频词的处理

根据词频对词库中的词排序

初始化网络结构

有了以上的对词的处理,就已经处理好了所有的训练样本,此时,便可以开始网络结构的初始化和接下来的网络训练。网络的初始化的过程在InitNet()函数中完成。

初始化网络参数

在初始化的过程中,主要的参数包括词向量的初始化和映射层到输出层的权重的初始化,如下图所示:

在初始化的过程中,映射层到输出层的权重都初始化为0,而对于每一个词向量的初始化,作者的初始化方法如下代码所示:

for (a = 0; a < vocab_size; a++) for (b = 0; b < layer1_size; b++) {
    next_random = next_random * (unsigned long long)25214903917 + 11;
    // 1、与:相当于将数控制在一定范围内
    // 2、0xFFFF:65536
    // 3、/65536:[0,1]之间
    syn0[a * layer1_size + b] = (((next_random & 0xFFFF) / (real)65536) - 0.5) / layer1_size;// 初始化词向量
}

首先,生成一个很大的next_random的数,通过与“0xFFFF”进行与运算截断,再除以65536得到[0,1]之间的数,最终,得到的初始化的向量的范围为:[−0.5/m,0.5/m],其中,m为词向量的长度。

Huffman树的构建

word2vec里是拿数组实现word2vec,效率很高,在学校里经常见到的是递归迭代实现Huffman树,这对于处理大量叶子节点的问题不是一个最佳方法。

在层次Softmax中需要使用到Huffman树以及Huffman编码,因此,在网络结构的初始化过程中,也需要初始化Huffman树。在生成Huffman树的过程中,首先定义了3个长度为vocab_size*2+1的数组:

long long *count = (long long *)calloc(vocab_size * 2 + 1, sizeof(long long));
long long *binary = (long long *)calloc(vocab_size * 2 + 1, sizeof(long long));
long long *parent_node = (long long *)calloc(vocab_size * 2 + 1, sizeof(long long));

首先,设置两个指针pos1和pos2,分别指向最后一个词和最后一个词的后一位,从两个指针所指的数中选出最小的值,记为min1i,如果pos1所指的值最小,则此时将pos1左移,再比较pos1和pos2所指的数,选择出最小的值,记为min2i,将它们的和存储到pos2所指的位置。并将此时pos2所指的位置设置为min1i和min2i的父节点,同时,记min2i所指的位置的编码为1,如下代码所示:

// 设置父节点
parent_node[min1i] = vocab_size + a;
parent_node[min2i] = vocab_size + a;
binary[min2i] = 1;// 设置一个子树的编码为1

完整的过程如下图所示:

构建好Huffman树后,此时,需要根据构建好的Huffman树生成对应节点的Huffman编码。假设,上述的数据生成的最终的Huffman树为:

此时,count数组,binary数组和parent_node数组分别为:

在生成Huffman编码的过程中,针对每一个词(词都在叶子节点上),从叶子节点开始,将编码存入到code数组中,如对于上图中的“R”节点来说,其code数组为{1,0},再对其反转便是Huffman编码:

vocab[a].codelen = i;// 词的编码长度
vocab[a].point[0] = vocab_size - 2;
for (b = 0; b < i; b++) {
    vocab[a].code[i - b - 1] = code[b];// 编码的反转
    vocab[a].point[i - b] = point[b] - vocab_size;// 记录的是从根结点到叶子节点的路径
}

注意:这里的Huffman树的构建和Huffman编码的生成过程写得比较精简。

负样本选中表的初始化

如果是采用负采样的方法,此时还需要初始化每个词被选中的概率。在所有的词构成的词典中,每一个词出现的频率有高有低,我们希望,对于那些高频的词,被选中成为负样本的概率要大点,同时,对于那些出现频率比较低的词,我们希望其被选中成为负样本的频率低点。这个原理于“轮盘赌”的策略一致。在程序中,实现这部分功能的代码为:

// 生成负采样的概率表
void InitUnigramTable() {
        int a, i;
        double train_words_pow = 0;
        double d1, power = 0.75;
        table = (int *)malloc(table_size * sizeof(int));// int --> int
        for (a = 0; a < vocab_size; a++) train_words_pow += pow(vocab[a].cn, power);
        // 类似轮盘赌生成每个词的概率
        i = 0;
        d1 = pow(vocab[i].cn, power) / train_words_pow;
        for (a = 0; a < table_size; a++) {
                table[a] = i;
                if (a / (double)table_size > d1) {
                        i++;
                        d1 += pow(vocab[i].cn, power) / train_words_pow;
                }
                if (i >= vocab_size) i = vocab_size - 1;
        }
}

多线程模型训练

TensorFlow上构建Word2Vec词嵌入模型

本文详细介绍了 word2vector 模型的模型架构,以及 TensorFlow 的实现过程,包括数据准备、建立模型、构建验证集,并给出了运行结果示例。

参考资料

"word2vec源码解析"一节主要参考此文章。

从此文知道了Huffman树的作用和HS的负反馈就是其哈夫曼树的根结点。

源码注释参考上述几个文档。

这是word2vec的使用说明。

代码

代码架构讲解分析:

局部代码解读:

具体使用:

原始

GitHub:

Google-Code:

其中,count数组中前vocab_size存储的是每一个词的对应的词频,后面初始化的是很大的数,已知词库中的词是按照降序排列的,因此,构建Huffman树的过程如下所示(对于Huffman树的原理,可以参见博文“”):

返回顶层目录
返回上层目录
dav/word2vec
google-code:word2vec
数据结构和算法——Huffman树和Huffman编码
在TensorFlow上构建Word2Vec词嵌入模型
机器学习算法实现解析——word2vec源码解析
深度学习笔记——Word2vec和Doc2vec原理理解并结合代码分析
word2vec之源码注释
基于深度学习的自然语言处理(Word2vec源码分析-2上)
基于深度学习的自然语言处理(Word2vec源码分析-2下)
word2vec 源代码 完整注释
word2vec源码解析之word2vec.c
word2vec使用说明
word2vec代码流程图
word2vec之源码注释
基于深度学习的自然语言处理(Word2vec源码分析-2上)
基于深度学习的自然语言处理(Word2vec源码分析-2下)
word2vec源码解析之word2vec.c
word2vec 源代码 完整注释
word2vec 源码分析word2vec.c
机器学习算法实现解析——word2vec源码解析
word2vec源码阅读-词典的建立
使用word2vec(C语言版本)训练中文语料 并且将得到的vector.bin文件转换成txt文件
http://suhui.github.io/word2vec
http://pskun.github.io/machine learning/word2vec-source-code-analysis.html
https://zhuanlan.zhihu.com/p/40557458
https://zhuanlan.zhihu.com/p/40558913
http://jacoxu.com/word2vector/
https://blog.csdn.net/lingerlanlan/article/details/38232755
https://blog.csdn.net/google19890102/article/details/51887344
https://blog.csdn.net/jingquanliang/article/details/82886645
https://www.processon.com/diagraming/5c3f5691e4b08a7683aa7ac5
https://blog.csdn.net/lingerlanlan/article/details/38232755
https://blog.csdn.net/mpk_no1/article/details/72458003
https://blog.csdn.net/leiting_imecas/article/details/72303044
https://www.zhihu.com/question/21661274
https://blog.csdn.net/zwwhsxq/article/details/77200129
word2vec-flow-chart
LearnVocabFromTrainFile-flow-chartbmp
init_net
CreateBinaryTree-huffman-tree-construction
CreateBinaryTree-huffman-tree-construction-1
CreateBinaryTree-huffman-tree-construction-2
CreateBinaryTree-huffman-tree-construction-3
CreateBinaryTree-huffman-tree-construction-4
CreateBinaryTree-huffman-tree-construction-5
CreateBinaryTree-Huffman-tree-example
CreateBinaryTree-huffman-tree-count-binary-parent-node