x
和 标签 y
。使得 Model
对 x
的输出越接近 y
越好y
,我们将数据分成两份,使得 Model
对其中一部分的输出越接近另一部分越好BERT 就是自监督学习,利用非 Mask 的来预测 Mask 的部分
源自Transformers
的双向编码表示。主要包含两个部分,预训练和 Fine-tuning
MASK
:一个特殊的字符,代表被盖住,不在字典里出现softmax
得到结果,这个结果和真实字的 one-hot
编码越接近越好[CLS]
放在一个序列的最前面,没有特别具体的语义。我们通过 [CLS]
对应的输出,来判断两个句子是不是连接在一起的。原文说:我们的输入表示能够在一个 token 序列中明确表示单个句子 和 一对句子。一个“句子”可以是连续文本的任意跨度,而不是一个实际的语言句子。
上图是论文中的示例。比如输入的一个序列包含两个句子,”my dog is cute”,”he likes playing”
。
[CLS]
,其在最后一个隐藏层的隐藏状态被当做整个序列的聚合表示,从而应用于分类任务[SEP]
表示一个句子的结束,以区分开不同的句子我们在进行了分词,添加了特殊 Token 之后的序列作为模型的输入。
接着对每个Token进行3个Embedding:词的Embedding,Segment的Embedding和位置的Embedding
WordPiece embedding
BERT 使用的是 MASK 语言模型。Mask语言模型有点类似与完形填空——给定一个句子,把其中某些词遮挡起来,让模型猜测可能的词。
BERT 对输入序列随机进行 15% Mask,然后预测这些被遮住的 Token。通过调整模型的参数使得模型预测正确的概率尽可能大。
但是这有一个问题:在 Pretraining Mask LM 时会出现特殊的Token [MASK],但是在后面的fine-tuning时却不会出现,这会出现Mismatch的问题。为了减轻这种不匹配,在BERT中,如果某个Token在被选中的15%个Token里,则按照下面的方式随机的执行
在有些任务中,比如问答,前后两个句子有一定的关联关系,我们希望BERT Pretraining的模型能够学习到这种关系。因此BERT还增加了一个新的任务——预测两个句子是否有关联关系。
这通过为 BERT 添加一个任务来实现:我们预训练了一个二分类的 是否是下一个句子
的任务。
当选择句子 A
和 B
作为预训练样本时,B
有 50% 的概率是 A
的真实的下一句,也有 50% 的概率是随机的一句。
比如下面两个句子是相关的
[CLS] the man went to [MASK] store [SEP] he bought a gallon [MASK] milk [SEP]
下面两个句子是不相关的
[CLS] the man [MASK] to the store [SEP] penguin [MASK] are flight ##less birds [SEP]
BERT的架构是多层的双向 Transformer encoder。这将使得我们能够获取双向的语义信息,而不是像传统方法那样,只能从左向右或者从右向左来获取单向的语义信息。
我们定义层数(Transformer blocks)为 L L L,hidden size 为 H H H ,self-attention 的头的个数为 A A A。一共提供了两版 BERT
B E R T B A S E ( L = 12 , H = 768 , A = 12 ) BERT_{BASE}(L=12, H=768, A=12) BERTBASE(L=12,H=768,A=12) ,总参数量为 110M
B E R T L A R G E ( L = 24 , H = 1024 , A = 16 ) BERT_{LARGE}(L=24,H=1024,A=16) BERTLARGE(L=24,H=1024,A=16),总参数量为 340M
E
代表 对输入进行 Embedding 的结果C
是 [CLS]
在最后一个隐藏层对应的隐藏状态T
是其它位置对应的隐藏状态Fine-tuning是简单的,因为Transformer中的 self-attention 机制提供了 BERT 对许多下游任务进行建模的能力,无论他们包含单个文本还是文本对。我们只需要替换掉输入和输出就好了。
对于每个任务,我们只需将特定于任务的输入和输出插入到BERT中,并对所有参数进行端到端微调。
在输出端,token 表示被输入到输出层用于 token 级任务,如序列标记或问题回答,而[CLS]
表示被输入到输出层用于分类,如逻辑蕴涵和情感分析
对于相似度计算等任务,输入是两个序列,如任务(a)
那样。我们用第一个特殊的 Token [CLS]
的最后一层输出,接上 softmax
进行分类,用分类的数据来进行 Fine-tuning
对于普通的分类任务,输入是一个序列。像任务(b)
那样。我们用第一个特殊的 Token [CLS]
的最后一层输出,接上 softmax
进行分类,用分类的数据来进行 Fine-tuning
第三类是问答类问题(如(c)
所示),输入是一个问题和一段很长的包含答案的文字,输出在这段文字中找到的答案。我们首先将问题和Paragraph
表示成一个很长的序列,中间用[SEP]
分开,这里假设答案是Paragraph
中一段连续的文字(Span)。BERT把寻找答案的问题转化成寻找这个Span的开始下标和结束下标的问题。
对于Paragraph的第i个Token,BERT的最后一层把它编码成 T i T_i Ti,然后我们用一个向量S(这是模型的参数,需要根据训练数据调整)和它相乘(内积)计算它是开始位置的得分,因为Paragraph的每一个Token
(当然WordPiece
的中间,比如##ing
是不可能是开始的)都有可能是开始可能,我们用softmax
把它变成概率,然后选择概率最大的作为答案的开始
类似的有个向量 T
,用于计算答案结束的位置
第四类任务是序列标注,比如命名实体识别,输入是一个句子(Token序列),除了[CLS]
和[SEP]
的每个时刻都会有输出的Tag,比如B-PER表示人名的开始。然后用输出的Tag来进行Fine-Tuning
,如任务(d)
所示
部分参考 BERT模型详解 - 李理的博客 (fancyerii.github.io)
原文地址 [1810.04805] BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding (arxiv.org)