BERT的来龙去脉

RNN

机器翻译任务:单词的先后顺序会影响句子的意义,句子间的单词数量不是一一对应的,

RNN:擅长捕捉序列关系,但只能实现N2N、1toN、Nto1,不能解决N2M的问题,

Sequence2sequence:包括编码器和解码器的结构,依然使用的是RNN网络
先由Encoder提取原始句子的'意义',再由Decoder将'意义'转换成对应的语言,依靠'意义'这一中介,成功解决了两端单词不对等的情况

问题:中间的意义单元存储的信息有限,如果一个句子太长,翻译精度就会随之下降

Transformer

Attention:在seq2seq的基础上,生成每个单词时,都从原始句子中提取生成该单词时最需要的信息,摆脱了输入序列的长度限制

QKV都是x 经过线性变换得到的,是为了提高模型的拟合能力。

将得分分别除以一个特定数值8(K向量的维度的平方根,通常K向量的维度是64)这能让梯度更加稳定,
问题:计算太慢,RNN需要逐个看过句子中的单词,才能给出输出

Self-attention:先提取每个单词的意义,再依据生成顺序选取所需要的信息,支持并行计算,效率更高

BERT 正片

因为计算机并不能读懂汉字,所以我们一般会用向量的方式去表示一个词。词语的意义之间是有关联的,距离可以表示词和词之间的关系,将收集好的句子输入模型,Bert就是帮助我们找到词语位置的模型之一,encoder部分可以将语言的意义很好地抽离出来,直接将这部分独立,也许能很好地对语言做出表示
BERT (Bidirectional Encoder Representations from Transformers):在未标记的文本上进行预训练,调节各个层的参数,学习上下文表示。因此只需要增加一个输出层进行微调,就能在多个任务上达到 SOTA 水平。

  • 首先BERT是一个无监督学习的模型;主要架构和transformers的encoder部分相同;
  • 主要贡献点在于Bidirectional,传统的pretrain基本思想都是language model,只能看到一端的信息【就算是Elmo看似用了两端信息,但是也是分别学习再拼接的】,这限制了与训练模型的表达能力;
  • 为了实现Bidirectional的学习,提出了masked language mode(MLM);
  • 为了实现text-pair的学习,利用了next sentence prediction;

1.BERT整体模型架构

BERT 模型有两个步骤:预训练、微调。

  • 预训练时,模型在不同的预训练任务中基于未标记数据进行训练;
  • 微调时,先使用预训练模型的参数初始化 BERT 模型,再在特定任务的标注数据上对参数进行微调。

预训练模型:假设有大量的维基百科数据,那么可以用来训练一个泛化能力很强的模型,当需要在特定场景使用时,例如做文本相似度计算,则只需要简单的修改一些输出层,再用自己的数据进行一个增量训练,对权重进行一个轻微的调整。

预训练的好处在于在特定场景使用时不需要用大量的语料来进行训练,节约时间效率高效,BERT就是这样的一个泛化能力较强的预训练模型。

模型架构是一种多层的双向 transformer encoder

BERT base :12层Encoder
BERT large :24层Encoder
Transformer:6层Encoder + 6层Decoder
从模型的层数来说其实已经很大了,但是由于transformer的residual模块,层数并不会引起梯度消失等问题,但是并不代表层数越多效果越好,有论点认为低层偏向于语法特征学习,高层偏向于语义特征学习。

输⼊可以是⼀个,或两个句⼦,最后都转换成最⼤长度521的序列。
[CLS] 是每个输入序列开头的特殊标记,⽤于分类或预测下⼀句等任务,该标记的最终隐藏状态用来聚合句子的表征(但最新研究表明有效果更好的方法来得到句子的嵌入);[SEP] 是两个句子之间的特殊标记,用于区分不同的句子。

输入

由三部分组成:

  1. token embedding(即word embedding)
    作用:将各个词转换成固定维度的向量。在BERT中,每个词会被转换成768维的向量表示。
    实现:
    • 使用WordPiece方法进行tokenization。 这是一个数据驱动式的tokenization方法,旨在权衡词典大小和oov词的个数。例子中的“strawberries”会被切分成“straw” 和“berries”。
    • tokenization的结果开头加上[CLS]、结尾加上[SEP](为后面的分类任务和划分句子对服务)

      Token Embeddings 层会将每一个wordpiece token转换成768维的向量。这样,例子中的6个token就被转换成了一个(6, 768) 的矩阵或者是(1, 6, 768)的张量(如果考虑batch_size的话)。
  2. segment embedding 段向量
    作用:区分一个句子对中的两个句子
    实现:Segment Embeddings 层把0赋给第一个句子中的各个token, 把1赋给第二个句子中的各个token。如果输入只有一个句子,那么它的segment embedding就是全0。
  3. position embedding 位置编码(自注意需要)
    作用:Transformers无法编码输入序列的顺序性,例如 I think, therefore I am,第一个 “I” 和第二个 “I”应该有着不同的向量表示
    实现: 实际上就是一个大小为 (512, 768) 的lookup表,表的第一行是代表第一个序列的第一个位置,第二行代表序列的第二个位置,以此类推。因此,如果有这样两个句子“Hello world” 和“Hi there”, “Hello” 和“Hi”会由完全相同的position embeddings,因为他们都是句子的第一个词。同理,“world” 和“there”也会有相同的position embedding。
    有点像位置的one-hot编码

总结:

  • Token Embeddings, (1, n, 768) ,词的向量表示
  • Segment Embeddings, (1, n, 768),区别句子对中的两个句子的向量表示
  • Position Embeddings ,(1, n, 768) ,得到输入序列的位置信息

​这些表示会被按元素相加,得到一个大小为(1, n, 768)的合成表示。这一表示就是BERT编码层的输入了。

注:在Transformer中的Input:Input embedding(随机初始化或者使用word2vec得到的词嵌入)+Positional Encoding(位置编码,正余弦函数)。
区别是Transformer的Positional Encoding是直接表示的,而BERT的position embedding会通过训练更新。

Pre-training BERT

BERT的预训练阶段采用了两个独有的非监督任务

(1)MLM-掩码语言模型

可以理解为完形填空,随机mask每一个句子中15%的词,用其上下文来做预测
输入[CLS]我 mask 中 mask 天 安 门[SEP],预测句子的mask,即多分类问题

  • 无监督损失函数:

    • AE(autoencoding)自编码模型;从损坏的输入数据中预测重建原始数据。可以使用上下文的信息(BERT中使用的)
    • AR(autoregressive)自回归模型;只能考虑单侧的信息(GPT中使用的)

    例:【我爱吃饭】
    AR:
    P(我爱吃饭)=P(我)P(爱|我)P(吃|我爱)P(饭|我爱吃);
    AE:
    mask之后:【我爱mask饭】
    P(我爱吃饭|我爱mask饭)=P(mask=吃|我爱饭)
    即打破了文本,让他文本重建

  • mask模型的缺点:
    mask之后:【我爱mask mask】
    优化目标:P(我爱吃饭|我爱maskmask)=P(吃|我爱)P(饭|我爱);

  • mask的概率:
    在所有的语料中随机mask15%的单词,其中10%替换成其他,10%原封不动,80%替换成mask

(2)NSP-下一个句子预测

输入成组的句子,由Bert判断两个句子是否相连,让Bert对上下文关系有更好的理解

输入[CLS]a[SEP]b[SEP],预测b是否为a的下一句,即二分类问题
NSP样本包括:
1.从训练语料库中取出两个连续的段落作为正样本
2.从不同的文档中随机创建一对段落作为负样本
缺点:主题预测(判断两个样本是否来自同一个文档)和连贯性预测(判断两个样本是否是顺序关系)合并为一个单项任务
Albert去掉了主题预测,只预测句子顺序

3.Fine-tuning BERT

主要的下游任务:

(1)句子对分类

本质是文本匹配,即将两个文本拼接,判断他们是否相似,使用CLS的输出判断,0则不相似,1相似
(2)单个句子分类

使用CLS的输出经过微调做二分类或多分类
(3)问答任务

当需要接收与文本序列的问题,并且需要在序列中标记答案。使用 BERT,可以通过学习两个标记答案开始和结束的额外向量来训练问答模型。
(4)命名实体识别(序列标注)

将所有的token经过softmax输出,看属于实体中的哪一个
接收文本序列并需要标记文本中出现的各种类型的实体(人、组织、日期等)。使用 BERT,可以通过将每个标记的输出向量输入到预测 NER 标签的分类层来训练 NER 模型。

一般步骤:

比如做微博文本情感分析
1.在大量通用语料上训练一个LM (Pretrain) :中文谷歌BERT
2.在相同领域上继续训练LM (Domain transfer 领域自适应/迁移) :在大量微博文本上继续训练这个BERT
3.在任务相关的小数据上继续训练LM(Task transfer) :在微博情感文本上(有的文本不属于情感分析
的范畴)
4.在任务相关数据上做具体任务(Fine-tune)。
先Domain transfer再进行Task transfer最后Fine-tune 性能是最好的。

在相同领域数据中进行further pre-training:

1.动态mask:就是每次epoch去训练的时候mask,每次mask的单词都是不一样的,而不是一直使用同一个。
2.n-gram mask:其实比如ERNIE和SpanBert都是类似于做了实体词的mask

可调节的参数:

  • Batch size:16,32一影响不太大
  • Learning rate (Adam):5e-5,3e-5,2e-5,尽可能小—点避免灾难性遗忘
  • Number of epochs:3,4
  • Weighted decay修改后的adam,使用warmup,搭配线性衰减

数据增强/自蒸馏/外部知识的融入

4.使用过的BERT模型变体之间的区别

SciBERT

是一个利用生物医学(82%)以及计算机科学(12%)方向总共114万篇科技论文预训练出来的BERT模型,更加适用于科技论文方向的自然语言处理任务。

5.使用BERT模型得到句子向量


bert类模型输出句向量sentence embedding的方式主要有两种方式:

  • 取cls表示句向量(效果较差)
  • 对所有的token值做一个pool操作(这个也是开源项目bert-as-service的默认做法)
    pool又有很多种,有取均值,最大值,用哪一层的结果又有很多讲究,有取最后一层的,取后两层的,甚至取第一层与最后一层。


sentense - transformers 发现还是用最后一层词向量求和平均做triplet - loss训练更合理

参考资料:
b站视频
使用Bert 模型需要哪些前提知识?
【NLP】 深入浅出解析BERT原理及其表征的内容
使用BERT生成句向量
如何使用预训练模型优雅的生成sentence embedding
BERT 论文解读
【译】为什么BERT有3个嵌入层,它们都是如何实现的
NLP中的Tokenization
为什么 Bert 的三个 Embedding 可以进行相加?
详解BERT阅读理解
算法面试问题三(BERT相关)
bert中的special token到底是怎么发挥作用的

posted @ 2022-05-10 16:38  YTT77  阅读(363)  评论(0编辑  收藏  举报