#深入理解# Bert框架原理


Bert 全称 Bidirectional Encoder Representations from Transformers ,从全称可知,Bert内部使用的是一个双向的transformer的encoder结构。

此前将预训练的语言模型应用到NLP任务主要有两种策略,一种是基于特征的语言模型,如ELMo模型;另一种是基于微调的语言模型,如OpenAI GPT。这两类语言模型各有其优缺点,而BERT的出现,似乎融合了它们所有的优点,因此才可以在诸多后续特定任务上取得最优的效果。

1. Bert 的网络结构

Bert 是一种 基于微调的多层双向 Transformer 编码器,(关于Transformer框架的深度解读请参考此文章->#由浅入深# 从 Seq2seq 到 Transformer)Bert中的Transformer 编码器 和 Transformer 本身的编码器结构相似,但有以下两点的不同:

  1. 与Transformer本身的Encoder端相比,BERT的Transformer Encoder端输入的向量表示,多了Segment Embeddings。
  2. 模型输入中的 Position Embeddings(位置编码)在bert中学习出来的,在Transformer中是预先设定好的值。

Bert 实现了两个版本的模型,在两个版本中前馈型神经网络(全连接层)大小都设置为4层,两个版本的其他参数对比请参考下表:

版本名称层数隐藏层维度self-attention头数总参数量前馈型神经网络层数
BERTBASE1276812110M4层
BERTLARGE24102416340M4层

2. Bert 模型的输入

在这里插入图片描述
与Transformer本身的Encoder端相比,Bert 的Transformer Encoder端输入的向量表示,多了Segment Embeddings;Bert的输入由以下三个嵌入向量相加而成:

  1. token Embeddings(词嵌入) 表示的是词向量,既可以是原始词向量(one-hot编码),也可以是经过word2vec或glove等模型处理后的静态词向量;其中第一个单词是CLS标志,可以用于之后的分类任务,对于非分类任务,可以忽略CLS标志;

  2. Segment Embeddings (段嵌入)用来区别两种句子,因为预训练不只做语言模型还要做以两个句子为输入的分类任务;例如输入数据由两个句子拼接而成,如果词语属于第一个句子,则Segment Embeddings的对应位置为0,属于第二个句子,则Segment Embeddings的对应位置为1

  3. Position Embeddings(位置编码) 学习出来的embedding向量。这与Transformer不同,Transformer中是预先设定好的值。

3. Bert 模型预训练任务

BERT模型使用两个新的无监督预测任务进行训练,分别是 Masked LMNext Sentence Prediction

3.1 Masked LM(MLM)

为了训练深度双向Transformer表示,采用了一种简单的方法:随机掩盖部分输入词,然后对那些被掩盖的词进行预测,此方法被称为 Masked LM

在训练的过程中,文章作者在一句话中随机选择 15% 的词汇用于预测。对于在原句中被抹去的词汇, 80% 情况下采用一个特殊符号 [MASK] 替换, 10% 情况下采用一个任意词替换,剩余 10% 情况下保持原词汇不变。这么做的主要原因是:

  1. 在后续微调任务中语句中并不会出现 [MASK] 标记,防止被预测的单词泄露给网络,迫使模型更多地依赖于上下文信息去预测词汇
  2. 并且赋予了模型一定的纠错能力,适应更多样的下游任务,因为有些NLP任务需要用到所有的输入数据,例如词性标注等

当然这种方法也有其缺点,就是每批次数据中只有 15% 的标记被预测(只计算15%的损失),这意味着模型可能需要更多的预训练步骤来收敛。

3.2 Next Sentence Prediction(NSP)

很多句子级别的任务如自动问答(QA)和自然语言推理(NLI)都需要理解两个句子之间的关系。在这一任务中我们需要随机将数据划分为等大小的两部分(依靠 segment embedding 标记两个句子),一部分数据中的两个语句对是上下文连续的,另一部分数据中的两个语句对是上下文不连续的。然后让Transformer模型来识别这些语句对中,哪些语句对是连续的,哪些对子不连续。

但是最新的 XLNet 中没有用到 NSP,因为实验表明 NSP 和 PLM 不兼容。 最新的 XLM 也没有用NSP。
用作者的话说,XLM 成功的秘诀是 larger dimension and no NSP(层数为12,和 BERT-Base 相同,但隐层更大,总参数比 BERT-Large 还多,GLUE benchmark 上的效果也超越了 BERT-Large)

个人认为,MLM,NSP分别学习词与词之间和句与句之间的关系。

4. Bert 中的特殊符号

[CLS]:用于标识序列的开始,在语义分析、语句层级的分类等需要使用到[CLS]位置的输出
[SEP]:用于分隔两个句子,在两个句子之间使用 [SEP] 进行分隔

5. Fine-Tune

这里 Fine-Tune 之前对模型的修改非常简单,例如针对sequence-level classification problem(例如情感分析),取第一个token的输出表示,喂给一个softmax层得到分类结果输出;对于token-level classification(例如NER),取所有token的最后层transformer输出,喂给softmax层做分类。
Fine-Tune 分为全局 Fine-Tune 和 局部 Fine-Tune,Bert是全局 Fine-Tune,微调是会更新所有参数;但是GPT 的 Fine-Tune 是固定语言模型参数进行 Fine-Tune 的

6. Bert 和 ELMo 模型的对比

6.1 Bert 比 ELMo 效果好的原因

从网络结构以及最后的实验效果来看,Bert 比 ELMo 效果好主要集中在以下几点原因:

  1. LSTM 抽取特征的能力远弱于 Transformer

  2. 拼接方式双向融合的特征融合能力偏弱(没有具体实验验证,只是推测)

  3. Bert 的训练数据以及模型参数均多余ELMo,这也是比较重要的一点

6.2 ELMo和 Bert 的区别

ELMo模型是通过语言模型任务得到句子中单词的embedding表示,以此作为补充的新特征给下游任务使用。因为ELMo给下游提供的是每个单词的特征形式,所以这一类预训练的方法被称为“Feature-based Pre-Training”。

而BERT模型是“基于Fine-tuning的模式”,这种做法和图像领域基于Fine-tuning的方式基本一致,下游任务需要将模型改造成BERT模型,才可利用BERT模型预训练好的参数。

7. BERT的局限性

从XLNet论文中,提到了BERT的两个缺点,分别如下:

  • BERT在第一个预训练阶段,假设句子中多个单词被Mask掉,这些被Mask掉的单词之间没有任何关系,是条件独立的,然而有时候这些单词之间是有关系的,比如”New York is a city”,假设我们Mask住”New”和”York”两个词,那么给定”is a city”的条件下”New”和”York”并不独立,因为”New York”是一个实体,看到”New”则后面出现”York”的概率要比看到”Old”后面出现”York”概率要大得多。
    但是需要注意的是,这个问题并不是什么大问题,甚至可以说对最后的结果并没有多大的影响,因为本身BERT预训练的语料就是海量的(动辄几十个G),所以如果训练数据足够大,其实不靠当前这个例子,靠其它例子,也能弥补被Mask单词直接的相互关系问题,因为总有其它例子能够学会这些单词的相互依赖关系。

  • BERT的在预训练时会出现特殊的[MASK],但是它在下游的fine-tune中不会出现,这就出现了预训练阶段和fine-tune阶段不一致的问题。其实这个问题对最后结果产生多大的影响也是不够明确的,因为后续有许多BERT相关的预训练模型仍然保持了[MASK]标记,也取得了很大的结果,而且很多数据集上的结果也比BERT要好。但是确确实实引入[MASK]标记,也是为了构造自编码语言模型而采用的一种折中方式。

  • 为了解决OOV的问题,我们通常会把一个词切分成更细粒度的WordPiece。BERT在Pretraining的时候是随机Mask这些WordPiece的,这就可能出现只Mask一个词的一部分的情况,例如:

probability这个词被切分成”pro”、”#babi”和”#lity”3个 WordPiece。有可能出现的一种随机Mask是把”#babi” Mask住,但是”pro”和”#lity”没有被Mask。这样的预测任务就变得容易了,因为在”pro”和”#lity”之间基本上只能是”#babi”了。这样它只需要记住一些词(WordPiece的序列)就可以完成这个任务,而不是根据上下文的语义关系来预测出来的。类似的中文的词”模型”也可能被Mask部分(其实用”琵琶”的例子可能更好,因为这两个字只能一起出现而不能单独出现),这也会让预测变得容易。

为了解决这个问题,很自然的想法就是词作为一个整体要么都Mask要么都不Mask,这就是所谓的Whole Word Masking。这是一个很简单的想法,对于BERT的代码修改也非常少,只是修改一些Mask的那段代码。

8. 从源码层面,理解Bert原理

  1. 从源码层面,深入理解 Bert 框架
  2. 从源码解析 Bert 的 Embedding 模块​
  3. 从源码解析 Bert 的 BertEncoder 模块
  4. 从源码解析 Bert 的 BertPooler 模块

文章从源码层理,对Bert模型进行了深入的解析

9. 用 Bert 解决实际NLP任务

使用 Bert 框架去解决NLP中的实际任务,请参考我的这篇 文章,里边对常见的NLP任务进行了分类,并详细讲解了针对每一类问题,如何对Bert框架进行微调。
参考文章:
4. 关于BERT的若干问题整理记录
5. 图解BERT模型:从零开始构建BERT
6. BERT四大下游任务
7. 超细节的BERT/Transformer知识点

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

energy_百分百

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值