BERT-illustration

BERT illustration

发展历史及主要想法

BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding, BERT 是 Bidirectional Encoder Representations from Transformers 的缩写。这个预训练模型让 NLP 领域进入了类似于当时 CV 界的后 ImageNet 时代(大量预训练模型应用)。

How BERT is developed

  • Step 1:在大量数据上(Wikipedia 和 大量书籍)进行半监督预训练
    • 预训练任务:Language Modeling,包含多个子任务:预测 masked 词,判读句子上下文关系等;
    • 这使得预训练模型具有一定的特征抽取和判断上下文联系(提取语义)等能力。
  • Step 2:在特定任务中进行监督学习
    • 根据特定任务的不同,按照一定的约定方式处理输入;
    • 输入内容通过预训练模型,后面根据任务要求添加分类器(e.g. Linear + Softmax)等得到输出。

Model Architecture

Model encoder hidden units(in feedforward network) attention heads (in multi-head attention)
BERT-BASE 12 encoder layers 768 hidden units 12 attention heads
BERT-LARGE 24 encoder layers 1024 hidden units 16 attention heads

简单实用示例

例如使用 BERT 进行垃圾邮件分类,将每段待分类文本的第一个词替换为 [CLS] (Classification 的缩写),输入模型得到输出:

每个输入 token 对应的 output vector 的大小都是 hidden_size (768 in BERT-BASE),对于这样的分类问题只需要关注第一个 output vector,即输入 [CLS] 对应的输出。将这个输出接入一个神经网络来分类(Linear + Softmax)输出垃圾邮件和非垃圾邮件的概率。

ps:至于为什么只需要第一个 [CLS] 对应的 hidden units 作为特征,需要看一下论文。

发展历史

WordEmbedding

在向量空间中表示一个单词,能够反映单词之间的语义相似性、语法相似性,典型的有 Word2Vec 和 GloVe。这两种模型都是在大规模语料集上进行预训练(Word2Vec 使用 skip-gram 或者 cbow + negative sampling),在之后的任务直接拿来使用。

ElMo

Word2Vec 和 GloVe 存在缺陷,同一个词在不同的上下文中有不同的语义,如果都用同一个向量表示可能不够准确,所以提出了 Contextualized word-embeddings。 ELMo (Embeddings from Language Models) 就是这个预训练模型,预训练使用的任务是 Language Modeling (给定一个句子的前一部分,预测下一个词,这样可以在大批量数据上进行(半)监督训练)。

ELMo 使用双向 LSTM 进行特征提取,这样可以让一个单词具有它的上下文信息。模型预训练完成之后,输入单词所在的句子,拼接 LSTM 中单词对应的 hidden units 以及之前的 word embedding (Word2Vec 或 GloVe),并进行加权,得到最后的 embedding,可以参考下面的图片:

ULM-FiT

一个用于任务迁移的预训练语言模型,训练好之后能够用极小的数据量获得较好的效果。类似于 CV 领域的迁移学习。

Transformer

这是一个比 LSTM 更好的特征提取结构,一开始用在机器翻译领域,其结构如下:

Multi-Head attention 能考虑上下文信息,重点关注有关联的单词,并且同一层能够进行并行,避免了像 LSTM 一样必须有一部分串行,提高了运算速度。

OpenAI Transformer

这个模型将 Transformer 用于 Language Modeling 任务上,选用 Transformer 的 decoder 部分(看不到后面的词)。选用 7000 本书籍作为数据训练(书籍中的语言更流畅),采用 12 层 decoder,输出下一个词的概率。

OpenAI Transformer 模型也是一个预训练模型,在使用上面的任务预训练之后可以用于下游任务(情感分类,相似度分析等),只需要将输入按照约定的标准进行修改,经过 Transformer 之后,再连接一些特定的分类器等进行特定任务。可以参考下图进行理解。

BERT

OpenAI Transformer 是一个成功的模型,但是在提取特征方面,使用 decoder 只能提取单方向的语言,上下文之间的联系没能提取完全,所以 BERT 使用 Encoder Transformer 来解决这个问题,双向的模型能够提取单词周围的上下文关联。

相应地,预训练任务不能使用像上面一样的普通 Language Modeling (已经知道了后面要出现的词,不能对已经作为输入的进行预测),BERT 使用的是 Masked Language Modeling (灵感来源于完形填空),以及 Two-sentence Task:

  • Masked Language Modeling: 随机将一些词遮住,要求根据上下文预测这些词,还有可能随机把一些词替换为另一些词,要求模型预测正确的词是什么;
  • Two-sentence Task: 预测两个句子是不是上下文关系,这有助于模型学习到一些高层次信息(句子的输入是 Tokenized 之后的 input,但这里使用的是 WordPieces,有可能会将一个单词分解为更小的 chunk 作为输入)。

关于使用预训练模型,可以按照约定的要求更改输入格式,例如官方提供的例子:

BERT 还可以用于特征抽取,像 VGG16 一样,每层 encoder 都包含一定的信息,可以代表输入的某部分特征,可以使用 encoder 中的 hidden units 作为特征用于其他的任务。

PS:BERT 预训练的时候使用的激活函数是 gelu:

其中 $\Phi(x)$ 满足正态分布,x 越小,被 drop 掉的概率(变为 0 )越大,这克服了 relu 缺乏一定的统计性的缺点。这个函数的输出与自身有关,同时具有非线性和随机正则性的因素,因此效果更好。

激活函数能够自归一化(给定输入是标准化之后的数据,输出也是归一化数据 i.e. 均值为 0,方差为 1)的要求:

这个激活函数需要有:(1)负值和正值,以便控制均值;(2)饱和区域(导数趋近于零),以便抑制更低层中较大的方差;(3)大于 1 的斜率,以便在更低层中的方差过小时增大方差(可以直观上考虑一下,输出的方差越大,那么梯度也就越大 e.g. MSE Loss);(4)连续曲线。后者能确保一个固定点,其中方差抑制可通过方差增大来获得均衡。我们能通过乘上指数线性单元(ELU)来满足激活函数的这些性质,而且 λ>1 能够确保正值净输入的斜率大于 1。

BERT 缺陷以及 XLNet

Auto-regressive 模型:

  • 给定 $x_1, x_2, x_3, \cdots, x_n$,要求预测 $x_{n+1}$;
  • 在语言生成方面的表现很好;
  • 但只能捕获到单向的语义信息。

Auto-encoder 模型:

  • 预训练任务是对输入的句子加入一些 [MASK],目标要求对 [MASK] 进行预测;
  • pretrain 和 fine-tuning 之间的 gap:
    • 在预训练的时候是使用 [MASK] 进行预测,但在进行下游任务时,下游任务的输入并没有 [MASK],所以预训练的时候有可能会学到 [MASK] 作为 feature,这对后面的下游任务是没有帮助甚至是有伤害的;
    • 在预测 [MASK] tokens 时,预测是并行的,所以 MASK token 之间没有依赖关系,导致可能会有一些比较离谱的预测(前两个是正常的预测,第三个是因为没有依赖导致的不正常的预测):
      • Whenever she goes to the shopping center, she buys a lot of clothes;
      • Whenever she goes to the cinema hall she buys a lot of popcorn;
      • Whenever she goes to the cinema hall she buys a lot of clothes.

XLNet 就是为了既能利用到综合上下文的信息,又具有 auto-regressive 模型的优势而产生的。XLNet 使用的是 Permutation Language Modeling,在 auto-regression 的基础上,但预测不是按照句子顺序进行的,而是乱序进行的。这样既保留的 auto-regressive 的优点,又能够提取双向的语义信息。

XLNet 的结构主要使用的是 Transformer-XL,Transformer-XL 主要是使用了相对的位置编码(针对长文本,长文本需要分块,解决绝对位置编码无法区分不同块的问题),并且相邻块之间做了缓存,后面的块能使用到前面块的语义信息。

XLNet 发现 NSP 任务的用处不大,于是预训练任务只使用了生成的自监督任务。

综上 XLNet 相比 BERT 能够更好的解决预训练和下游任务之间的 gap,吸取自回归模型的优点,并提取双向信息。

XLNet 的一些问题:

XLNet 在 GLUE benchmark 的几乎所有任务上都比先前最优水平得到了提升,但是 CoLA 这一项的表现似乎不尽如人意。CoLA 是判断一个句子是否在语法上合理的,是不是说明这个任务较为依赖单词顺序?
XLNet 计算量和激活值比 BERT 更大,有可能接近 BERT 的 2 倍(因为 XLNet 要给每个位置维护两套隐状态,一套是包含当前 token 信息的 content stream h,另一套是不包含当前 token 信息的 query stream g,此外还有前一个 segment 的缓存。模型太大,可能不适合某些场景,并且对研究人员的硬件要求也变高了。

但实际上,RoBERTa 对 BERT 的参数进行精调之后,表现进一步提高,所以说 BERT 的性能因为超参数限制没有发挥到极致也是之前 XLNet 到达 SOTA 的原因之一。

参考文献

1. Illustrated-bert.
2. 如何评价在20个任务上超越BERT的XLNet?

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2020 Bowen
  • Powered by Hexo Theme Ayer

请我喝杯咖啡吧~

支付宝
微信