BERT and it‘s family

本文主要转载自:
mathor‘s blog
https://www.zhihu.com/search?type=content&q=bert%20family

大名鼎鼎的芝麻街

预训练语言模型的缩写大多是芝麻街的人物。这显然是起名艺术大师们的有意为之。他们甚至都可以抛弃用首字母缩写的原则去硬凑出芝麻街人名

上图所示的模型(除了 Big Bird,因为没有这个模型)他们之间都有一些共同点,就是能通过一个句子的上下文来给一个词进行 Embedding,而能达到这种目的的网络架构有很多,例如 LSTM,Self-attention layers,Tree-based model(注重文法,一般表现不佳,只有在文法结构非常严谨的情况下表现好)等等

模型压缩

预训练模型往往都比较庞大,预训练过程需要耗费大量的人力和财力。因此模型压缩就变得越来越重要。学术界已经出现的轻量级的预训练模型: Distill BERT,Tiny BERT,Mobile BERT,Q8BERT,ALBERT

授人以鱼不如授人以渔,究竟有哪些方法可以使 Model 变小呢?可以参考李宏毅老师模型压缩的视频讲解,以及 All The Ways You Can Compress BERT 这篇文章。常见的方法有以下几种

  • Network Pruning 剪枝
  • Knowledge Distillation 知识蒸馏
  • Parameter Quantization 参数量化
  • Architecture Design 结构设计

Fine Tune

预训练模型往往能带给数据很好的embedding,然而在具体任务中,预训练模型往往还需要进行fine-tune。预训练fine-tune有3种:一种是把target-speific layer和pre-trained一起精调 ;另一种只精调target-specific layer;最后一种是调target-speific layer和一部分的pre-trained

Combination of Features

我们知道 BERT 有很多 Encoder Layer,大家常规的做法都是提取最后一层的输出来做下游任务,但实际上这是最优解吗?其实就有人在 NER 任务上做过一个实验,将不同层的输出进行各种组合,得到的效果如下
在这里插入图片描述

肖涵在 Github 上创建了一个名为 bert-as-service 的开源项目,该项目旨在使用 BERT 为您的文本创建单词嵌入。他尝试了各种方法来组合这些嵌入,并在项目的 FAQ 页面上分享了一些结论和基本原理

肖涵的观点认为:

  • 第一层是嵌入层,由于它没有上下文信息,因此同一个词在不同语境下的向量是相同的
  • 随着进入网络的更深层次,单词嵌入从每一层中获得了越来越多的上下文信息
  • 但是,当您接近最后一层时,词嵌入将开始获取 BERT 特定预训练任务的信息(MLM 和 NSP)
  • 使用倒数第二层比较合理

Why Pre-train Models?

为什么我们要使用这些预训练的模型?一个很明显的道理是,我们没那么多钱去从头训练一个比较大的模型,所以直接拿别人训练好的来用就行了

当然,EMNLP 2019 的一篇文章 Visualizing and Understanding the Effectiveness of BERT 从学术角度仔细分析了为什么要使用预训练模型,文章表明,预训练模型可以大大加速损失的收敛,而不使用预训练模型,损失比较难下降。可以理解为,预训练模型提供了一种比随机初始化更好的初始化

另一个结论是,预训练模型可以大大增加模型的泛化能力。上图表示给模型不同参数时,模型训练后结束点的损失会抵达一个 local minima 的位置。这个 local minima 的位置越陡峭,则泛化能力越差,因为输入稍微变化,它的损失就会有很大的变动;反之,这个 local minima 越平缓,则泛化能力越强

ELMO

ELMo的整体图如下图图8。相对于上面的图6,有两个改进,第一个是使用了多层LSTM,第二个是增加了后向语言模型(backward LM)。

对于后向语言模型,跟前向语言模型类似,除了它是给定后文来预测前文。后向lstm语言模型的公式如下图所示,可以对照着前向语言lstm语言模型的公式(图7所示)来看。还是非常好理解的。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
ELMO的不足也非常明显,使用了两个独立的LSTM分别进行embedding,仅仅在第二层时候进行concat,没有信息交互。

BERT

对于 Transformer 类模型(典型代表就是 BERT),自注意力机制使得它能够同时看到上下文,每一个 token 两两之间都能交互,唯一要做的只是随机地把某个 token 用[MASK]遮住就可以

如果你回溯历史,回到 Word2vec 刚刚掀起 NLP 革命的时候,你会发现 CBOW 的训练方式和 BERT 几乎一样,它们的主要区别在于,BERT 能关注的范围长度是可变的,而 CBOW 的范围是固定的。同时,BERT的NSP(next sentence prediction)预训练任务也和负采样的思想相同
在这里插入图片描述

BERT的特点

  1. 真正的双向:使用双向 Transformer,能同时利用当前单词的上下文信息来做特征提取,这与双向RNN分别单独利用当前词的上文信息和下文信息来做特征提取有本质不同,与CNN将上下文信息规定在一个限定大小的窗口内来做特征提取有本质不同;
  2. 动态表征:利用单词的上下文信息来做特征提取,根据上下文信息的不同动态调整词向量,解决了word2vec一词多义的问题;
  3. 并行运算的能力:Transformer组件内部使用自注意力机制(self- attention),能同时并行提取输入序列中每个词的特征。
  4. 易于迁移学习:使用预训练好的BERT,只需加载预训练好的模型作为自己当前任务的词嵌入层,后续针对特定任务构建后续模型结构即可,不需对代码做大量修改或优化。
    在这里插入图片描述

RoBERTa

RoBERTa在训练方法上对Bert进行改进,主要体现在改变mask的方式、丢弃NSP任务、训练超参数优化和使用更大规模的训练数据四个方面。

其改进点如下:
1.静态Mask变动态Mask
Bert在整个预训练过程,选择进行mask的15%的Tokens是不变的,也就是说从一开始随机选择了这15%的Tokens,之后的N个epoch里都不再改变了。这就叫做静态Masking。而RoBERTa一开始把预训练的数据复制10份,每一份都随机选择15%的Tokens进行Masking,也就是说,同样的一句话有10种不同的mask方式。然后每份数据都训练N/10个epoch。这就相当于在这N个epoch的训练中,每个序列的被mask的tokens是会变化的。这就叫做动态Masking。这样做的目的是:动态mask相当于间接的增加了训练数据,有助于提高模型性能。

2.移去NSP任务
Bert为了捕捉句子之间的关系,使用了NSP任务进行预训练,就是输入一对句子A和B,判断这两个句子是否是连续的。两句子最大长度之和为512。RoBERTa去除了NSP,而是每次输入连续的多个句子,直到最大长度512(可以跨文章)。这种训练方式叫做(FULL-SENTENCES),而原来的Bert每次只输入两个句子。这样做的目的是:实验发现,消除NSP损失在下游任务的性能上能够与原始BERT持平或略有提高。这可能是由于Bert以单句子为单位输入,模型无法学习到词之间的远程依赖关系,而RoBERTa输入为连续的多个句子,模型更能俘获更长的依赖关系,这对长序列的下游任务比较友好。

Whole Word Masking (WWM)

随机地 mask 掉某个 token 效果是否真的好呢?对于中文来说,词是由多个字组成的,一个字就是一个 token。如果我们随机 mask 掉某个 token,模型可能不需要学到很多语义依赖,就可以很容易地通过前面的字或后面的字来预测这个 token。举个例子:“东北黑龙江是个很美的地方”将“龙”mask掉,那么模型只要根据”黑,江“来预测,学不到更长的依赖,为此我们需要把难度提升一点,盖住的不是某个 token,而是某个词(span),模型需要学到更多语义去把遮住的 span 预测出来,这便是 BERT-wwm。同理,我们可以把词的 span 再延长一些,拓展成短语级别、实体级别(baidu-ERNIE)

SpanBERT

还有一种 BERT 的改进叫 SpanBERT。它每次会盖住 n个 token,其中n 是根据上图所示的概率得到的。实验结果发现,这种基于概率选择盖住多少个 token 的方式在某些任务上要更好一些

SpanBERT 还提出了一种名为 Span Boundary Objective (SBO) 的训练方法。一般我们训练只是把 masked 的 tokens 给训练出来。而 SBO 希望通过被盖住范围的左右两边的输出,去预测被盖住的范围内有什么样的东西。如上图所示,将 w3 和 w8 的输出以及一个索引送入后续的网络中,其中这个索引表示我们希望预测的是 span 中哪个位置的词

在这里插入图片描述

XLNet

在这里插入图片描述
简单来说,XLNet 认为 BERT 类模型训练和测试阶段不统一(训练阶段有 [MASK]token,测试阶段没有),因此可能会存在某些问题。如果从 Autoregressive 的角度去看 XLNet,其实就是将输入打乱顺序作为输入,然后从左往右预测下一个 token。如果以 AutoEncoder (BERT) 的角度去看 XLNet,我们希望根据 [MASK]左边或者右边的信息去预测 [MASK]位置的词。与 BERT 不同的地方在于,XLNet 的输入没有 [MASK]的存在

MASS/BART

在这里插入图片描述

BERT 类模型缺乏生成句子的能力,所以它不太适合做 Seq2Seq 的任务,而 MASS 和 BART 这两个模型就解决了 BERT 不擅长生成的问题。我们首先把一个句子输入到 Encoder,我们希望 Decoder 的 output 就是 Encoder 的 input,但有一点要注意的是,我们必须将 Encoder 的 input 做一定程度的破坏,因为如果没有任何破坏,Decoder 直接将 Encoder 的输入 copy 过来就行了,它可能学不到什么有用的东西

MASS 的做法是,把输入的一些部分随机用 [MASK]token 遮住。输出不一定要还原完整的句子序列,只要能把[MASK] 的部分预测正确就可以了
在 BART 的论文中,它又提出了各式各样的方法,除了给输入序列随机 mask 以外,还可以直接删除某个 token,或者随机排列组合等。

具体的破坏方式参考下图
在这里插入图片描述

UniLM

在这里插入图片描述
还有一个模型叫 UniLM,它既可以是编码器,也可以是解码器,还可以是 Seq2Seq。UniLM 由很多 Transformer 堆叠,它同时进行三种训练,包括 BERT 那样作为编码器的方式、GPT 那样作为解码器的方式、MASS/BART 那样作为 Seq2Seq 的方式。它作为 Seq2Seq 使用时,输入被分为两个片段,输入第一个片段的时候,该片段上的 token 之间可以互相注意,但第二个片段,都只能看左边 token

ELECTRA

在这里插入图片描述
在这里插入图片描述
预测一个东西需要的训练强度是很大的,ELECTRA 想要简化这件事情,转为二分类问题,判断输入的某个词是否被随机替换了

但问题来了,怎样把一些词进行替换,同时保证文法没错,语义也不是那么奇怪的句子呢?因为如果 token 被替换成了一些奇怪的东西,模型很容易就能发现,ELECTRA 就学不到什么厉害的东西了。论文用了另一个比较小的 BERT 去输出被 mask 的单词,这里不需要用很好的 BERT,因为如果 BERT 效果太好,直接就输出了和原来一摸一样的单词,这也不是我们期望的。这个架构看上去有点像 GAN,但实际上它并不是 GAN,因为 GAN 的 Generator 在训练的时候,要骗过 Discriminator。而这里的 small BERT 是自己训练自己的,只要把被 mask 的位置预测出来就好了,至于后面的模型预测的对不对和它没有关系

ELECTRA 训练效果很惊人,在相同的预训练量下,GLUE 上的分数比 BERT 要好很多,而且它只需要 1/4 的运算量就可以达到 XLNet 的效果

在这里插入图片描述

T5

预训练语言模型需要的资源太多,不是普通人随便就可以做的。谷歌有篇论文叫 T5,它展现了谷歌庞大的财力和运算资源,这篇文论把各式各样的预训练方法都尝试了一次,然后得到了一些结论,让别人没有研究可做

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值