赞
踩
NLP系列模型解析:
Transformer:https://blog.csdn.net/lppfwl/article/details/121084602
GPT系列:https://blog.csdn.net/lppfwl/article/details/121010275
BERT:https://blog.csdn.net/lppfwl/article/details/121124617
BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
2019年goole AI发表的文章,附上原文:https://paperswithcode.com/method/bert
pytorch版本代码:https://github.com/huggingface/transformers/tree/master/src/transformers/models/bert
BERT名字由来: Bidirectional Encoder Representations from Transformers
基于transformer的预训练深度双向编码语言理解模型,其特点就在于:预训练,双向
预训练代表该模型是预先训练好的通用模型,可以直接迁移应用,只需要额外添加一个输出层,在特定任务的数据集上微调即可,不需要修改模型结构
双向代表该模型是一个双向语言模型,可以在模型的每一层都充分利用每个词的前后文本信息。这点不同于之前的ELMo和GPT。
BERT属于降噪自编码语言模型,被Mask掉的单词就是加入的噪音,BERT就可以认为是对其“去噪”。而ELMo和GPT都属于自回归语言模型。
作者在论文里主要对比了ELMo和GPT,这里就简单说一下这两个模型。
目前有两种将预训练语言表征(language representations)用于下游任务的策略:feature-based和fine-tuning。
ELMo是feature-based类型,ELMo将预训练得到的language representations作为一个用于特定任务的模型( task-specific architecture)的输入,也就是说针对不同类型的下游任务,需要构建不同的模型结构。而且虽然说ELMo是双向语言模型,但是它是使用left-to-right和right-to-left 模型提取语义特征,然后再进行拼接,然后输入下游任务的模型中(The contextual representation of each token is the concatenation of the left-to-right and right-to-left representations),所以ELMo算不上是严格意义上的双向语言模型。
GPT是fine-tuning类型,它是单向语言模型,因此缺陷也很明显,就是只能利用词语前面的文本信息,没办法用到后面的信息,所以效果要比BERT差一些。(对GPT有疑问的可以看一下我的另一篇博客:https://blog.csdn.net/lppfwl/article/details/121010275)
ok,下面进入正题
BERT模型就是一个多层的transformer-encoder,这里不多说模型的结构了(对transformer有疑问的可以看一下我的另一篇博客:https://blog.csdn.net/lppfwl/article/details/121084602)
论文里对模型的结构参数介绍了以下:
这里说一下模型的输入:
不同于transformer,BERT的输入embedding由三部分组成,token embeddings和position embeddings和transformer是一样的,segment embeddings是句子编码,用于区分不同句子的,比如输入的两个句子A和B,A的句子编码就是[0]*A_len,A_len是句子A的长度,同理B的句子编码就是[1]*B_len,B_len是句子B的长度。
另外BERT中的position embeddings采用的是可学习的方式,这点和transformer也不同
可以看一下源码这里是怎么实现的,看完就懂了。
输入模型的embedding=token embeddings+segment embeddings+position embeddings
BERT的预训练不同于ELMo和GPT使用传统的从左到右或者从右到左的语言模型的训练方式,而是使用了两个训练任务:Masked LM (MLM)和Next Sentence Prediction (NSP)
作者认为传统的从左到右或者从右到左的语言模型的训练方式会限制模型的性能,因此为了让模型能够兼顾上下文信息,作者使用Masked LM方式进行预训练。
具体的实现方式就是随机mask掉一句话15%的词,将这些词用[mask]符号替代,然后让模型去预测这些被mask掉的词。但是,作者认为直接用[mask]符号替代一句话的原有词语会造成预训练和下游任务微调的不一致,因为下游任务微调的时候不会出现[mask]这个符号,因此作者采用了三种方式来mask:
1.80%的概率用[mask]符号替换词语
2.10%的概率用随机的一个符号替换词语
3.10%的概率保留原来的词语
作者在论文的附录里对比了不同mask方式的性能,有兴趣可以看看。
一些下游任务比如问答、自然语言推理等都是基于两个句子之间关系的理解,但是语言模型没办法直接获取句子之间的关系。Masked LM是token-level级别的任务,为了实现sentence-level级别的任务,作者使用了NSP。
具体的方法也很简单,每一个NSP任务的训练样本包括A和B两个句子,所有训练样本中50%的样本B是A的下一句(标签是IsNext),另外50%的样本中B是从语料中随机抽的一个句子,而不是A的下一句(标签是NotNext)。
作者在论文中也对比了不同预训练任务对模型性能的影响。
BERT的优势之一就是在迁移到下游的任务中时,只需要添加一个额外的输出层即可,不需要针对特定任务修改模型结构。在用于下游任务时,不同任务的输入也是要统一到BERT的输入形式的,具体作者在论文中给出了几个例子,如下图:
其实我觉得和GPT在用到下游任务的时候差不多,就是句子拼接成一个sequence输入模型。
BERT在11个下游任务中都得到了SOTA的效果。论文里有对一些下游任务及数据集的介绍,这个有兴趣的可以看看了解一下。
还有就是作者做了很多Ablation Studies,也就是一些trick效果的对比,包括不同mask方式、不同的预训练任务、不同模型大小对性能的影响,以验证BERT中使用的方法的有效性。
此外作者还将BERT作为feature-based模型使用,在NER(命名实体识别)也得到了不错的效果。
最后再说一下,BERT里面用的是wordpiece算法来构建词表,和GPT里面用的BPE算法都属于subword算法,有兴趣可以看看在GPT那篇博客里的介绍。
1.预训练和微调时的不一致,因为微调的时候不会出现[mask]这个符号
2.BERT假设了预训练时被 mask调的token之间是相互独立的,没有依赖关系
ok,就这么多,学习一个新的模型还是要论文、代码和网上的资料一起看,自己弄一遍代码就都懂了。
原创不易,转载请征得本人同意并注明出处!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。