您现在的位置是:首页 >学无止境 >bert预训练梳理网站首页学无止境

bert预训练梳理

winner8881 2024-09-07 00:01:02
简介bert预训练梳理

BERT (Bidirectional Encoder Representation Transformers) 是在2018年由Google AI 团队发布的,虽然在此前刚发布不久的ELMo模型已经相比过去带来了很大的改善,但是BERT在各主流任务上取得的成绩仍然是一个质的飞跃。可以说,此后2-3年陆续出现了很多模型都是围绕着BERT展开进一步的改善和优化,NLP迎来了雨后春笋般的发展。

那么BERT究竟有什么样的特别之处,以至于有这么多后来者争相效仿和赶超呢?从模型设计的理念中我们可以了解到BERT模型有几个关键词:预训练深度双向。在当时已有的效果最好的模型中,一种是采用feature-based方法的ELMo模型,它是通过从左向右(LTR)和从右向左(RTL)两个模型的输出拼接获得词的表示;另一种是采用预训练加fine-tune的OpenAI GPT,它是通过从左向右的单向模型来训练。单向模型的主要缺点在于不能获得足够好的词表示,在句子级任务以及分词级任务的效果都是不够好的,同时模型训练的速度也会受到限制。

BERT论文主要贡献在于验证了双向预训练模型比将两个单向预训练模型拼接起来的效果更好,另外BERT也展示了一个通用的大规模预训练模型在很多句子级和分词级任务中能够取得非常好的成绩,从而避免采用许多复杂繁重的特定任务框架。目前BERT在11个NLP下游任务中均达到了最优的效果。

模型结构剖析

BERT最核心的部分是采用了Transformer架构,所以有的学者认为BERT不是一个新的模型,而是在Transformer基础上发展过来的一套流程。具体而言,BERT是一个多层Transformer的Encoder,输入的Embedding通过一层层的Encoder进行编码转换,再连接到不同的下游任务。从卷积神经网络的发展可以知道,残差的引入使得采用深层更窄的网络比浅层更宽的网络更有利于提升性能,对于图像任务,深层的网络意味着能学到不同层次的特征,从最基本的的线、面到复杂的图像。延伸到NLP领域,增加网络的层数可以理解为词、句子、文章、语义等不同级别进行特征提取。

BERT采用了双向并行输入的方式,即将句子整个输入到模型中,而不是将单词一个接着一个地输入,这样可以充分利用GPU的性能,大大提升模型的运行效率。与此同时由于并行输入会带来单词在文本中的位置信息的丢失,因此BERT模型额外需要增加了一个位置编码输入,确保位置信息不被丢失。

针对不同的下游任务,BERT在输入层引入了两个特殊符号,一个是[CLS],放在整个输入文本序列的最前面;另一个是[SEP],对于输入为句子对的任务,将[SEP]放在两个句子的中间以及第二个句子的结尾。[CLS]对应最终输出的hidden state用作分类任务的表示,如果是单句子分类,表示输入句子的类别;如果是句子对分类,表示两个句子是相关的/不相关的、相似意思/相反意思。

BERT的输入向量由三部分组成,分别是token embedding, segment embedding和position Embedding。在分词接入token embedding之前,先进行tokenization处理。这里采用WordPiece嵌入方式,将每个单词进一步拆分成更通用的sub-word,可以避免词汇表过大及减缓OOV的问题,token embedding层再将各分词转换成固定维度的向量。segment embedding是针对句子对任务设置的,只有0和1两个值,用于区分两个句子,句子A编码为0,句子B编码为1,如果是单句子任务,所有编码都为0。position embedding表示每个单词在句子中的位置,同一个单词在不同位置中它的embedding是不同的。3个embedding的size都是(batch_size, seq_length, hidden_size),最后将3个embeddings按元素值相加,即表示BERT编码层的输入。

在这里插入图片描述

预训练模型

BERT采用两个无监督任务进行参数预训练。第一个是MLM(Masked Language Model),简单来讲就是对句子随机挖去几个空,让模型去预测这几个空原先的单词。在BERT的预训练中采取的策略是随机抽取句子中15%的单词进行处理,其中这15%的单词又按照80%-10%-10%的比例采取不同的处理方式:80%的单词用[MASK]来替换,表示需要预测的部分,10%用随机的词来替换,10%维持原单词不变。这种训练流程可以让模型学习到单词在上下文中的分布表示,此外用1.5%的随机替换(15%中的10%)也不会损害模型的理解能力。

另外一个预训练任务是NSP(Next Sentence Prediction)。对于句子对A和B,选取B的时候50%的概率是真实的A的下一句(标签IsNext),50%的概率是从语料中随机选取的句子(标签NotNext)。通过预训练NSP任务,让模型理解到两个句子之间的关系,从而能够应用于QA和NLI等下游任务中。

两个任务进行联合训练( In addition to the masked language model, we also use a “next sentence prediction” task that jointly pretrains text-pair representations. )

BERT模型通过对Masked LM任务和Next Sentence Prediction任务进行联合训练,使模型输出的每个字/词的向量表示都能尽可能全面、准确地刻画输入文本(单句或语句对)的整体信息,为后续的微调任务提供更好的模型参数初始值

在这里插入图片描述

总结

  • 预测遮挡单词是一个多分类问题,logloss
  • 预测下一个句子是一个二分类问题,交叉熵loss
  • 合并任务的目标函数就是两个任务的目标函数之和
  • 采用梯度下降方法更新合并任务模型参数

模型微调

由于Transformer采用的是自注意力机制,使得BERT模型可以应用于各种各样的下游任务。对于句子对任务,常规的做法是在计算交叉注意力之前,先单独对句子对进行编码。而BERT是将这两步合二为一,即使用自注意力机制来对句子进行编码。

对于输入是两个句子(A和B)的任务,A和B可以是意思相同的两种表述,可以是蕴涵的假设-前提对,可以是问答系统中的问题-回答对,也可以是文本分类或序列标注的文本对。而在输出侧,token表示用于分词级的分类任务,例如序列标注或问答系统;而[CLS]用于分类任务,如蕴涵分析或情感分析等。

在这里插入图片描述

预训练数据和参数

以下分项列出BERT预训练过程使用的所有数据和调试参数:

  • 数据集:BooksCorpus (单词量 800M),English Wikipedia (单词量 2,500M)
  • 主要参数:batch_size=256, epochs=40, max_tokens=512, dropout=0.1
  • 优化参数:优化器Adam, lr=1e-4, β1=0.9, β2=0.999, L2 weight decay=0.01, lr_warmup=10,000
  • 激活函数:gelu
  • 训练损失:mean MLM likelihood + mean NSP likelihood
  • 机器配置:BERT(base)使用4个云TPUs,BERT(large)使用16个云TPUs
  • 训练时长:4天
  • 加速方式:90%的步数按照128的文本长度训练,剩余10%的步数按照512的文本长度训练

微调参数

在fine-tune阶段,大部分模型参数与预训练阶段是一样的,只有batch_size, lr, epochs需要调整,推荐参数如下:

  • batch size = 16, 32
  • lr = 5e-5, 3e-5, 2e-5
  • epochs = 2, 3, 4

BERT的下游任务

特定任务的模型是通过在BERT基础上增加一个额外的输出层,BERT典型的四个下游任务分别是:

  • a. 句子对分类任务:如MNLI, QQP, QNLI, STS-B, MRPC, RTE, SWAG任务;
  • b. 单句子分类任务:如SST-2,CoLA任务;
  • c. 问答系统任务:如SQuAD v1.1任务;
  • d. 单句子标注任务:如CoNLL-2003 NER任务;
    在这里插入图片描述
    单文本分类任务
  • 对于文本分类任务,BERT模型在文本前插入一个[CLS]符号,并将该符号对应的输出向量作为整篇文本的语义表示,用于文本分类,如下图所示。可以理解为:与文本中已有的其它字/词相比,这个无明显语义信息的符号会更“公平”地融合文本中各个字/词的语义信息。
  • 比如对于sequence-level的分类任务,BERT直接取第一个[CLS] token 的final hidden state,再加一层全连接层后进行softmax来预测最终的标签。

在这里插入图片描述

  • 在NSP任务中,向量C虽然在CLS的位置上,但它包含的是输入的两句话的全部信息,把C作为特征向量输入分类器Binary,得到一个介于0-1之间的值f,其中,1是代表两句话true,0代表两句话毫无关联,依旧用将CrossEntropy(e,f)作为损失函数,用反向传播算出损失函数关于模型的梯度,然后作梯度下降来更新模型参数。 这样作预训练是因为:
  • 相邻的两句话通常有关联,这样作二分类可以强化这种关联,让embedding层包含这种关联;
  • encoder层中的self-attention层的作用恰好就是找相关性

在这里插入图片描述
业务应用基于业务上的文本数据对bert进行finetune,可以得到含有每个token embedding表示的bert网络,然后将bert网络推导serving端,可以对线上的实时文本推理得到每个实时文本的语义embedding,然后文本的语义embedding进行相似物料召回。

BERT与GPT的对比

与BERT最有可比性的模型是GPT,BERT的很多设计理念是从GPT参考过来的,目的是就是为了更好比较两个模型。二者主要区别在于:

  • BERT的训练语料更大,大概是GPT的3倍;
  • GPT仅在微调时使用[SEP]和[CLS]符号,而BERT在预训练和Fine-tune阶段都使用[SEP]和[CLS]符号;
  • BERT训练的batch_size大约是GPT的4倍;
  • GPT使用固定学习率lr=5e-5,BERT根据特定任务选择lr;

两个模型结构对比:
在这里插入图片描述

一些问题

1、为什么BERT在第一句前会加一个[CLS]标志?
BERT在第一句前会加一个[CLS]标志,最后一层该位对应向量可以作为整句话的语义表示,从而用于下游的分类任务等。

为什么选它呢,因为与文本中已有的其它词相比,这个无明显语义信息的符号会更“公平”地融合文本中各个词的语义信息,从而更好的表示整句话的语义。

具体来说,self-attention是用文本中的其它词来增强目标词的语义表示,但是目标词本身的语义还是会占主要部分的,因此,经过BERT的12层,每次词的embedding融合了所有词的信息,可以去更好的表示自己的语义。

而[CLS]位本身没有语义,经过12层,得到的是attention后所有词的加权平均,相比其他正常词,可以更好的表征句子语义。

当然,也可以通过对最后一层所有词的embedding做pooling去表征句子语义。

这里补充一下bert的输出,有两种,在BERT TF源码中对应:

一种是get_pooled_out(),就是上述[CLS]的表示,输出shape是[batch size,hidden size]。

一种是get_sequence_out(),获取的是整个句子每一个token的向量表示,输出shape是[batch_size, seq_length, hidden_size],这里也包括[CLS],因此在做token级别的任务时要注意它。

2、为什么BERT选择mask掉15%这个比例的词,可以是其他的比例吗?
BERT采用的Masked LM,会选取语料中所有词的15%进行随机mask,论文中表示是受到完形填空任务的启发,但其实与CBOW也有异曲同工之妙

从CBOW的角度,这里 p = 15 p=15 p=15%有一个比较好的解释是:在一个大小为1/p=100/15≈7的窗口中随机选一个词,类似CBOW中滑动窗口的中心词,区别是这里的滑动窗口是非重叠的。

那从CBOW的滑动窗口角度,10%~20%都是还ok的比例。

3、在BERT应用中,如何解决长文本问题?
不改变模型构造前提:

  • head-only:保存前 510 个 token (留两个位置给 [CLS] 和 [SEP] )

  • tail-only:保存最后 510 个token

  • head + tail :选择前128个 token 和最后382个 token(文本在800以内)或者前256个token+后254个token(文本大于800tokens)

  • 分段:把长文本分成几段,每段经过BERT之后再进行拼接或求平均或者接入其他网络如lstm,比如首先将输入文本(长度为L)分成k=L/510个小段落,将他们一次输入BERT得到k个段落的表示。每个段落的representation是最后一层[CLS]的hidden state,并分别使用mean pooling,max pooling and self-attention来合并所有段落的representation。

  • 另外transformer-xl 、LongFormer:用稀疏自注意力拓展模型文本容纳量等优秀设计也可以解决长文本。

  • 直接截断:从长文本中截取一部分,具体截取哪些片段需要观察数据,如新闻数据一般第一段比较重要就可以截取前边部分;

  • 抽取重要片段:抽取长文本的关键句子作为摘要,然后进入BERT;

4、bert OOV怎么解决?
如果一个单词不在词表中,则按照subword的方式逐个拆分token,如果连逐个token都找不到,则直接分配为[unknown]

Ref:

  [1].BERT 论文详细阅读笔记
  [2].Bert预训练
  [3].BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
  [4].关于BERT预训练模型,你想知道的都在这~
  [5].图解BERT模型
  [6].关于BERT中的那些为什么
  [7].Transformer、Like-Bert、对比学习、ChatGPT相关面试集锦

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。