计算机系统应用教程网站

网站首页 > 技术文章 正文

BERT庖丁解牛(庖丁解牛的步骤)

btikc 2025-01-31 12:03:15 技术文章 22 ℃ 0 评论

BERT: Pre-training of Deep Bidirectional Transformers for Language Understandin。 微信公众号的标题容不下一篇论文的标题,真是差评啊。

BERT的全称是Bidirectional Encoder Representations from Transformers,是谷歌2018年发表的一篇paper,引用量截止目前已经超过了12677。BERT是基于transformer encoder的双向预训练语言模型,在大量NLP任务中都取得了SOTA(stat-of-the-art)的效果。现在马上都2021年了,你如果还不理解BERT,你可能已经不是一个合格的打工人了

预训练模型早已经证明能显著提升nlp任务的效果,早期的杰出工作包括word2vec,ELMO,OpenAI GPT1等。一般来说预训练模型应用到下游的方式包括feature-based和fine-tuning。feature-based的方式包括有word2vec和ELMO,给定一个词,模型输出一个向量,下游任务基于这个向量去建模。fine-tuning的方式主要有OpenAI的GPT,以及BERT,fine-tuning的方式是把预训练模型加入到训练过程中,预训练模型的参数会进行调整来更好的完成下游的任务。

BERT在预训练阶段引入了两个目标,一个是MLM(Masked language model),一个是NSP(Next sentence prediction)。论文的贡献点有3个,第一是证明了双向语言预训练模型的重要性(相比传统language model的GPT),第二描述了基于预训练模型的方式能减少大量的特征工程工作,它可以是说第一个基于fine-tuning就能在句子级别,toker级别的任务达到SOTA效果预训练模型,第三在11个NLP任务上达到了SOTA,并且部分任务效果提升明显。

先上张结构图,一图顶千言,BERT的核心基本都在下图中:


预训练模型基本都具备两段式,第一步利用大量无标注语料进行pre-training(预训练),第二步利用预训练的模型进行下游的任务fine-tuning(或Feature-based)

Pre-training: 左边的图是BERT进行预训练的过程,看红色的部分NSP和Mask LM,Mask LM简单理解就是一个完型填空,输入的时候扣掉语料中的一些词,任务就是用户上下文的信息把扣掉的这些词预测出来,MASK的策略是随机MASK掉输入句子中的15%的词。NSP预测的是Sentence B 是否是Sentence A的下一句话,是一个二分类的任务。举个例子,输入的是"["CLS"]" + 我家孩子10个[MASK]了 ["SEP"] + 他现在没有学会[MASK] + "["SEP"]", 输出是2个mask位置的字“月”和“爬”,以及这两个句子是不是上下居的关系,明显应该输出“是”。BERT在预训练阶段使用大量的语料来构造这样的训练样本来学习模型的参数。

预训练过程中这种MASK是引入双向的语言模型的核心,可以利用上下来来进行这样完型填空,但是同时可能存在一个小问题,模型预训练的时候输入的15%被MASK掉了,但是进行fine-tuning的时候输入不会被mask,这个造成了训练数据和输入数据的分布不一致。为了解决这个问题,MASK的时候做了一个小技巧,这被MASK的 15%的词以80%的概率被替换成[MASK], 10%的概率被替换成一个random的词,10%还是原来的词。为什么是80%,10%,10%呢?这个是实验的结果,你也可以100%random试试,论文中给出了几组实验结果,这种实验一般公司真做不了,太花钱了。

Fine-Tuning:右边的图是fine-tuning的过程,经过了左边的预训练任务后,预训练模型已经从大量的语料中学习了很多知识,把你学习的这些知识再拿下游的有label的数据进行训练完成任务,可以完成单句的文本分类任务,两句话的句间关系推断(文本相关性,相似性),token级别的命名实体识别(NER),QA问答等,你也可以在fine-tuning阶段做多任务学习,比如在对话系统的时候需要识别用户的意图,同时需要把该意图的实体找出来,应用BERT可以在一次训练中同时做意图识别(多分类)和NER。BERT的输出是包含了[CLS]和每个字的embedding向量,做句子分类任务是拿[CLS]后面接一层全连接就可以了;做token级别的任务使用embedding向量后接一个全连接。 BERT的巨大优势在于你完成这些NLP常见的任务工作量非常的小,同时效果非常的好,是不是惊呆了?当然不是完全没有代价的。

天下没有免费的午餐,BERT的参数量是巨大的,谷歌提供了2个版本的BERT预训练模型,BERT-base和BERT-large。base版本的model size是L=12,H=768,A=12,(关于这些参数的含义的理解需要去看Transformer的论文,如果有时间,后面单独写一篇,本文主要介绍的是BERT的思想)整体的参数量110M(1.1亿参数),large版本的model size是L=24,H=1024,A=16,整体的参数量340M,可能对于这个没有直观的印象,那就换算成钱看看吧,一个BERT-base的预训练过程需要花费100万美金(这个我理解是按谷歌云服务的计算和存储进行计价的),后面新的GPT3单次训练花费1200万美金(1750亿参数),据说训练出来的模型能写出跟人一样的文章,GPT3只放出了部分参数,怕有人利用这个做坏事,比如xxx。简单看看GPT fine-tuning写的诗,《桥上的秋菊》 黄花淡淡复丛丛,冷艳霜痕两不同。金蕊斓斑宜向日,素衣零落御秋风。是不是惊呆了?感觉很多文学从业者都要被失业了...

实验: 前面说了那么多,接下来看看实验数据,BERT论文中4个NLP任务的实验结果,效果提升确实惊人,出于文章篇幅的考虑,主要贴一些GLUE和SQuAD v2.0的实验结果。其中GLUE的实验结果如下, GLUE的全称是General Language Understanding Evalution,是一些不同的语言理解任务的集合。:

SQuAD v1.1和 SQuAD v2.0是斯坦福大学做的对话数据集, SQuAD v2.0比 SQuAD v1.1更难,加入了一些没有答案的QA对,优质的公开数据集也推动学科前进的重要基石,比如知名 斯坦福的CV数据集ImageNet,后面有机会专门写一篇文章介绍一下公开数据集, SQuAD v2.0的结果如下:

从实验结果来看,相对于以前的SOTA效果提升了确实不小。后面的BERT类预训练模型把这个结果又往前推进了不少,比如Facebook的RoBERTa,以及谷歌的XLNET,后面会单独写一下XLNET,RoBERTa这类强基准的模型。

论文中还进行了预训练任务作用的研究,是否需要NSP任务,比较LTR LM和MLM,实验结果如下图:

从BERT论文中的实验结果看是需要NSP任务的,特别是QNLI这个任务,它是一个句间关系推断的任务,其他任务看也有一些提升。而LTR看效果还是要差很多,所以双向的上下文优势还是很明显的。关于是否NSP任务, 后续的预训练模型基本都放弃了NSP任务 ,因为这个任务过于简单,对于预训练模型的帮助不大。

文章的最后介绍了基于BERT feature-based方法,上面的实验都是基于fine-tuning的方式,在BERT模型output后面加了一层classification层。基于feature-based的方式有一些特有的应用场景,首先不是所有的任务都是可以基于BERT进行fine-tuning,有一些任务所特有的模型结构,其次fine-tuning还是有一些成本的,基于feature-based方式代价更小。文中给出了CoNLL-2003 NER任务的结果:

下面的Feature-based approach从BERT拿了输出的向量后,输入一个2层BiLSTM,可以看出基于Feature-based的方式跟fine-tuning的方式已经很接近了,效果最差的是Embeddings,效果最好的concat last four Hidden

从经验来看,使用大量无监督语料训练的预训练模型对于很多NLP任务是有显著的帮助,这个看起来make sense,我们常说的读书破万卷,下笔如有神,是一个道理。 BERT提出的基于Transformer encoder的双向语言模型的架构,在这样一个架构下可以进行大量的NLP任务,并且能取得很好的效果。BERT类模型也在2018年以后得到了飞速的发展,典型的有GPT2/GPT3,ALBERT,XLNET,RoBERTa,百度和清华各自的Ernie,还有很多优秀的预训练模型,有兴趣的可以都看看,吸取一些作者的精髓的思路。

睡前还是要问一句,今天比昨天更博学了吗?

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表