点击上方,选择星标置顶,每天给你送干货

阅读大概需要11分钟

跟随小博主,每天进步一丢丢

作者: 小川Ryan

整理:机器学习与自然语言处理

原文链接:https://zhuanlan.zhihu.com/p/58425003

由于近日所做的工作与预训练模型联系比较紧密,却发现自己对几个词向量内部的细节有所遗忘了,因此打算写篇文章来拾起一些记忆,同时也方便以后供自己和他人查阅。

一、语言模型

1、n-gram model

谈到词向量则必须要从语言模型讲起,传统的统计语言模型是对于给定长度为m的句子,计算其概率分布P(w1, w2, ..., wm),以表示该句子存在的可能性。该概率可由下列公式计算得到:但实际过程中句子的长度稍长便会为估计带来很大难度,因此n-gram 模型对上述计算进行简化:假定第i个词的出现仅与其前n-1个词有关,即:实际计算中,通常采用n元短语在语料中出现的频率来估计其概率:为保留句子原有的顺序信息,我们当然希望n越大越好,但实际上当n略大时,该n元短语在语料中出现的频率就会越低,用上式估计得到的概率就容易出现数据稀疏的问题。而神经网络语言模型的出现,有效地解决了这个问题。

2、Neural Network Language Model神经网络语言模型不使用频率来估计n元短语出现的概率,而是通过神经网络训练得到一个语言模型。首先将原始文本进行one-hot编码,在分别乘以词嵌入矩阵,得到每个词的词向量表示,拼接起来作为输入层。输出层后加上softmax,将y转换为对应的概率值。模型采用随机梯度下降对进行最大化。

3、循环神经网络语言模型(RNNLM)尽管NNLM采用神经网络对句子的可能性进行预测,但其依然是采用了n-gram对运算进行了简化,而RNNLM则直接对整个句子进行建模,即直接计算RNNLM与NNLM的差别在于隐藏层的计算:其每个隐藏层的结点同时依赖于当前词的词向量输入和上一个词的隐藏态输出,这样一来,模型便能用更完整的上文信息进行学习和预测。

上述的NNLM和RNNLM的目的都是为了建立语言模型,词向量(即输入层之前的词嵌入矩阵)只是整个过程的副产物,而从C&W开始,就直接以生成词向量为目标构建模型了。由于CBOW是在C&W基础上进行的升级和简化,所以我们直接从CBOW看起。

二、Word2Vec

1、CBOW

CBOW的主要思想是将一句话中的某个词挖去,用其上下文对其进行预测。我们先来看上下文(context)中只有一个词的简单情况(即用一个词来预测一个中心词):输入层是上下文单词的one-hot编码,词典大小为V,第一个权重矩阵W为V行N列的词向量矩阵,N是词向量的维度,如常用的300维、400维等,暂且称W为"输入词向量",它的作用是把上下文单词的词向量表示出来,如此处的隐藏层并不经过非线性激活,只是将上下文单词用W表示出来的词向量的各维线性地传到下一层;矩阵W' 是W转置后的结果,暂且称为"输出词向量",其作用是表示要预测的中心词的词向量;现在要做的就是计算词典中所有词的“得分”,选出最大概率的中心词作为预测结果。

论文中采用的方法是将上下文单词的词向量与中心词的词向量做点积来表示得分,即而我们知道两个向量的做点积的结果是可以反映它们的相似度的,我认为这也是为什么将词向量用来做相似词检测效果很好的原因。将隐藏层  与  相乘,便能得到词典中所有的词与上下文的词的得分了,最后再在输出层计算softmax函数将分数归一化成概率:使得概率最大的中心词就作为预测的结果。训练过程则采用反向传播和随机梯度下降,不断更新词向量矩阵,最后通常选用"输入词向量"  作为最后的结果。

我们再来看看上下文是多个词的CBOW

用上下文的C个词来预测中心词,与上下文只有一个词的不同之处在于隐藏层不再是取一个词的词向量的各维,而是上下文C个词的词向量各维的平均值,即:其他的方面均没有太大差别,最小化损失函数得到最优的词向量。

详细的训练步骤推导,可以参见论文 word2vec Parameter Learning Explained ,文中的推导十分详尽,甚至还在附录中带初学者回顾了一遍反向传播。毕竟走马观花的所学终究都只是空中楼阁,所以强烈建议认真阅读和体会一下论文中的推导过程。

2、Skip-gram

与CBOW恰好相反,Skip-gram的主要思想是选取一个句子中的某个单词(也称中心词),用其来预测上下文的其他单词。输入层是中心词的one-hot编码,经过"输入词向量"得到其词向量表示,隐藏层为中心词词向量的各维:Skip-gram的不同在于:输出层需要计算出C个分布(C为需要预测的上下文的词数),通过分别计算每一个分布中最大概率的词确定最有可能的C个词。C个分布共用同一个“输出词向量”,同样地计算每个分布中所有词的得分:然后最小化损失函数得到最优词向量。

3、优化方法

上述未优化的CBOW和Skip-gram中,输出层后采用一般的softmax层,在预测每个词的概率时都要累加一次分母的归一化项,而指数计算的复杂度又比较高,因此一旦词典的规模比较大,预测的效率将会极其低下。在CBOW和Skip-gram中都有相应的优化方法以减小计算复杂度,我们来介绍其中的两种。

3.1  Hierarchical Softmax首先以词典中的每个词在语料中出现的次数(或频率)为权重,构建一棵哈夫曼树,叶子节点为词典中的每个词的one-hot表示,每个非叶子结点也表示为一个向量。此时,从根节点到每一个叶子节点的路径都可以由一串哈夫曼编码来表示,如假设向左结点为0,向右结点为1,上图中的“cat”就可以表示为01.

在预测过程中,每一个非叶子结点都用自身的向量表示来做一次二分类(如使用逻辑回归),分类的结果便导向其是去到左结点还是右结点,这样一来,预测为"cat"的概率就可表示为P(结点1==0)*P(结点5==1)了,更复杂的树结构也以此类推。此法在预测某一个特定的词的概率时就只需考虑从根节点到该叶子结点这几步了,使预测的效率大大提升。

再来看论文中的正式解释: 表示 从根节点到 的路径长度,  表示从根节点到  的第  个内部结点,每个内部结点的向量表示为  , 其可以由上述的"输出词向量"得到。那么,预测为某个词的概率可按下式计算:函数[[x]]定义为: 表示结点n的左孩子结点,  为隐藏层的输出。定义内部节点向左的概率为则向右的概率为那么图中预测为  的概率为最小化损失函数详细的公式推导可以参见博客:

https://blog.csdn.net/itplus/article/details/37969979以及一个讲得比较到位的视频:https://www.bilibili.com/video/av6475775?from=search&seid=8126638077872162758

3.2 Negative Sampling(负采样)

负采样的目的依然是为改善在预测每一个词的概率时,普通softmax需要累加一次归一化项带来的高计算成本问题,其核心思想是将对每一个词概率的预测都转化为小规模的监督学习问题。具体地,对于语料中的某个句子,如“I want a glass of orange juice to go along with my cereal.”选取"orange"为上文,然后把预测为"juice"标记为1(即正样本),再选取句子中的k个其他词为负样本,假如k=4,就像这样:

再将采样到的这些样本用来训练一个逻辑回归模型。这样一来,在预测"orange"一词下文出现的词的概率时,尽管还是需要迭代比较多次来看哪个词的概率最大,但在每次迭代时,计算softmax时:

分母的归一化项就不用再像上式这样累加词典中所有的词,仅需要累加采样到的5个词就好了,同样大大地提高了训练效率。至于k的选取,Mikolov的论文中提及对于规模比较小的语料,k一般选在5到20之间,规模较大则控制在5以内。

关键是如何采样?如果按照词频的观测分布采样的话,那每次都很可能采样到"a","the","of"等这种不具备太大实际意义的词,因此论文中提出subsample的思想:如果词w的频率高于某个阈值t,则以P(w)的概率在采样时跳过这个词:

实际训练中还有一个小trick, 设f(wi)为词wi在词典中的观测概率,则以P(wi)的概率对wi进行采样:至于为何取这个值效果比较并没有相应的理论证明

关于负采样训练过程的详细推导参见博客:

https://blog.csdn.net/itplus/article/details/37998797

通俗易懂版的介绍则可参见吴恩达老师的教程:

https://mooc.study.163.com/course/2001280005?tid=2001391038&_trace_c_p_k2_=a3ea1bdb753c414994abbc51519cd5f7#/info

这个专题将分成三次发布,下一次会详细介绍Glove和Fasttext,再下一次介绍Elmo,GPT以及Bert,敬请期待!

参考文献

[1] Xin Rong, word2vec Parameter Learning Explained

[2] 来斯惟,基于神经网络的词和文档语义向量表示方法研究

[3] Tomas Mikolov,Distributed Representations of Words anand their Compositionality

[4]博客:Word2Vec中的数学原理


方便交流学习,备注:昵称-学校(公司)-方向,进入DL&NLP交流群。

方向有很多:机器学习、深度学习,python,情感分析、意见挖掘、句法分析、机器翻译、人机对话、知识图谱、语音识别等。

记得备注呦

推荐阅读:

【ACL 2019】腾讯AI Lab解读三大前沿方向及20篇入选论文

【一分钟论文】IJCAI2019 | Self-attentive Biaffine Dependency Parsing

【一分钟论文】 NAACL2019-使用感知句法词表示的句法增强神经机器翻译

【一分钟论文】Semi-supervised Sequence Learning半监督序列学习

【一分钟论文】Deep Biaffine Attention for Neural Dependency Parsing

详解Transition-based Dependency parser基于转移的依存句法解析器

经验 | 初入NLP领域的一些小建议

学术 | 如何写一篇合格的NLP论文

干货 | 那些高产的学者都是怎样工作的?

一个简单有效的联合模型

近年来NLP在法律领域的相关研究工作


从Word2Vec到Bert,聊聊词向量的前世今生(一)相关推荐

  1. 【词向量】从Word2Vec到Bert,聊聊词向量的前世今生(一)

     机器学习算法与自然语言处理推荐  来源:https://zhuanlan.zhihu.com/p/58425003 作者:小川Ryan [机器学习算法与自然语言处理导读]BERT并不是凭空而来,如何 ...

  2. 【Word2Vec】word2vec是如何得到词向量的?

    前言 word2vec是如何得到词向量的?这个问题比较大.从头开始讲的话,首先有了文本语料库,你需要对语料库进行预处理,这个处理流程与你的语料库种类以及个人目的有关,比如,如果是英文语料库你可能需要大 ...

  3. word2vec中单词向词向量的转换过程详解

    目录 前言: 1.Word2Vec两种模型的大致印象 2.CBOW模型流程举例 3.CBOW模型流程举例 总结: 目录 前言: 针对word2vec是如何得到词向量的?这篇文章肯定能解决你的疑惑.该篇 ...

  4. bert获得词向量_NLP中的词向量对比:word2vec/glove/fastText/elmo/GPT/bert

    作者:JayLou,NLP算法工程师 知乎专栏:高能NLP之路 https://zhuanlan.zhihu.com/p/56382372 本文以QA形式对自然语言处理中的词向量进行总结:包含word ...

  5. bert获得词向量_词向量详解:从word2vec、glove、ELMo到BERT

    目前,词向量(又叫词嵌入)已经成为NLP领域各种任务的必备一步,而且随着bert elmo,gpt等预训练模型的发展,词向量演变为知识表示方法,但其本质思想不变.学习各种词向量训练原理可以很好地掌握N ...

  6. bert获得词向量_无监督语义相似度匹配之Bert抽取文本特征实战

    今天记一次采用bert抽取句子向量的实战过程,主要是想感受一下bert抽取出来的句子特征向量是否真的具有不错的语义表达. 在此之前,我们来回顾一下,如果我们想拿到一个句子的特征向量可以采用什么样的方式 ...

  7. bert获得词向量_BERT中的词向量指南

    作者:Chris McCormick 编译:ronghuaiyang 导读 在本文中,我将深入研究谷歌的BERT生成的word embeddings,并向你展示如何通过BERT生成自己的word em ...

  8. bert获得词向量_只需几行 Python 代码,即可用 BERT 玩转词嵌入!

    作者 | Anirudh_S 译者 | Sambodhi 编辑 | 张之栋 AI 前线导读: 在自然语言处理领域中,诞生于 2018 年末的 BERT 非常的"火热".强悍如 BE ...

  9. 120G+训练好的word2vec模型(中文词向量)

    从网上了解到,很多人缺少大语料训练的word2vec模型,在此分享下使用120G+语料训练好的word2vec模型. 训练语料: 百度百科800w+条,20G+ 搜狐新闻400w+条,12G+(数据下 ...

  10. bert获得词向量_Bert输入输出是什么

    1. 模型的输入/输出 BERT模型的全称是:BidirectionalEncoder Representations from Transformer.从名字中可以看出,BERT模型的目标是利用大规 ...

最新文章

  1. Android应用性能优化之使用SparseArray替代HashMap(转)
  2. C#——《C#语言程序设计》实验报告——面向对象程序设计——自动出题判分小程序
  3. Boost:bind绑定作为一个组合的测试程序
  4. php底层实现也是c语言,深入php内核,从底层c语言剖析php实现原理
  5. jQuery遍历not的用法
  6. npm上传自己的项目
  7. java 折线图 放大 缩小_可拖拉放大缩小HC折线图 | JShare
  8. C/C++入门的精髓!太全了吧,收藏夹的必备
  9. 如何通过StackStorm自动支持2万多台服务器
  10. NG Updata(升级)
  11. 在线打mysql代码_mysql 在线alter table要留神_mysql
  12. 游标sql server_SQL Server游标性能问题
  13. mysql分页优化方法
  14. uni 登录token方法_uniapp如何检验用户是否登录
  15. 复变函数与积分变换小结
  16. kuangbin专题 专题1 简单搜索
  17. 【顶会论文】165篇CoRL2020 accept论文汇总
  18. Base-calling for next-generation sequencing platforms (译文)
  19. 【爬虫】爬取个人随手记账户
  20. GitLab分支介绍

热门文章

  1. 05-python中的异常
  2. asp.net MVC Views-----Controller传递数据方法
  3. 前端面试题2016--CSS
  4. Linux中的atim、mtime、ctime
  5. ubuntu 12.04下gedit查看txt中文乱码解决办法
  6. [iOS]学习笔记3(动态性)
  7. Oracle 进程 说明
  8. Nodejs 离线文档下载
  9. 最新的Functions 类
  10. 第四十四篇 面向对象高阶