查看原文
其他

Bert 改进: 如何融入知识

老宋的茶书会 AINLP 2020-10-22

作者:老宋的茶书会

知乎专栏:NLP与深度学习

研究方向:自然语言处理




前言

一个合格的博客主需要学会制作高质量的博客(蹭热点),最近最热的,应该就是 Bert 了,一直想捋一遍预训练语言模型的前世今生,但随便瞅了瞅 GPT-2, 感觉,emmm,放弃。

但最近有两篇文章引起了我的注意,这两篇文章的名字都叫 ERNIE, 一篇是百度的,另一篇清华与华为诺亚方舟合作的,很巧的是,二者的重点都是在于如何将知识融入到模型中,都很厉害。

虽然咱们没有资源搞预训练语言模型,但看看长长见识还是需要的,免得面试官问起了: 你觉得 Bert 有啥缺陷,emmm,咱也不能哑口无言不是。

本文从 Bert 谈起,主要是为了各个模型的对比,并分析每个模型内部各个模块所起到的作用。

先从 Bert 谈起

1, Transformer vs LSTM, 单向 vs 双向

Bert 采用双向Transformer 来做特征抽取的基本单元,而 ELMO 中采用双向 LSTM ,对比二者, LSTM 被碾压,主要有以下几个方面。

  • 并行能力。这对于语言模型这种需要大规模数据来说,如果无法并行,那么运行时间真的是一个噩梦,这是扼制 RNN 落地的主要因素。

  • 捕捉距离与抽取特征能力:LSTM 与 GRU 依旧无法摆脱长距离依赖的问题,主要是因为二者是通过维护一个全局的向量信息来做信息融合,这意味着,可能会有一些重要信息在融合过程中丢失了,可以参见 RNN vs LSTM vs GRU -- 该选哪个?, 而距离越长,这种问题可能会越严重。

  • LSTM 不是真正的双向:LSTM 是双向,但不能完全捕捉双向的信息,我个人的理解依旧在于:LSTM 在时序传播的过程中,会损失一部分信息(单一向量维护全局信息),这使得双向的 LSTM 在特征提取方面不如Transformer, 因为它不是真正的双向。

其实,这二者之间的更好的对比在: 放弃幻想,全面拥抱Transformer:自然语言处理三大特征抽取器(CNN/RNN/TF)比较, 张俊林大佬写的,厉害的一批。

至于 GPT-1 与 GPT-2 中为何采用单向的 Transformer,这点我一直没搞懂,难道是为了独树一帜?我个人认为双向的 Transformer 无疑完胜单向啊。

2, Large vs Base

Bert 提供了两个不同 size 的模型,Base的参数量有110M, Large 的参数量在340M, 而据我个人的实验,大概率情况下,Large 效果会更好,好多少得看具体的任务和数据集,分类这种简单任务一般差不太多,1-2个百分点,复杂任务如阅读理解就有点东西了。

这说明一点: 大力出奇迹啊

3,不同粒度的Embedding



Bert 的输入包含有两个粒度:token 以及 segment, 这从侧面反映了,不同粒度的信息的融合是有帮助的,我觉得可以试试段落粒度等更粗的粒度信息,但我等乞丐实验室还是,默默看大佬们装逼吧。

4. 预训练任务:Masked LM

Masked LM 其实很像是完形填空问题,其具体指的是, 随机 mask 输入 tokens 中的15%的 tokens , 然后将隐层向量输出到softmax,在整个词表中做softmax, 预测被遮住的 tokens。这么做的目的在于实现双向,举例来说:

妈妈再也不用[MASK]心我[MASK]学习。

这句话中,双向 Transformer 在预测 [MASK]位置时会结合左右上下文信息, 而在训练时,两个 [MASK] 的损失会相加,然后再反向传播。

注意,对于一个序列而言,Bert 选取 15% 个词来 mask, 一个序列只能生产一个样本,这个样本中有 15% 是被 mask 的。

对于这种 mask 方式,其的确能够获得双向预训练模型,但该方法存在两个缺陷:

首先第一个问题是训练与微调之间的不匹配。 这是因为在微调时并没有 [MASK] 这个 token,它只出现在预训练任务中。为了减轻该问题, Bert 采用了以下策略:

序列:my dog is hairy
mask的词为 hairy
则 hairy 的替换过程如下:
- 80% 情况下:用 [MASK] 替换 hairy
- 10% 情况下:随机从词表中选择一个词来替换 hairy
- 10% 情况下:不改变这句话,这样的目的是使得最终的表示偏向于实际的词

该策略能够很好的解决不匹配的问题, 下面一段是我个人的理解:

  • 首先,80% 的情况替换为 [MASK] 符合语言模型本身,最原始就是这么做的,可以参见 Word2Vec 的 CBOW。

  • 其次, 随机选择一个词来替换,我个人认为是为了增加泛化,文章也指出, 1.5%(10% * 15%) 的随机替换似乎并不会对模型的语言理解能力带来坏处。

  • 最后,10% 不做替换,目的是减少训练与微调的不匹配,使得最终的表示偏向于实际的词。

第二个问题是对于每个序列而言,标记的token只有 15%,这使得模型收敛较慢,需要更长的训练步数。 在 Word2Vec 的CBOW 中, 序列中的每个词都有被预测过,而文章此处的改进是基于经验的, 只预测 15% 的词的确要比全都预测更好,只是对应的训练步数需要增加才能获得收敛。

  • 对于如何生成样本数据的代码参见:pytorch-pretrained-BERT 下的 random_word 函数。

  • 对于预训练模型的训练代码参见:pytorch-pretrained-BERT 下的 BertForPreTraining

5, Next Sentence Prediction

对于许多NLP任务来说,句子之间的关系信息是有帮助的,如QA, NLI 等,而这种关系恰恰是语言模型难以捕捉的, 而 Next Sentence Prediction 模块就是为了弥补这个缺陷。

该模型更详细的说是,选定两个句子 A, B 作为预训练样本,B 有 50% 的可能为A的下一句, 有 50% 的可能是语料库中的随机句子,举例如下:

Input: [CLS] the man went to [MASK] store [SEP] he bought a gallon [MASK] milk [SEP]
Label: IsNext

Input: [CLS] the man [MASK] to the store [SEP] penguin [MASK] are flight ##less birds [SEP]
Label: NotNext

该模块实现了 97%-98% 的 accuracy, 并且实验表明,对于 QA 与 NLI 效果显著。

这也充分说明了,不同粒度的信息对于深层次的理解是有帮助的,或许段落级别的融入也会有一些作用,对于长文本来说。

ERNIE - 百度

百度的这篇文章更像是 Bert 模型对于中文的针对性改进,当然对英文也有一定的作用,但对于中文来说更明显。

1, 双向Transformer

ERNIE 同样采用多层的双向Transoformer 来作为特征提取的基本单元,Transformer 的重要性可见一斑,所以深入 Transformer 对于我们来说是十分必要的。

这部分没啥创新,就是简单提一下。

2, 不同粒度的信息融合

ERNIE 同样采用了多种粒度信息,只不过不同粒度信息的预训练过程与 Bert 不同, 对于一个 token, 其同样由 token embedding + segment embedding + position embedding 组成,与 bert 相同, 每一句话的第一个 token 都为 [CLS]。

3, Basic-Level Masking 预训练

这个过程与 Bert 中的 MLM 类似,是对于词粒度的预训练。对于英文而言,粒度为 word, 对于中文而言,粒度为字。

随机 Mask 输入序列中 15% 的 token, 然后预测这些被 mask 掉的 tokens。这点与 Bert 相同, 不同的是,其论文中没有提到十分采用类似 Bert 的那种 Mask 的Trick 来降低预训练与预测的不一致性,这点需要看代码确认一下。

4, Phrase-level Masking 预训练

我个人认为短语级别的粒度信息对于中文,英文来说都是有用的。

对于中文来说, 比如 “放你一马”, 这从单单的字粒度信息是学习不到的,且这种信息相当多。而对于英文来说,英文短语也不在少数,就像: pull up, pull down, push up, push down 我觉得word粒度对这种短语信息也是难以捕捉的。

在这部分的预训练过程中,首先采用对应的工具识别出句子中存在的 Phrase, 然后随机 Mask 句子中的一些短语(文章并没有说 mask 多少百分比), 然后预测 mask 掉的 Phrase 中的 word(字), 即以 word(字)为预测单元。

5. Entity-level Masking 预训练

实体信息包括人名,地名,组织名称,产品名称等, 而实体又是一种抽象的概念,且通常包含着一些重要的信息,且实体之间的关系也十分重要。ERNIE 先用命名实体识别找出句子中的实体,然后与 Phrase-level 一样, mask 其中的一些实体并预测这些mask掉的 word (字)。





对此,Entity-level Masking 预训练能够捕捉到实体的语义信息,这点是毋庸置疑的,但对于实体间关系的抽取,从模型上来看并不突出,希望有大佬解释一下(论文中是提到可以学习到实体间关系,只是我对此存疑)。

6. 多源数据

ERNIE 在预训练时采用了多源数据,包括:中文维基百科,百度百科,百度新闻,百度贴吧。其中,百度贴吧由于其社区的特性,里面的内容是对话形式的,而 ERNIE 中对于 Segement Embedding 预训练与 Bert 的 NSP 不同的是,其采用 DLM 来获得这种句子粒度级别的信息,而这对于句子语义的把握更佳准确。

7, DLM:Dialogue Language Model

对比 Bert 中的 NSP, 似乎 DLM 更能把握句子的语义信息,且对于对话,问答这种形式的任务效果更好。DLM 的训练过程与 NSP 也有很大的区别,其输入如下:





为了使得 ERNIE 能够表示多轮对话,其输入采用QRQ, QQR,QRR(Q表示Query, R表示Response) 这几种形式, 如上图就是 QRQ 的一个例子。ERNIE 会 mask 掉输入的一些 token, 然后让模型去预测这些被 mask 掉的 token(文章并没有给出mask比例以及如何分配mask)。

同样有趣的是,ERNIE 也通过随机替换 Query 或 Response的方式来会添加一些 fake 样本来让模型去预测该输入是 real 还是 fake。

DLM 与 NSP 相比, 其更加复杂也更倾向于对话这种更高难度的任务,我个人认为,这种方式对于对话这种任务来说帮助很大。

我个人认为,句子粒度的信息还有很大的发展空间,希望有大神能出一个比较文章。

实验表现

这部分一部分参见论文,一部分参见[4]。ERNIE 至少在中文领域完全超越了Bert, 尤其是对于实体短语相关如命名实体识别,QA 相关的任务上表现突出。

百度的实力还是相当的屌啊,话说,为啥百度市值降到了400多亿美元,有没有大佬解释一下。

ERNIE: 清华 + 华为诺亚方舟

清华的这篇文章与百度的有很大的差异,同样是引入外部知识,清华走了与百度完全不一样的道路,我们先来看看他们是怎么做的。

两篇文章对比,百度那篇文章更侧重于训练一个更好的预训练语言模型, 而清华的这篇文章更侧重于如何融入知识图谱。

融入知识图谱面临的两大挑战

知识图谱本质是 实体 + 实体间关系, 其中实体为点,实体间关系为边。而将知识图谱引入到预训练语言模型,有两个主要的挑战:

  • Structed Knowledge Encoding:对于给定的文本,如何有效的提取其中的知识图谱信息并对其进行 encode。

  • Heterogeneous Information Fusion:即如何将 encode 后的知识图谱信息融入预训练模型。

1, 模型架构





我们看到,上述整个模型可以整体分为两部分:

  • T-Encoder:与 Bert 的预训练过程完全相同,是一个多层的双向 Transformer encoder, 用来捕捉词汇和语法信息。

  • K-Encoder:本文创新点,描述如何将知识图谱融入到预训练模型。

2, 模型输入

对于一个给定的句子, 以下是其对应的 token 序列,划分按照word(字):

同时,文章采用命名实体识别的方式识别出句子中的实体,并与知识图谱中的实体进行对应, 由于实体往往不止一个token, 因此实体序列的长度与token序列的长度往往并不相等:

3, T - Encoder

前面提到,就是与 Bert 完全相同的,一个多层的双向 Transformer encoder, 其输出为:

4, TransE:encode 知识图谱

TransE 能够将实体与实体间关系转化为一种分布式表示, 而论文中就是采用这种方法,具体的我也不介绍了,对这方面了解有限:

5, K - Encoder

K - Encoder 的输入 tokens embedding 以及 entity embedding 首先分别经过一个多层的 Multi-head self-attentions(MH-ATTs):

然后要将 entity embedding 与 token embedding 融合, 其中,emtity 与 token 之间是有对应的,文中采用第一个 token 作为对应方式,一部分token有对应的entity, 一部分没有(如上图)。

  • 对于有对应实体的情况,则有:

  • 对于没有对应实体的情况,则有:

此处的激活函数可以选择 GELU,  表示集成了 emtity 信息与 token 信息的隐层状态。

将上述操作简单描述, 那么第 i 个 aggregator 操作可以简述为:

6, dEA: denoising entity auto-encoder

从上式我们可以看出,该阶段的目的就是对于token序列与entity序列,计算每个token所对应的 entity 序列概率分布,以此来进行预训练。

该预训练模块的目的其实很明确,就是为了将 K-Encoder 输出的信息结合,毕竟不是每一个 token 都有对应的实体信息的。

在 dEA 的预训练过程中,考虑到 token 与 entity 之间的对齐误差, 因此采用一些策略进行调整:

  • 5% 的情况下,对于给定的 token-entity 对,我们将实体替换为其他随机实体, 旨在减轻对齐过程所带来的误差。

  • 15% 情况下,mask token-entity 对, 旨在减轻对于新 token-entity 所带来的误差

  • 剩下80% , 保持不变。

6, 其余

论文中的细节与创新点就是这些,其余的我觉得看的意义不是很大,因此我就简单过了,感兴趣的可以看一看,毕竟咱也没有资源去试。

最后

这两篇文章的质量都很高,可以说我是近一年来看的国内质量最高的几篇文章之二了。

对于百度的那篇文章,预训练过程的 entity-level 能否把握住实体之间的关系,我对此存疑,需要做实验证明一下。

对于清华的那篇文章,我个人感觉,太过复杂了,中间变化太多, 无论是命名实体识别, token-entity 对齐以及知识图谱的encode, 都会引入噪声,但无疑,这篇文章打开了一扇大门,相对创新性更高。

相信接下来是知识图谱研究者的时代了,对于这方面的知识融入,我个人更看好百度这个方向,不过目前百度的工作是不够的,相信如果能够验证百度的模型能否表示实体关系这个方向,绝对会是一篇不错的文章,如果可以,那么百度的这个方向无疑是接下来的最热点。

此外,还有一点有趣的是,句子粒度的预训练任务,句子的关系有:是它的下一句,上一句,回答,无关等关系,哪种预训练更能全面把握这种关系,也是值得思考的一个方向。

最后,段落粒度的方向,也值得一试,万一出结果了呢,哈哈哈哈。

个人水平不够,主要还是提一些我个人的看法,希望大家友善批评,不要骂我哦。

最后,大声喊出我们NLP新时代的口号: 大力出奇迹。

此时,某乞丐玩家路过,,,一群乞丐玩家留下了羡慕的泪水,哈哈哈哈。

Reference

[1] BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding

[2] ERNIE: Enhanced Representation through Knowledge Integration

[3] ERNIE: Enhanced Language Representation with Informative Entities

[4] 如何评价百度新发布的NLP预训练模型ERNIE?


原文链接:
https://zhuanlan.zhihu.com/p/69941989

本文由作者授权AINLP原创首发于公众号平台,点击'阅读原文'直达原文链接,欢迎投稿,AI、NLP均可。

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存