Glove算法报告

  • 算法简介

我觉得Glove算法非常的厉害,它是一种训练词向量的方法。它结合了俩种经典算法:一个是基于奇异值分解(SVD)的LSA算法,另一个是word2vec算法。

Glove的算法模型:

X代表单词间共同出现次数的矩阵

Xij代表单词j在单词i上下文窗口中出现的次数。

Xi代表所有在单词i上下文窗口中均出现单词的次数之和。

Pij=P(j|i)=Xij/Xi表示单词j在单词i上下文中出现的概率。

作者希望训练得到的词向量具有如下特性:

  1. 与冰具有相似属性单词,如固体(solid),要求P冰,固体P水蒸气,固体 值很大
  2. 与水蒸气具有相似属性单词,如气体(gas),要求P冰,气体P水蒸气,气体 值很小
  3. 与冰、水蒸气不相关单词,如时尚(fashion),要求P冰,时尚P水蒸气,时尚 值接近1

就是词向量开始学习时候的初值或者起点应该是共现概率的比率,而不是这些概率本身。在提出模型之前需要注意的点是一个词在GloVe中有两个向量,一个是作为中心词的时候,一个是作为上下文词时候的向量。而模型希望有一个函数F,可以通过i,j和k的词向量拟合出这样的比率

那么如何去推导这个公式呢,如何让F函数变化来体现右边比率形式所表达的词向量之间的差异性呢,我觉得本文的作者真的脑洞大开,公式的推导真的是一步一步想出来的。因为向量空间具有线性结构,就是a和b之间存在某种关系,c和d之间存在某种关系,这两个关系相似,那么a-b应该和c-d相似。这是word2vec的效果,最著名的例子就是国王-男人=王后-女人,由此想到直接建模词表示之差来得到差异性从而拟合比率:

然后提到右边是概率的比值,是标量,而左边是词向量,两者不能做等号。作者采用了点积建模,公式转变成:

在这里,注意一下,在共现矩阵中,中心词和上下文词之间是几乎没有区别的,所以w和what应该是可以随意交换的,并且glove拟合的是一个对称矩阵。因此,作者为了解决该问题,作了俩步变化,首先将F变化,为了让分子或分母中的下标互换之后能和ratio中的对应位置上的P相等,要考虑什么函数的输入之差能映射到输出之比上 ,所以得出:

根据上面式子可以得出对应相等的部分

在这里作者解出来F就是以e为底的指数函数,即exp,所以等式变换为

可以看到如果删掉log(Xi)的话,这个等式就具备了对称性。又因为log(Xi)这一项跟k是没有关系的,所以作者觉得可以表示成wi的一个偏置bi。最后,还要加上wk 额外的偏置bk ,就能得出对称性。得出的等式为:

这个等式就是F函数的强简化版,但是这个函数的主要缺点是它是对所有共现矩阵同等看待,又由于共现矩阵是非常稀疏的,一些极少出现的词作为输入不仅仅携带很少的信息,还会添加噪音,导致计算量大大增加,因此,作者提出了新的加权的最小二乘回归模型来解决这个问题,引入了一个权重函数f来得到损失函数,因此损失函数为

其中权重函数f应该遵循三点性质:

  1. f(0)=0,若f是连续函数,那在频数趋近0的时候函数的极限应该也是0
  2. 权重函数f应该是非递减的,这样极少共现的词不会多给权重
  3. 权重函数f应该在频数值X大的时候相应地变小,这样频繁共现的词也不会多给权重,例如中文里“的,地”。

作者找到的满足性质的f函数为:

作者在经过一系列的试验后,得出α的值在0.75的时候效果最好。

二:算法代码解析:

这是glove存储单词的方式,其中*word指的是字符串,count是频数。和word2vec代码一样,这里需要解决哈希冲突的问题。在glove中采用的是使用链表,使得相同哈希的单词会通过链表串联起来

Common.c

上述几个比较函数,用于词典中单词排序以及返回单词的哈希值

该函数实现了dict的功能,能通过单词的哈希值快速的检索到单词。它是一个链表的数组,数组的大小是TSIZE,是哈希值的上限。要在这个链表数组中查找到想要的单词,首先要计算单词的哈希值,比如是15,然后再ht[15]这个链表中找到单词。

vocab_count.c

用于计算原文本的单词统计.它的输入是整个语料,它的输出是词典。词典的形式是单词以及单词在语料中出现的次数(频数)。词典是按照频数从高到低排好序的。整篇代码都是用c语言写的,但是c语言没有字典dict这个数据结构,所以作者就用c自己写了一个dict

关键代码如下:

cooccur.c

功能是从语料中建立共现矩阵,GloVe是在共现矩阵上面进行训练的。所谓共现矩阵,在GloVe中是大量的三元组<eat, food, 150>,<of, the, 100000>…cooccur.c文件生成的三元组的顺序是根据词频排好序的。比如<of, the, 100000>在<eat, food, 150>前面,因为of的频数大于eat。<of, the, 100000>在<of, mine, 1000>前面,因为the的频数大于mine。

Shuffle.c

这部分代码的功能是打乱共现矩阵中三元组的顺序。cooccur生成的三元组是排好序的。我没有尝试过用排好序的训练能得到什么结果。一个很简单的shuffle方法是把所有的都读入内存,在内存中打乱。但是在我们的内存不足以装下所有的三元组的时候怎么办?这里采用了一个两阶段的方法做shuffle,先局部shuffle,得到很多临时文件。在第二阶段,再均匀的从每个临时文件中读取三元组,放入内存。shuffle以后再写出的就是最终shuffle好的共现矩阵了。

该部分代码则是将共现矩阵CREC数组内容写进二进制文件中。

这很简单,意思就是将数字内容顺序进行打乱,交换顺序。

这部分就是之前所说的shuffle的第一个阶段,即顺序地读入文件的三元组,局部排序。

第二阶段再对之前的临时文件打乱一次,最后输出最终打乱的三元组,作为glove的输入。Num代表一共有num个临时文件。首先打开所有的临时文件,用fid来表示。然后从每个临时文件读入array_size/num个三元组,这样内存中会基本均匀的有所有临时文件的三元组,打乱他们再写出,

Glove.c

和绝大多数的词向量不同,glove的目标是通过训练词向量和上下文向量,使得它们能够重构共现矩阵。glove训练部分的代码风格和word2vec中训练部分的代码风格如出一辙,要训练的参数和word2vec的参数基本一致,都是一份词向量参数和一份上下文向量参数,维度上glove多了一个bias,所以会有区别。 该函数主要介绍了如何初始加载文件内容,

文件的内容都存储到了array数组里面。

这部分是初始化参数,开辟了vector_size+1维的空间, 其中1位是为了bias。一些参数报错会在文件中返回一些错误报告。

train_glove函数,开启多线程调用glove_thread函数去训练,跟word2vec套路一样

这里是glove的核心代码之一。通过算出词向量和上下文向量的内积,然后按照论文所说用f加权函数与差值进行相乘。Glove其实是对共现矩阵进行的遍历,对于每个当前单词Wi遍历所有Xij非零的Wj词的语境向量。

L1和L2是分别找了当前词W1和语境词W2的位置,W2那里可以看到跳跃了一个词汇表的长度,到向量存储空间的后面存储语境向量的地方。

该部分是关键代码,即更新词向量和上下文词向量的值(包括bias值),通过梯度下降方法来更新。

实验结果:

GloVe代码包括了四个.c文件

首先执行vocab_count.c这个文件的功能是扫一遍语料,建立一个字典。

执行cooccur.c文件。它的功能是从语料中建立共现矩阵,GloVe是在共现矩阵上面进行训练的。所谓共现矩阵,在GloVe中是大量的三元组<eat, food, 150>,<of, the, 100000>…cooccur.c文件生成的三元组的顺序是根据词频排好序的。比如<of, the, 100000>在<eat, food, 150>前面,因为of的频数大于eat。<of, the, 100000>在<of, mine, 1000>前面,因为the的频数大于mine。

执行第三个文件shuffle.c。这个文件是用来打乱之前生成的共现矩阵(也就是打乱三元组的顺序)。

最后执行glove.c。它会在打乱顺序的三元组上面训练词向量。

运行代码之后:

上述图片为一整个语料库中每个单词的出现次数,

该图片即为训练出来的词向量。

  • 算法总结:

Glove是结合了LSA和word2vec两者的优点。LSA是一种词向量表征工具,也是基于共现矩阵,采用了基于奇异值分解SVD的矩阵分解技术对大矩阵进行降维,但是SVD计算代价太高,并且它对于所有单词的统计权重都是一致的,而glove克服了这些缺点。Word2vec因为它是基于局部滑动窗口计算的,利用了局部上下文的特征,所以缺点就是没有充分利用所有的语料。因此Glove将这俩种特征合并到一起。

因为Glove源码是采用了C语言,而且我已经很长时间没有接触C,忘得快差不多了,所以代码看起来颇为的困难,网上搜了很多的资料,才对此有点理解。C语言没有字典这个类,因此作者自己写了一个文件来生成字典,这值得我去学习。很多函数的妙用也都get到了,后面相信自己会对代码越来越熟悉。

Glove的创新点在于它是一种新的词向量训练模型,并且能够在多个任务上取得最好的结果。相对于原始概率,概率的比值更能够区分相关和不相关的词。

Glove论文详解及代码分析相关推荐

  1. MGN网络详解以及代码分析

    MGN网络详解以及代码分析 最近阅读了云从科技最新的关于REID的论文以及相关的博客和代码,算法是基于MGN,关于网络的部分,这里记录一些自己的学习笔记. 以下是我参考的博客和代码的网址 博客: ht ...

  2. CV | Emotionally Enhanced Talking Face Generation论文详解及代码实现

    本博客主要讲解了Emotionally Enhanced Talking Face Generation(情感增强的谈话人脸生成)论文概括与项目实现,以及代码理解. Emotionally Enhan ...

  3. 6.DeepFM: A Factorization-Machine based Neural Network for CTR Prediction论文详解和代码实现

    一.总述 这篇论文来自哈工大&华为诺亚方舟实验室,主要关注如何学习user behavior背后的组合特征(feature interactions),从而最大化推荐系统的CTR.但目前的方法 ...

  4. facenet 中心损失函数(center loss)详解(代码分析)含tf.gather() 和 tf.scatter_sub()函数

    我们来解读一下,中心损失,再来看代码. 链接:https://www.cnblogs.com/carlber/p/10811396.html 我们的重点是分析代码,所以定义部分,大家详情参见上面的博客 ...

  5. 水平集详解与代码分析二

    上一节我们分析了CV模型的原理并列出了演化公式,这一节我们将通过该公式编写CV模型的C++代码,代码调用了opencv库的一些函数,可以根据自己使用的版本更改.代码一一对应公式里的各项系数. 头文件. ...

  6. 水平集详解与代码分析一

    前面我们从大体上描述了一下水平集方法的思想,实际上,各种水平集方法的区别只是在于如何构建能量函数E(C).当构建好能量泛函E(C)之后,通过水平集的思想,将曲线C用水平集函数Φ代替,再通过求解能量泛函 ...

  7. 组合模式详解附有代码案例分析(包含透明组合模式、安全组合模式的代码示例)

    组合模式 一.组合模式的概念和角色 (一).组合模式的概念 (二).组合模式的角色 二.组合模式的应用场景 三.透明组合模式的代码示例 四.安全组合模式的代码示例 五.组合模式的优缺点 (一).优点 ...

  8. 模板方法模式详解附有代码案例分析(包含模板方法模式重构JDBC操作业务代码示例)

    模板方法模式 一.模板方法模式的概念和角色 (一).模板方法模式的概念 (二).模板方法模式的角色 二.模板方法模式的应用场景 三. 模板方法模式的代码示例 四.模板方法模式重构JDBC操作业务 五. ...

  9. UNet论文详解分析

    论文地址:https://arxiv.org/abs/1505.04597 一.概要 2015年UNet的出现使得原先需要数千个带注释的数据才能进行训练的深度学习神经网络大大减少了训练所需要的数据量, ...

最新文章

  1. 【转载】 java根据ip地址获取详细地域信息
  2. 【C / C++】关于数组太大在编译器不能运行问题
  3. [大数据]-Fscrawler导入文件(txt,html,pdf,worf...)到Elasticsearch5.3.1并配置同义词过滤...
  4. python-环境安装-pycharm安装-新手入门可使用社区版
  5. cdoj 1252 24点游戏 dfs
  6. 口红会染唇是什么意思_别只知道露华浓了!这些平价口红,我吹爆!
  7. 计算机网络—物理层(思维导图)
  8. 招聘笔试c语言题库,2014年腾讯校园招聘C语言笔试题含答案
  9. 背离 - MBA智库百科
  10. 不同公式等号对齐_魔方的公式(第二版)
  11. 坚果Pro2刷魔趣系统教程
  12. Web2.0是什么:下一代软件的业务模式与设计模式
  13. Lua踩坑记录(持续更新)
  14. Lession10 常用类(正则表达式、Date Time结构、string类、Math类)
  15. 利用python爬取甲骨文图片及其对应的汉字含义,共1062个甲骨文,百度云下载
  16. c语言 字符串switch,C++中如何对字符串进行switch
  17. arcgis把jpg转成栅格图像,[转载]在ArcGIS中配准(TIF、JPEG)栅格图像并矢量化(转)...
  18. 淘宝框架atlas集成
  19. UVM TLM1.0简单介绍
  20. QQ音乐Android端120万行代码,编译耗时是怎样优化的,凭借这份《数据结构与算法》核心文档

热门文章

  1. java虚数复数计算_真实的虚数,不仅不是没用,而且还很实在
  2. YTU 计算机网络课程设计
  3. 《MATLAB语音信号分析与合成(第二版)》:第4章 语音信号的线性预测分析
  4. 系统设计 架构设计 画图工具 架构图 设计图
  5. com.alibaba.fastjson.JSONException: syntax error, pos 1, line 1, column 2
  6. TCP/UDP协议常用端口号服务
  7. 电脑小知识cmd命令大全
  8. html中的innerHTML的用法
  9. 算法:Smith数问题
  10. 有利可图网_您的基于云的应用程序可能是有利可图的产品