一文让你由浅入深了解bert的来龙去脉和原理以及bert代码实战(文本相似度为例)

预训练

2018年的bert火遍了大江南北,所以今天我们来聊一聊bert的来龙去脉,以及它的原理和使用,首先我认为bert是一个预训练的模型,在bert之前其实也有很多类似的模型,当然比较有名的elmo(就是命不好),所以我认为想要了解bert的原理之前,必须要明白什么是预训练模型。

word2vec

预训练顾名思义是为了更好的执行我们的任务而需要提前做的一些准备工作,比如我们去训练一个神经网络,而embdeding层往往是我们提前使用word2vec将词训练成为词向量,因此我们也可以将word2vec称为预训练模型。

那么新的问题来了?像word2vec已经可以把词向量做到低维稠密又包含语义为什么我们还要发明elmo或者bert呢?答案很简单word2vec不够我们用啦。或者说不能够满足需求,word2vec是不包含上下文的,或者说表达的语义不够(具体的推导和详解我会在word2vec中解释)由于word2vec的skip-gram是一个词预测周围的词,而且由于词典太大,不得不使用负采样的方式进行。我觉得这也是他对于上下文提取信息不足的原因。所以为了充分的提取每一个词的上下文信息,后来出现了elmo和bert,我们也叫他们语言模型。

elmo和bert

其实elmo和bert的目的是一样的,使我们训练的词向量能够包含上下文信息。当然他们不仅能训练出词向量嵌入到其他模型,用bert或者elmo训练出的模型有极大的泛化能力,我们可以在模型的基础上进行我们的任务,比如分类,文本相似度等,但由于bert自身的原理,他不能作为一个生成模型,所以在生成方面给nlp留了一些活路,elmo也有一些自身的弊端(其实就是两个单向的lstm肯定会存在梯度消失还有串行计算的问题)所以又后来有发展了XLNnet(以后再说),当然在判别或者预测上bert的能力还是非常强大的。

我们知道训练bert的目的是为了获取上下文信息,但是在很早很早之前我们就努力的往这方面发展了:

早期的语言模型n-gram

n-gram是比较早期的语言模型,也是最简单最常用的,举个例子:“今天周一大家都很开心去上学”,通过分词我们可以将这句话分为[“今天”,“周一”,“大家”,“都”,”很开心”,“去上学”],而这句话生成的概率可以用一个公式来表示如公式(1):

P(“今天”,“周一”,“大家”,“都”,”很开心”,“去上学”)=P(今天)P(周一│今天)P(都│今天,周一)PP(很开心│今天,周一,都)P(都│今天,周一,都,很开心)

这也是根据我们大家常用的贝叶斯定理,如公式(2):在这里插入图片描述

转换到nlp中则是公式(3):

在这里插入图片描述
根据公式我们可以知道每一个词的生成是依赖于前面的词,但并不一定是前面所有的词都和当前词是有关系的,根据马尔科夫的假设,一个词是与相邻的几个词有关,因此我们不再以一个词依赖于前面所有的词。只依赖前面一个词 或者两个词,
这样我们的公式(3)可以转变为公式(4):
在这里插入图片描述
公式(4)可以改写成公式(5)
在这里插入图片描述
当然如果当前词依赖前两个词的话可以写成公式(6):
在这里插入图片描述
依赖3个词4个词也是可以的,n-gram的大概原理就是这样,假设每个词依赖前面一个词我们叫1-gram,依赖两个时我们叫2-gram以此类推。N的时候我们称为N-gram。

skip-grim 和CBOW

根据N-gram的原理,我们知道每个词依赖于他前面的一些词,利用这种性质我们很容易计算出每个词的特征,但是实际往往不是这样的,文章中的每个词不仅与前面的词有关联,它与后面的词也有关联,考虑到这个因素,我们又发明了skip-grim 和CBOW ,一个是利用一个词预测周围的词,另一个是利用周围的词预测当前词,再使用分布式的表示方式将单词用词向量的形式表示出来,这样即低维稠密又包含语义关系,也就是我们常用的word2vec。

word2vec的局限性

但是word2vec还是不够强大,我们要得到的词是在上下文中包含的语义信息而不是当前词,如果使用skip-grim(有空再写一篇原理)预测整个文本的词不现实,计算量超级大。所以我们使用负采样的方式来计算词向量。也就导致word2vec有自身的局限性。

elmo的局限性

到了今天,nlp的发展的越来越迅速,出现了seq2seq端到端,attention,transform等深度模型,当然还有cnn,Lstm,Gru神经网络。所以人们想利用深度学习来训练我们的文本。使每个词都包含上下文信息,因此出现了elmo和bert当然现在又出现了bert的轻量级albert。在这里elmo就不跟大家细讲了,它主要使用了正反方向的两个LSTM进行预测下一个词(不是Bi-LSTM,这样会造成自己看见自己的现象)当然他也就有着LSTM的两大问题:1、梯度消失的问题 2、不能并行计算导致时间成本太高。因此科学家们想到了使用transform来进行预训练也就是bert。

Bert原理

Masked LM

我们知道bert目的是对于每个单词提取上下文的信息,但是怎么提取呢?我们知道elmo利用Lstm预测下一单词的信息,通过使用梯度下降法不断地反向传播。优化参数,从而训练出一个包含上下文信息的模型。

这个时候有个聪明的人想到了一个方法,比如给定一个句子; “今天周一大家都很开心去上学”,从这句话中随机的去将一个词打上马赛克(mask),这样这句话就表示成”今天周一大家都mask去上学“”,然后把这句话放到模型中让模型预测mask表示的是什么,不断的进行反向传播,最终模型训练出mask的上下文表示。这样不断进行循环计算使这个模型包含训练数据中每个词的上下文信息。此方法被称为“Masked LM”(MLM)如图(1)。
在这里插入图片描述
这就是bert最核心的一个原理,也就是为什么bert可以训练每一个词的上下文信息。感觉像让机器做完形填空一样

transform

但是神经网络像Lstm,Gru由于自身是时序类的模型,在这种想法上确实很难实,正好2018年5月出现了transform让这个想法成为了现实,transform利用self—attention并行的计算两两词之间的“关系”,解决了Lstm不能并行计算的问题,更没有梯度消失这样的问题存在,而且并行计算可以让计算机完成bert的想法如图(2)。
在这里插入图片描述
在这里插入图片描述

Next Sentence Prediction

当然bert还能够识别句子级别的联系,在下游任务中很多都需要句子关系,比如问答系统,语言推理等,bert在这里的原理是数据分成两个部分,一部分是连续的,另一部分是不连续的,随机输入训练数据,让bert进行预测那两个句子是连续的,那些不是连续的,从而能够提取句子之间的联系,这种方法被称为:Next Sentence Prediction。

Bert的输入

由于transform可以并行计算的原因,它也就不具备Lstm的时序类的特性,因此Bert在embedding层时加入位置信息,也就是Position Embeddings,它表示每个单词的位置,为了表示句子之间的关系,又加入Segment E

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值