BERT解读

背景

之前我们解读了ELMo和OpenAI GPT,我们发现他们直接的比较各有优缺点,不同于OpenAI GPT的单向语言模型,ELMo用的是双向语言模型,这能更好的捕捉文本语句中上下文的依赖关系,但是特征提取器方面,ELMo用的是LSTM即RNN的网络架构,OpenAI GPT用的是更强的transformer中的decoder部分进行建模。那么我们能不能结合两者的优势呢?
将transformer和双向语言模型进行融合,便得到NLP划时代的,也是当下在各自NLP下流任务中获得state-of-the-art的模型------BERT(Bidirectional Encoder Representations from Transformers), 其论文参考《BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding》

BERT的思路

结合BERT的论文我们再来分析下这几种预训练模型的方式。BERT的论文指出,预训练模型有两种方式,即feature-based 和 fine-tuning。ELMo采用的是feature-based,因为他它是先预训练一个多层lstm,每层进行线性加权得到的embedding,作为下游task-specific的任务的输入,可以看作新的特征;而OpenAI的GPT采用的是fine-tuning形式,因为它在后续训练是微调所有预训练参数。
另外从语言模型角度,GPT是完全的单向语言模型;ELMo是不完全的双向,因为LSTM本质还是分别从左算到右边,从右算到左,最后concat得到,并非真正意义的双向,另外如果网络加深,双向LSTM会出现自己看到自己的情况。为了解决这个,BERT提出了MLM(Masked Language Model)达到了真正的双向深度语言模型。

模型架构

BERT 框架分为两个步骤,pre-train和fine-tuning,pre-train由多个pre-train相关task共同训练模型参数,fine-tuning的时候用task-specific的带标签的数据进行supervised training,修正之前pre-train之后得到的所有参数,所以说对于不同的task尽管最终模型不同,pre-train的模型是一致的。

论文中指出BERT模型分为 B E R T l a r g e BERT_{large} BERTlarge B E R T b a s e BERT_{base} BERTbase B E R T l a r g e BERT_{large} BERTlarge的参数为L=24, H=1024,A=16, Total Parameters=340M, B E R T b a s e BERT_{base} BERTbase的参数为L=12, H=768, A=12, Total Parameters=110M,这里L为tranformer的层数,H为hidden state的维度,A为self-attention的head的个数。 这里要注意的是虽然 B E R T b a s e BERT_{base} BERTbase 的参数和OpenAI GPT的一致,但是由于BERT采用的是真正的双向语言模型,其transformer采用的是encoder部分,OpenAI GPT由于是单向语言模型,为避免提前看到后面的单词,需要mask当前时刻以后的单词, 即self-attention只对当前时刻t之前的单词进行,采用了masked self-attention,所以相当于用的相当于是transformer的decoder部分。

模型的输入和输出

BERT解读_第1张图片
bert的输入可以是一个句子或者多个句子,每个输入的开头都有个特殊标记[CLS],最后一层这个标记的hidden state的输出可用于下游的分类问题。当输入多个句子的时候,为了做区分,这里采用了两种方式:

  1. 学习到的segment embedding区分A句子还是B句子;
  2. 特殊符号[SEP]分割A和B句子

Token embedding这里采用WordPiece embeddings.
Position embedding用去区分单词在句子中的位置.
综上如图所示bert的输入即为segment embedding,token embedding, position embedding的叠加(均为训练得到),相对于transformer,这里多个segment embeding,并且这里segment embedding均为学习到的,所以每个单词的embedding融合了句子上下文的信息,一词多义也能得到解决。

Pre-Train BERT

这里有两个预训练任务,训练数据是 BooksCorpus 和Wikipedia,这里只忽略表格,标题,列表;并且这里采用整篇文章而不是随机shuffle的句子,有利于学习长文本的连续序列。

Task1: Masked LM (MLM)

这里做法是随机sample句子中的部分token进行mask,,然后用上下文预测被mask的token,类似于Cloze task(完形填空),具体做法是被mask的token的最后一层输出的final state后接softmax输出下一个词的概率。对于每条句子,这里随机mask 15%的token。
但是这样做是有缺点的,即被mask的token被特殊token[MASK] 代替,这就造成了pre-train和fine-tuning的不一致性,因为我们fine-tuning可是没有[MASK]这个特殊符号的。为了减轻这个不一致性造成的影响,并不是总是用[MASK]这个特殊符号去替换那15%被mask的单词。实际上这15%的token中

  1. 80%的token被[MASK]替换
  2. 10%的token被随机token替换
  3. 10%的token保持不变
    这样做的好处是,对于输入,任何一个字都有可能是错误的,模型需要更多的去依赖整个上下文来预测,更具有泛化能力;另外减轻pre-train和fine-tuning的不一致的问题。因为这里只预测15%的token而不是和普通LM预测全部token,模型收敛会相对慢些。

Task2: Next Sentence Prediction(NSP)

为了让模型理解句子间的关系,增加了NSP的预训练任务。训练数据构造方式如下:50%的数据用用真实的下个句子,预测label为1,50%句子从预料随机取,预测label为0。这个是通过前面提到的[CLS]的输出然后softmax预测进行而分类的。

Fine-tuning BERT

BERT解读_第2张图片

  1. 分类任务,输入端,可以是句子A和句子B可以是单一句子,[CLS] 接softmax用于分类。
  2. 答案抽取,比如SQuAd v1.0,训练一个start和end 向量分别为S,E ,对每个bert输出向量(比如 B E R T b a s e BERT_{base} BERTbase 768维)和S 或 E计算dot product,之后对所有输出节点的点乘结果进行softmax得到该节点对应位置的起始概率或者或终止概率, 假设BERT输出向量为T,则用S·Ti + E·Tj表示从i位置起始,j位置终止的分数,最大的分数对应i和j(i
  3. SQuAD v2.0,和SQuAD 1.1的区别在于可以有答案不存在给定文本中
    ,因此增加利用CLS的节点输出为C,当最大的分数对应i,j在CLS时候不存在答案;预测的时候,当S·Ti + E·Tj的最大值小于S·C + E·C,并且可以当超过设置的某一个阈值时,不存在答案即可。

总结

优点

  1. 真正双向语言模型,学习到更好的上下文信息
  2. 分类,对话等常见下游NLP任务,都可以用这一套框架,并且基于共享的预训练参数进行fine-tune,并且取得了state-of-the-art的效果

缺点

  1. [MASK]符号在pre-train和fine-tune不一致的问题没有彻底解决
  2. 只预测15%的token,训练收敛较慢

你可能感兴趣的:(NLP,自然语言处理,深度学习,神经网络,机器学习)