史上最小白之Bert详解

1.前言

关于BERT,张俊林博士有一篇特别好的文章:从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史
非常透彻地讲解了Bert是怎么样从NNLM->Word2Vec->ELMO->GPT->BERT一步一步发展出来地,强烈推荐大家去看那篇文章,层层深入,跟着大神的思路走,一步一步把每个知识点搞懂,看完真的会有一种醍醐灌顶的感觉。当然不能看完就完事了,别人脑子里想出来地东西毕竟是别人地,要转化成自己的知识的话还得需要自己总结提炼,于是就有了这篇我个人对于BERT不是那么专业地理解。

2.BERT原理

BERT我自己把它一句话概括成多层Transformer的双向两阶段式语言模型
怎么理解多层Transformer的双向两阶段式语言模型?我们拆开来一个一个讲。

2.1 多层Transformer

Transformer你要是看了上一篇Transformer详解应该不会陌生,BERT就是基于Transformer的模型,但是BERT只运用了Transformer的Encoder部分。多层Transformer也就是多个Encoder堆叠。Google发布了两个版本的BERT,一个Base版,一个Large版。
Base版本:L(Layers)=12,H(Hidden)=768,A(attention head)=12,Total Parameters=110M
Large版本:L(Layers)=24,H(Hidden)=1024,A(attention head)=16,Total Parameters=340M

Total Parameters为什么是110M和340M呢?怎么计算出来地?

这个地方很容易被忽略,你可以自己先算算,要是能算出来,好啦,下面的已经不用看了,你已经了解BERT了。这个计算参数问题,需要我们把BERT的每一一步都弄得明明白白才能算出来,接下里我们就以Base BERT为例一起算一下吧。

第一步,先来计算Bert的输入部分参数:
在这里插入图片描述
通过上图我们可以看到BERT的输入部分由3部分组成:
Token Embedding:单词的Embedding
Segment Embedding:句子的Embedding,BERT的训练数据都是由两个句子构成的,那么每个句子有个句子整体的embedding项对应给每个单词
Position Embedding:位置Embedding,NLP中单词顺序是很重要的特征,需要在这里对位置信息进行编码,用来表示每个单词在输入序列中的位置信息

BERT的词表大小vocab_size=32000,那么每个词可以表示成32000维的one-hot向量;BERT的max_length=512,也就是可以接收的最大输入句子的长度,那么每个单词的位置信息可以表示成512维的one-hot向量;BERT的训练数据接收的是句子对,那么就可以用2维的one-hot向量表示两个不同的句子。
在这里插入图片描述
上图是神经网络语言模型NNLM的结构,BERT的Hidden=768,也就是上图中的N=768,上面说的单词,位置,和句子的one-hot向量首先均需要通过神经网络语言模型输入到隐藏层的映射,在这一步,就以一个单词为例,可以发现这里的参数计算其实与输入序列的长度是没有关系地,单词one-hot向量(1,32000),需要的参数矩阵为(32000,768);位置one-hot向量(1,512),需要的参数矩阵为(512,768);句子one-hot向量(1,2),需要的参数矩阵为(2,768),经过这样的转换就能得到Token Embedding,Segment Embedding,Position Embedding了,然后再将这3个Embedding相加就是BERT的输入了。因此输入部分涉及的参数为: 32000 ∗ 768 + 512 ∗ 768 + 2 ∗ 768 32000*768+512*768+2*768 32000768+512768+2768

然后合并后的输入Embedding便会进入Transformer的Encoder中,Encoder又分为Multi-Heads Attention和Feed Forward。

第二步计算 Multi-Heads Attention 参数:
在这里插入图片描述
在Multi-Heads Attention输入Embedding需要经过 W Q , W K , W V W^Q,W^K,W^V WQ,WK,WV转换生成Q,K,V,怎么确定 W Q , W K , W V W^Q,W^K,W^V WQ,WK,WV的维度呢,因为BERT输入的句子最大长度为512,句子长度小于512用0补齐,大于512截断。故输入的序列Embedding矩阵的维度为(512,768),dmodel=768 也就是一个单词的Embedding维度, W Q , W K , W V W^Q,W^K,W^V WQ,WK,WV的维度为(dmodel,dmodel/heads)=(768,768/12)=(768,64),Base BERT是12个Heads。
在这里插入图片描述
然后通过self-attention计算Z,这样我们就得到了12个Z,然后将12个Z拼接成一个大的矩阵12个(768,64)拼接成(768,768)的大矩阵,然后需要对这个(768,768)的大矩阵用 W O W^O WO进行线性变换,维度不变依旧是(768,768),因为参数矩阵 W O W^O WO的维度也是(768,768)
在这里插入图片描述
那么Multi-Heads Attention中需要用到的参数量就是:
3 ∗ 768 ∗ 64 ∗ 12 + 768 ∗ 768 3*768*64*12+768*768 37686412+768768
在这里插入图片描述
Add&Norm中是没有参数的,只是添加一个残差块和归一化,具体可见上一篇博客Transformer详解

第三步计算Feed Forward参数:
在这里插入图片描述
在Transformer中说过,在这一步需要将输入映射到高维空间然后再变回原本的向量维度,W1就是负责映射到高维空间,W2负责恢复成原来的维度。Feed Forward的输入为(768,768)的矩阵,BERT的映射到高维度的变换使用的是4H,也就是4倍输入维度,因此W1的维度就是(768,4x768),W2的维度就是(4x768,768),故Feed Forward部分参数量为: 768 ∗ 4 ∗ 768 + 4 ∗ 768 ∗ 768 768*4*768+4*768*768 7684768+4768768

然后又进行Add&Norm,接着进入下一个Encoder,堆叠12层。

因此将这三步所有参数汇总为:
( 32000 + 512 + 2 ) ∗ 768 + 12 ∗ ( 3 ∗ 768 ∗ 64 ∗ 12 + 768 ∗ 768 + 768 ∗ 4 ∗ 768 ∗ 2 ) = 109905408 = 110 M (32000+512+2)*768+12*(3*768*64*12+768*768+768*4*768*2)=109 905 408=110M (32000+512+2)768+12(37686412+768768+76847682)=109905408=110M
为了计算方便,以上计算全部忽略了偏置b,因为b的数量相对来说比较少,暂且不计,比110M少的0.1M应该就是b的参数量。

看到这你应该知道BERT的参数量怎么计算了吧?试着参照上面Base的算法,计算看看Large BERT的参数量吧。

2.2双向

在这里插入图片描述
这里直接引用张俊林博士的原文内容:Masked双向语言模型向上图展示这么做:随机选择语料中15%的单词,把它抠掉,也就是用[Mask]掩码代替原始单词,然后要求模型去正确预测被抠掉的单词。但是这里有个问题:训练过程大量看到[mask]标记,这会引导模型认为输出是针对[mask]这个标记的,但是真正后面在进行预测任务的时候是不会有这个标记的,这自然会有问题。为了避免这个问题,Bert改造了一下,15%的被上天选中要执行[mask]替身这项光荣任务的单词中,只有80%真正被替换成[mask]标记,10%被狸猫换太子随机替换成另外一个单词,10%情况这个单词还待在原地不做改动。这就是Masked双向语音模型的具体做法。

然后就上面这段BERT预训练任务MLM(Masked Language Model)做一些简单的补充。

1.随机选择语料中的15%的单词,意思是说从输入的token中随机选择15%的token,而不是从总的BERT词表中随机选择15%。然后每次对于这部分被选出来的15%的token进行预测,因为每次只能预测输入token的15%,而且是随机地,要想将整个句子都预测出来的话需要多迭代几次,这也是为什么BERT预训练需要消耗大量时间的原因。

2.80%真正被替换成[mask]标记,10%被狸猫换太子随机替换成另外一个单词,10%情况这个单词还待在原地不做改动。引用BERT作者原论文中的例子:
在这里插入图片描述
为什么要这样分成80%,10%,10%呢?
作者在原论文中也有解释:
在这里插入图片描述
BERT是一个多任务学习模型,上面MLM只是BERT预训练中的一个任务,另一个是NSP(Next Sentence Prediction)。之前也说过BERT的训练数据是句子对的形式。

NSP,指的是做语言模型预训练的时候,分两种情况选择两个句子,一种是选择语料中真正顺序相连的两个句子;另外一种是第二个句子从语料库中抛色子,随机选择一个拼到第一个句子后面。我们要求模型除了做上述的Masked语言模型任务外,附带再做个句子关系预测,判断第二个句子是不是真的是第一个句子的后续句子。之所以这么做,是考虑到很多NLP任务是句子关系判断任务,单词预测粒度的训练到不了句子关系这个层级,增加这个任务有助于下游句子关系判断任务。

对NSP具体实现步骤做一个说明:
在这里插入图片描述
1.首先在最开始的输入阶段,我们从语料中提取出两个句子A和B,50%的概率B是A在语料中的下一句,50%的概率B是随机取地句子。
2.将这两个句子A和B打包成一个序列,[CLS] A [SEP] B [SEP]
3.然后就是生成句子标识,将序列中[CLS] A [SEP]的区域中每个单词token都对应一个相同的句子Embedding E A E_A EA, E A E_A EA怎么算,在上面将计算参数的时候应该已经说过了,B [SEP]对应一个相同的句子Embedding E B E_B EB
4.最后将[CLS]的输出当做是包含序列A 和 序列B句子语义关系信息的输出输入到分类器中
这样就完成了句子对之间关系分析的任务。

以上就是BERT的与训练部分内容了。

2.3 两阶段式模型

BERT是一个两阶段模型,分为Pre-Train 和 Fine-Tuning两阶段。上面介绍地都是BERT的Pre-Train部分,那么接下来就来看看BERT的Fine-Tuning部分。

Fine-Tuning就是在BERT预训练好的基础上再通过自己当前场景业务实际的数据来进行微调。在这里插入图片描述
上图中我看可以看到,BERT 预训练的输出其实是输入中每个Token经过训练后的Embedding值,就是每个Token的词向量,然后当我们真正在使用的时候就可以根据自己的实际业务将这些Token词向量再进行Fine-Tune微调。
可以看到输出序列依旧是 [CLS] A [SEP] B [SEP],将其作为咱们Fine-Tune的输入,那么Fine-Tune的结构也应该按照BERT的预训练结构来设计。然后训练好了之后,就可以运用到各种NLP下游task中了。

接下来说说 BERT 具体的NLP下游任务应该怎么样实现。
在这里插入图片描述
句子关系类任务:Entailment,QA,语义改写,自然语言推理等任务都是这个模式,它的特点是给定两个句子,模型判断出两个句子是否具备某种语义关系
使用BERT预训练的模型参数处理这类问题,只需要给输入加上一个起始[CLS]和终结符号[SEP],句子之间加个分隔符[SEP]即可。对于输出来说,把第一个起始符号[CLS]对应的Transformer最后一层位置上面串接一个softmax分类层即可

分类任务:文本分类,情感分析等任务,特点是不管文章有多长,总体给出一个分类类别即可
对于分类问题,咱们一般都把一句话或者一篇文档当做一个整体,那么就是输入单句,只需要给输入文本增加起始[CLS]和终结符号[SEP],输出部分与句子关系类任务一样,是要把把第一个起始符号[CLS]对应的Transformer最后一层位置上面串接一个softmax分类层即可

序列标注:这是最典型的NLP任务,比如中文分词,词性标注,命名实体识别,语义角色标注等都可以归入这一类问题,它的特点是句子中每个单词要求模型根据上下文都要给出一个分类类别。
对于序列标注问题,输入部分和单句分类是一样的,只需要输出部分Transformer最后一层的每个单词对应位置都进行softmax分类

生成式任务:比如机器翻译,文本摘要,写诗造句,看图说话等都属于这一类。它的特点是输入文本内容后,需要自主生成另外一段文字。
关于生成式任务,原论文没提及,我个人感觉之所以没提及是因为BERT是一个有监督的模型,而对于像生成任务式这种,生成一句话,是不应该有一个统一的固定的答案地,就是我个人觉得生成式任务不适合用有监督的学习解决。人工智能那么就要像人,我们人不说别人,自己对于同一张图片每一次的描述可能都不一样,同一句英语每次翻译成汉语可能也会有些微的出入,因此用给定了固定生成式答案地有监督学习解决生成式问题都是不合理地。虽然说BERT也是可以做生成式任务地,我们通过BERT得到每个单词的词向量后,然后根据自己的业务数据,输入到Seq2Seq模型中再训练就能处理生成式任务了。但我个人觉得生成式任务采用有监督的学习模型是不合理地。

3.BERT的优缺点

BERT优点:
1.效果好,相比于GPT,GPT是单向,而BERT是双向,相比与ELMO,ELMO采用的是LSTM,而BERT采用的是效果更好的特征提取器Transformer
2.几乎支持所有的NLP下游任务

BERT缺点:
1.虽然说Transformer中引入了位置编码来解决位置信息是一个还不错的解决方案,但还是存在些许不足之处,可能需要更加强大的超越Transformer的特征提取器
2.BERT参数量巨大,计算资源消耗大
3.一些可有可无的小问题,[mask]的时候每次是随机选取15%,比如”New York is a city”,假设我们Mask住”New”和”York”两个词,那么给定”is a city”的条件下”New”和”York”并不独立,因为”New York”是一个实体,看到”New”则后面出现”York”的概率要比看到”Old”后面出现”York”概率要大得多。不过BERT预训练数据量特别大,影响就基本上可以忽略了

4.结语

以上就是我个人关于BERT的一些总结,本人才疏学浅水平实在有限,如果有写得不对的地方欢迎指正~

生命不息,学习不止,大家一起加油吧,奥利给!!!

5.参考

从Word Embedding到Bert模型—自然语言处理中的预训练技术发展史
关于BERT的若干问题整理记录
word2vec原理(一) CBOW与Skip-Gram模型基础

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值