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

各种词向量的特点:

  • One-hot:维度灾难 and 语义鸿沟;
  • 矩阵分解(LSA):利用全局语料特征,但SVD求解计算复杂度大;
  • 基于NNLM/RNNLM的词向量:词向量为副产物,存在效率不高等问题;
  • word2vec、fastText:优化效率高,但是基于局部语料;
  • glove:基于全局预料,结合了LSA和word2vec的优点;
  • elmo、GPT、bert:动态特征。

从one-hot到word2vec到elmo,可以看到技术的演进总是在现有基础上解决之前的问题,同时引出新的问题。这里总结一下比较经典的语言模型:word2vec、glove、ELMo、BERT。

word2vec

word2vec来源于2013年的论文《Efficient Estimation of Word Representation in Vector Space》,它的核心思想是利用神经网络对词的上下文训练得到词的向量化表示,训练方法:CBOW(通过附近词预测中心词)、Skip-gram(通过中心词预测附近的词):

CBOW与Skip-gram基本结构

CBOW :

NOTE:花括号内{}为解释内容.

  1. 输入层:上下文单词的onehot. {假设单词向量空间dim为V,上下文单词个数为C}
  2. 所有onehot分别乘以共享的输入权重矩阵W. {V*N矩阵,N为自己设定的数,初始化权重矩阵W}
  3. 所得的向量 {因为是onehot所以为向量} 相加求平均作为隐层向量, size为1*N.
  4. 乘以输出权重矩阵W' {N*V}
  5. 得到向量 {1*V} 激活函数处理得到V-dim概率分布 {PS: 因为是onehot嘛,其中的每一维斗代表着一个单词},概率最大的index所指示的单词为预测出的中间词(target word)
  6. 与true label的onehot做比较,误差越小越好

所以,需要定义loss function(一般为交叉熵代价函数),采用梯度下降算法更新W和W'。训练完毕后,输入层的每个单词与矩阵W相乘得到的向量的就是我们想要的词向量(word embedding),这个矩阵(所有单词的word embedding)也叫做look up table(其实聪明的你已经看出来了,其实这个look up table就是矩阵W自身),也就是说,任何一个单词的onehot乘以这个矩阵都将得到自己的词向量。有了look up table就可以免去训练过程直接查表得到单词的词向量了。

Skip-gram 

跟CBOW的原理相似,它的输入是目标词,先是将目标词映射为一个隐藏层向量,根据这个向量预测目标词上下文两个词,因为词汇表大和样本不均衡,同样也会采用多层softmax或负采样优化。

分层softmax

一般神经网络语言模型在预测的时候,输出的是预测目标词的概率,也就是说我每一次预测都要基于全部的数据集进行计算,这无疑会带来很大的时间开销。不同于其他神经网络,word2vec提出两种加快训练速度的方式,一种是Hierarchical softmax,另一种是Negative Sampling。

原始神经网络模型的输入输出框架

word2vec hierarchical softmax结构

和传统的神经网络输出不同的是,word2vec的hierarchical softmax结构是把输出层改成了一颗哈夫曼树,其中图中白色的叶子节点表示词汇表中所有的|V|个词,黑色节点表示非叶子节点,每一个叶子节点也就是每一个单词,都对应唯一的一条从root节点出发的路径。我们的目的是使得w=wO这条路径的概率最大,即: P(w=wO|wI)最大,假设最后输出的条件概率是W2最大,那么我只需要去更新从根结点到w2这一个叶子结点的路径上面节点的向量即可,而不需要更新所有的词的出现概率,这样大大的缩小了模型训练更新的时间。

我们应该如何得到某个叶子结点的概率呢?

假设我们要计算W2叶子节点的概率,我们需要从根节点到叶子结点计算概率的乘积。我们知道,本模型替代的只是原始模型的softmax层,因此,某个非叶子节点的值即隐藏层到输出层的结果仍然是uj,我们对这个结果进行sigmoid之后,得到节点往左子树走的概率p,1-p则为往右子树走的概率。关于这棵树的训练方式比较复杂,但也是通过梯度下降等方法,这里不详述,感兴趣的可以阅读论文word2vec Parameter Learning Explained。

~~~

(2)Negative Sampling 负采样

传统神经网络在训练过程中的每一步,都需要计算词库中其他词在当前的上下文环境下出现的概率值,这导致计算量十分巨大。

然而,对于word2vec中的特征学习,可以不需要一个完整的概率模型。CBOW和Skip-Gram模型在输出端使用的是一个二分类器(即Logistic Regression),来区分目标词和词库中其他的 k个词(也就是把目标词作为一类,其他词作为另一类)。下面是一个CBOW模型的图示,对于Skip-Gram模型输入输出是倒置的。

此时,最大化的目标函数如下:

其中,Qθ(D=1|w,h)为二元逻辑回归的概率,具体为在数据集 D中、输入的embedding vector θ、上下文为 h的情况下词语 w 出现的概率;公式后半部分为 k 个从 [噪声数据集] 中随机选择 kk个对立的词语出现概率(log形式)的期望值。可以看出,目标函数的意义是显然的,即尽可能的 [分配(assign)] 高概率给真实的目标词,而低概率给其他 k 个 [噪声词],这种技术称为负采样(Negative Sampling)。

这种想法来源于噪声对比评估方法(NEC),大致思想是:假设X=(x1,x2,,xTd)是从真实的数据(或语料库)中抽取样本,但是样本服从什么样的分布我们不知道,那么先假设其中的每个xi服从一个未知的概率密度函数pd。这样我们需要一个相对可参考的分布反过来去估计概率密度函数pd,这个可参考的分布或称之为噪音分布应该是我们知道的,比如高斯分布,均匀分布等。假设这个噪音分布的概率密度函数pn,从中抽取样本数据为Y=(y1,y2,,yTn)Y=(y1,y2,,yTn),而这个数据称之为噪声样本,我们的目的就是通过学习一个分类器把这两类样本区别开来,并能从模型中学到数据的属性,噪音对比估计的思想就是“通过比较而学习”。

具体来说,word2vec里面的负采样:将输出层的V个样本分为正例(Positive Sample)也就是目标词对应的项,以及剩余V1个负例(Negative Samples)。举个例子有个样本phone

number,这样wI=phone,wO=number, 正例就是number这个词,负例就是不太可能与phone共同出现的词。负采样的思想是每次训练只随机取一小部分的负例使他们的概率最小,以及对应的正例概率最大。随机采样需要假定一个概率分布,word2vec中直接使用词频作为词的分布,不同的是频数上乘上0.75,相比于直接使用频次作为权重,取0.75幂的好处可以减弱不同频次差异过大带来的影响,使得小频次的单词被采样的概率变大。

采样权重

负采样定义的损失函数如下:

损失函数,一部分是正样本(期望输出的词),另一部分是负采样随机抽取出来的负样本集合,V'wo是输出向量

如果大家理解的还不是很深的话,接下来将通过谷歌发布的tensorflow官方word2vec代码解析加深理解。代码链接:https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/word2vec/word2vec_basic.py,之后我会对代码进行详细剖析,欢迎跟踪~谢谢

glove

word2vec只考虑到了词的局部信息,没有考虑到词与局部窗口外词的联系,glove利用共现矩阵,同时考虑了局部信息和整体的信息。Count-based模型,如GloVe,本质上是对共现矩阵进行降维。首先,构建一个词汇的共现矩阵,每一行是一个word,每一列是context。共现矩阵就是计算每个word在每个context出现的频率。由于context是多种词汇的组合,其维度非常大,我们希望像network embedding一样,在context的维度上降维,学习word的低维表示。这一过程可以视为共现矩阵的重构问题,即reconstruction loss。(这里再插一句,降维或者重构的本质是什么?我们选择留下某个维度和丢掉某个维度的标准是什么?Find the lower-dimensional representations which can explain most of the variance in the high-dimensional data,这其实也是PCA的原理)。

来自论文《Glove: Global vectors for word representation》。Glove损失函数的确定

ELMO

之前介绍词向量均是静态的词向量,无法解决一次多义等问题。下面介绍三种elmo、GPT、bert词向量,它们都是基于语言模型的动态词向量。下面从几个方面对这三者进行对比:

ELMO是“Embedding from Language Models"简称。在此之前word embedding本质是个静态方式,静态的意思就是说单词训练好之后就固定了,在以后使用时,单词不会跟着上下文场景变化而变化。如Jobs is the CEO of apple,he finally eat an apple.用word2vec “apple”的表示是一样的向量,动态模型可以解决此问题。

ELMO的本质思想是:事先用一个语言模型去学习单词的word embedding, 当在使用时,单词已经具备了特定的上下文,这时候可以根据上下文的语义去调整单词的word embedding, 这样经过调整的word embedding更能表达这个上下文中具体的含义,也就解决了一词多义问题,故ELMO本质就是根据当前上下文对Word Embedding进行动态调整的过程。

Elmo采用典型的两阶段过程:第一阶段使用预训练语言模型进行训练,第二阶段当做具体的下游任务时,从预训练的网络中提取对应的词的Word Embedding作为特征补充到下游任务中。

第一阶段,预训练:采用双层双向LSTM对上下文进行编码,上下文使用静态的word embedding, 对每层LSTM,将上文向量与下文向量进行拼接作为当前向量,利用大量的预料训练这个网络。对于一个新的句子,可以有三种表示,最底层的word embedding, 第一层的双向LSTM层的输出,这一层能学习到更多句法特征,第二层的双向LSTM的输出,这一层能学习到更多词义特征。经过elmo训练,不仅能够得到word embedding, 又能学习到一个双层双向的神经网络。

第二阶段,下游任务使用:将一个新的句子作为elmo预训练网络的输入,这样该句子在elmo网络中能获得三个embedding, 可以将三个embedding加权作为word embedding, 并将此作为下游任务的输入,这被称为“Feature-based Pre-Training"。

GPT

GPT是Generative Pre-Traxining的简称。与ELMO相似,采用两阶段的模式:利用语言模型进行预训练,通过fine-tuning模式应用到下游任务。

利用语言模型进行预训练:与elmo不同的是,GPT使用transformer进行提取特征,并且是单向的transformer,只是根据上文来预测某个词,Transformer模型主要是利用自注意力(self-attention)机制的模型。

fine-tuning: 与ELMo当成特征的做法不同,OpenAI GPT不需要再重新对任务构建新的模型结构,而是直接在transformer这个语言模型上的最后一层接上softmax作为任务输出层,然后再对这整个模型进行微调。

由于不同NLP任务的输入有所不同,在transformer模型的输入上针对不同NLP任务也有所不同。具体如下图,对于分类任务直接讲文本输入即可;对于文本蕴涵任务,需要将前提和假设用一个Delim分割向量拼接后进行输入;对于文本相似度任务,在两个方向上都使用Delim拼接后,进行输入;对于像问答多选择的任务,就是将每个答案和上下文进行拼接进行输入。

BERT

BERT是“Bidirectional Encoder Representations from Transformers"的简称。

同GPT采用两阶段模式:利用双向transformer语言模型进行预训练,通过fine-tuning模式解决下游任务。

BERT创新: Masked语言模型和Next Sentence Prediction。

BERT(Bidirectional Encoder Representations from Transformers)详解(参考链接:https://plmsmile.github.io/2018/12/15/52-bert/

http://fancyerii.github.io/2019/03/09/bert-theory/#elmo):

1.总体框架:利用半监督学习一个双向语言模型,然后在下游任务中,经过该语言模型后,接其他任务。

2. BERT输入表示(如图):

句子开头有一个特殊的Token [CLS]句子结束有一个特殊的Token [SEP]如果是两个句子同时输入,则只有开头有[CLS],后面那个句子没有[CLS],只有[SEP]每个token有三个embedding,词的Embedding;位置的Embedding和Segment的Embedding词embedding不用多说,位置embedding是将位置用低维稠密向量表示,segment的embedding是为了将多个句子区分,第一个句子可能用0表示,第二个用1,只有一个句子的时候可能只用0第一个token很有用,可不能小瞧,因为它本身没有任何意义,在进行self-attention时,会获取下文所有信息(编码整个句子的语义),不像其他单词,在self-attention时获取最多的信息是来自于自己。注意这里的分词会把”playing”分成”play”和”##ing”两个Token,这种把词分成更细粒度的Word Piece的方法是一种解决未登录词的常见办法

3. BERT预训练(至关重要的两点):

Mask language model:遮掩语言模型Next Sentence Prediction:预测下一个句子(关系)4. Mask language model(遮掩语言模型):在预训练的时候,随机mask掉15%的单词,让语言模型去预测这个单词,如图(图中512是padding,规定了句子的长度):

这样的话有两个缺点:

大量mask标记,造成预训练和finetune时候的差距,因为finetune没有mask,finetune的时候用的是自己的数据集收敛很慢,但是效果好(比单向语言模型慢)关于第一条的解决方案:

80%的概率替换成[MASK],比如my dog is hairy → my dog is [MASK]10%的概率替换成随机的一个词,比如my dog is hairy → my dog is apple10%的概率替换成它本身,比如my dog is hairy → my dog is hairy这样的好处在于:BERT并不知道[MASK]替换的是哪一个词,而且任何一个词都有可能是被替换掉的,比如它看到的apple可能是被替换的词。这样强迫模型在编码当前时刻的时候不能太依赖于当前的词,而要考虑它的上下文,甚至更加上下文进行”纠错”。比如上面的例子模型在编码apple是根据上下文my dog is应该把apple(部分)编码成hairy的语义而不是apple的语义。5. Next Sentence Prediction(预测下一个句子):对于像QA、NLI等需要理解多个句子之间关系的下游任务,只靠语言模型是不够的。还需要提前学习到句子之间的关系。是一个二分类任务。输入是A和B两个句子,标记是IsNext或NotNext,用来判断B是否是A后面的句子。这样,就能从大规模预料中学习到一些句间关系。

对于这个任务,BERT会以50%的概率抽取有关联的句子(注意这里的句子实际只是联系的Token序列,不是语言学意义上的句子),另外以50%的概率随机抽取两个无关的句子,然后让BERT模型来判断这两个句子是否相关。6. 下游特定任务:

单句子分类(CLS+句子):输入是一个序列,所有的Token都是属于同一个Segment(Id=0),我们用第一个特殊Token [CLS]的最后一层输出接上softmax进行分类,用分类的数据来进行Fine-Tuning。利用CLS进行分类。

多句子分类(CLS+句子A+SEP+句子B):对于相似度计算等输入为两个序列的任务,过程如图左上所示。两个序列的Token对应不同的Segment(Id=0/1)。我们也是用第一个特殊Token [CLS]的最后一层输出接上softmax进行分类,然后用分类数据进行Fine-Tuning。利用CLS分类。

NER(CLS+句子):序列标注,比如命名实体识别,输入是一个句子(Token序列),除了[CLS]和[SEP]的每个时刻都会有输出的Tag,然后用输出的Tag来进行Fine-Tuning利用句子单词做标记。QA:CLS+问题+SEP+文章。比较麻烦,比如比如SQuAD v1.1数据集,输入是一个问题和一段很长的包含答案的文字(Paragraph),输出在这段文字里找到问题的答案。比如输入的问题是:

Where do water droplets collide with ice crystals to form precipitation?

包含答案的文字是:

... Precipitation forms as smaller droplets coalesce via collision with other raindrops or ice crystals within a cloud. ...

答案是:

”within a cloud”

我们首先把问题和Paragraph表示成一个长的序列,中间用[SEP]分开,问题对应一个Segment(id=0),包含答案的文字对于另一个Segment(id=1)。这里有一个假设,那就是答案是Paragraph里的一段连续的文字(Span)。BERT把寻找答案的问题转化成寻找这个Span的开始下标和结束下标的问题。

对于Paragraph的第i个Token,BERT的最后一层把它编码成Ti,然后我们用一个向量S(这是模型的参数,需要根据训练数据调整)和它相乘(内积)计算它是开始位置的得分,因为Paragraph的每一个Token(当然WordPiece的中间,比如##ing是不可能是开始的)都有可能是开始可能,我们用softmax把它变成概率,然后选择概率最大的作为答案的开始:

类似的有一个向量T,用于计算答案结束的位置。

总结

word2vec:

nlp中最早的预训练模型,缺点是无法解决一词多义问题.

ELMO:

优点: 根据上下文动态调整word embedding,因为可以解决一词多义问题;

缺点:1、使用LSTM特征抽取方式而不是transformer,2、使用向量拼接方式融合上下文特征融合能力较弱,伪双向。

GPT:

优点:使用transformer提取特征

缺点:使用单项的语言模型,即单向transformer.

BERT:

优点:使用双向语言模型,即使用双向transformer;使用预测目标词和下一句这中多任务学习方式进行训练。

缺点:对文本字数512限制,不利于文本生成。

参考:

https://arxiv.org/abs/1810.04805

https://zhuanlan.zhihu.com/p/35074402

https://www.zhihu.com/question/44832436/answer/266068967

https://zhuanlan.zhihu.com/p/53425736

https://www.cnblogs.com/robert-dlut/p/9824346.html

【NLP】词向量:从word2vec、glove、ELMo到BERT详解!相关推荐

  1. NLP(词向量、word2vec和word embedding)

    最近在做一些文本处理相关的任务,虽然对于相关知识有所了解,而且根据相关开源代码也可以完成相应任务:但是具有有些细节,尤其是细节之间的相互关系,感觉有些模糊而似懂非懂,所以找到相关知识整理介绍,分享如下 ...

  2. NLP发展历程从Word2Vec,GloVe,ELMo,Flair,GPT,BERT

    1.2013年,Word2vec模型,Google公司 无监督模型,与语境无关 2.2014年,GloVe模型,Stanford GLoVe:Global Vectors for Word Repre ...

  3. NLP之一文搞懂word2vec、Elmo、Bert演变

    导读 自然语言处理本质是解决文本相关的问题,我们可以把它的任务分为大致两部分:预训练产生词向量以及对词向量进行操作(下游NLP具体任务).在自然语言处理中有词向量模型word2vec.Elmo以及Be ...

  4. 词向量算法—Word2Vec和GloVe

    最近学习nlp,从CS224n视频课2019winter的课程入手,听完了前几个lecture,以及做完斯坦福课程官网上对应的编程作业之后对词向量的算法有了大致的了解. 但网上对于词向量算法好多都是一 ...

  5. NLP词向量模型总结:从Elmo到GPT,再到Bert

    词向量历史概述 提到NLP,总离开不了词向量,也就是我们经常说的embedding,因为我们需要把文字符号转化为模型输入可接受的数字向量,进而输入模型,完成训练任务.这就不得不说这个转化的历史了. 起 ...

  6. 什么是词向量?word2vec、Glove、FastText分别是什么?

    什么是词向量?word2vec.Glove.FastText分别是什么? 在任何一种基于深度学习的自然语言处理系统中,词嵌入和句子嵌入已成为重要组成部分.它们使用固定长度的稠密向量对词和句子进行编码, ...

  7. 毕业设计 - NLP:词向量Skip-gram word2vec

    文章目录 简介 0 前言 1 项目介绍 2 数据集介绍 3 项目实现 3.1 数据预处理 3.2 配置网络 3.3 网络训练 3.4 模型评估 4 最后-毕设帮助 简介 今天学长向大家介绍NLP基础 ...

  8. cs224n第二讲:简单的词向量表示:word2vec, Glove

    第二讲:简单的词向量表示:word2vec, Glove How do we represent words? 在处理所有NLP任务的时候,我们首先需要解决非常重要的一个问题(可能是最重要的):用什么 ...

  9. 词向量模型Word2Vec

    文章目录 1.词向量模型通俗解释 1.1Word2Vec 1.2如何训练词向量 1.3构建训练数据 2.CBOW与Skip-gram模型对比 2.1CBOW模型 2.2Skip-gram模型 2.2. ...

最新文章

  1. 3D 可视化,卷积、池化清清楚楚!网友:终于能看懂神经网络到底在干啥了......
  2. 利用ASP.NET2.0向导控件一步步建立与用户的交互--------提高和自定义用户体验
  3. RFID和WiFi定位技术的比较
  4. 使用jQuery queue(队列) 遇到的问题及解决方案
  5. 微信小程序中form 表单提交和取值实例详解
  6. 市面上有哪几种门_目前市面上木门的几种分类
  7. CVPR2021 | 深度解读RepVGG!
  8. 希尔排序是一种稳定的排序算法_十大经典排序算法——希尔排序
  9. 深入理解分布式系统原理与设计
  10. 张家口zec挖矿软件哪里下载_电脑小白去哪里下载正规软件?
  11. 深入浅出MyBatis:MyBatis解析和运行原理
  12. Web前端学习日记3
  13. PLC通讯实现-C#实现欧姆龙以太网通讯FINS UDP(三)
  14. 华为网络设备-二层Eth-trunk配置
  15. 面试技巧-面试官的考题
  16. 怪文書 / Dubious Document
  17. 文献计量之洛特卡定律
  18. AR增强现实的三大关键技术
  19. 第一章 车联网技术的背景、发展和各国地区的现状
  20. 谷歌浏览器无法更新解决办法

热门文章

  1. 解决Failure to find org.glassfish:javax.el:pom:3.0.1-b06-SNAPSHOT
  2. android测试环境与条件,测试环境与实际运行环境之间可能存在的差异有哪些
  3. 物联网技术西电捷通TRAIS符合性检测系统的应用研究
  4. 解决win11系统任务栏(通知区域)蓝牙图标不显示问题
  5. python路径规划算法可视化_基于粒子群算法的牙齿正畸路径规划方法python实现
  6. 62、Flutter插件通信iOS,Android实现过程<二>
  7. Ubuntu Cmake :Command not found解决方法
  8. 北京知名互联网公司(仅供参考):
  9. iPhone 6 (iOS 9.2) extractiion failed by XRY
  10. 2020永久气体气瓶充装考试及永久气体气瓶充装证考试