【NLP】BERT模型

目录

一、认识

1.1 背景

1.2 提出

二、Bert网络结构

2.1 Input Embedding

2.2 Bert Encoder

三、Bert预训练

3.1 MLM

3.2 NSP

四、特点

五、变长与定长Bert


一、认识

BERT(Bidirectional Encoder Representation from Transformers)是2018年10月由Google AI研究院提出的一种预训练模型,该模型在机器阅读理解顶级水平测试SQuAD1.1中表现出惊人的成绩: 全部两个衡量指标上全面超越人类,并且在11种不同NLP测试中创出SOTA表现,包括将GLUE基准推高至80.4% (绝对改进7.6%),MultiNLI准确度达到86.7% (绝对改进5.6%),成为NLP发展史上的里程碑式的模型成就

BERT的网络架构使用的是多层Transformer Encoder结构。其最大的特点是抛弃了传统的RNN和CNN,通过Attention机制将任意位置的两个单词的距离转换成1,有效的解决了NLP中棘手的长期依赖问题

1.1 背景

预训练语言模型(Language model pre-training)对于下游很多自然语言处理任务都有着显著的改善。但是作者说到,现有预训练模型的网络结构限制了模型本身的表达能力,其中最主要的限制就是没有采用双向编码的方法来对输入进行编码

OPENAI GPT中使用了从左到右(left-to-right)的网络架构,使得模型在编码过程中只能看到之前的信息

如上图所示。对于这句样本来说,无论是采用left-to-right还是right-to-left的方法,模型在对"it"进行编码时都不能够很好的捕捉到其具体的指代信息。就像人在看这句话时一样,在没有看到"tired"这个词前无法判断"it"具体所指代的事物(如:把"tired"换成"wide",则"it"指代的就是"street")。若采用双向编码的方式则从理论上来说就能够很好的避免这个问题

橙色线条表示"it"应将注意力集中在哪些位置上,颜色越深表示注意力权重越大。通过上图可以发现,模型在对"it"进行编码时,将大部分注意力都集中在了"The animal"上,而这也符合实际预期

1.2 提出

BERT(Bidirectional Encoder Representations from Transformers)这一网络结构来实现模型的双向编码学习能力。同时,为了使得模型能够有效的学习到双向编码的能力,BERT在训练过程中使用了基于掩盖的语言模型(Masked Language Model,MLM),即随机对输入序列中的某些位置进行遮蔽,然后通过模型来对其进行预测

由于MLM预测任务能够使得模型编码得到的结果同时包含上下文的语境信息,有利于训练得到更深的BERT网络模型。除此之外,在训练BERT的过程中还加入了下句预测任务(Next Sentence Prediction, NSP),即同时输入两句话到模型中,然后预测第2句话是不是第1句话的下一句话

二、Bert网络结构

多个Transformer Encoder一层一层地堆叠起来,就组装成了BERT了,在论文中,作者分别用12层和24层Transformer Encoder组装了两套BERT模型,两套模型的参数总数分别为110M和340M

可以发现上半部分与之前的Transformer Encoder差不多,只不过在Input部分多了一个Segment Embedding

2.1 Input Embedding

在BERT中Input Embedding主要包含三个部分:Token Embedding、Positional Embedding和Segment Embedding。虽然前面两种 Embedding 在 Transformer 中已经介绍过,但是这里需要注意的是BERT中的 Positional Embedding 对于每个时刻的位置并不是采用公式计算出来的,其原理也是类似普通的词嵌入一样为每一个位置初始化了一个向量,然后随着网络一起训练

BERT开源的预训练模型最大只支持 512 个字符的长度,这是因为其在训练过程中(位置)词表的最大长度只有 512

由于 BERT 的主要目的是构建一个通用的预训练模型,因此难免需要兼顾到各种 NLP 任务场景下的输入。因此 Segment Embedding 的作用便是便是用来区分输入序列中的不同序列,其本质就是通过一个普通的词嵌入来区分每一个序列所处的位置。如在 NSP 任务中,那么对于任意一个序列的每一位置都将用同一个向量来进行表示,即此时 Segment 词表的长度为 2

最后,再将这三部分 Embedding 后的结果相加(并进行标准化)便得到了最终的 Input Embedding 部分的输出

最上面的 Input 表示原始的输入序列,其中第一个字符 [CLS] 是一个特殊的分类标志,若下游任务是做文本分类的话,那么在BERT的输出结果中可以只取 [CLS] 对应的向量进行分类即可;而其中的 [SEP] 字符则是用来作为将两句话分开的标志。Segment Embedding层则同样是用来区分两句话所在的不同位置,对于每句话来说其内部各自的位置都是一样的,若原始输入就只有一句话,那么 Segment Embedding 层中对应的每个 Token 的位置向量都是一样的。Positional Embedding 是用来标识句子中每个 Token 各自所在的位置,使得模型能够捕捉到文本"有序"这一特性

2.2 Bert Encoder

其整体由多个BertLayer(也就是论文中所指代的Transformer blocks)所构成

在Transformer中,模型的输入会被转换成512维的向量,然后分为8个head,每个head的维度是64维。但是BERT的维度是768维度,然后分成12个head,每个head的维度是64维

BERT模型分为24层和12层两种,其差别就是使用Transformer Encoder的层数的差异,BERT-base使用的是12层的Transformer Encoder结构,BERT-Large使用的是24层的Transformer Encoder结构

三、Bert预训练

BERT是一个多任务模型,其预训练(Pre-training)任务是由两个自监督任务组成,即MLM和NSP

3.1 MLM

Masked LM,MLM是指在训练的时候随即从输入语料上 mask 掉一些单词,然后通过的上下文预测该单词,该任务非常像在中学时期常做的完形填空

正如传统的语言模型算法和RNN匹配那样,MLM 的这个性质和 Transformer 的结构是非常匹配的。在BERT的实验中,随机的抽取 15% 的 token 作为参与 MASK 任务的对象。在训练模型时,一个句子会被多次喂到模型中用于参数学习,但是 Google 并没有在每次都 mask 掉这些单词,而是在确定要 Mask 掉的单词之后,做以下处理:

  • 80%的时候会直接替换为[Mask],将句子 "my dog is cute" 转换为句子 "my dog is [Mask]"
  • 10%的时候将其替换为其它任意单词,将单词 "cute" 替换成另一个随机词,例如 "apple"。将句子 "my dog is cute" 转换为句子 "my dog is apple"。
  • 10%的时候会保留原始Token,例如保持句子为 "my dog is cute" 不变

优点

  • 被随机选择15%的词当中以10%的概率用任意词替换去预测正确的词,相当于文本纠错任务,为BERT模型赋予了一定的文本纠错能力
  • 被随机选择15%的词中以10%的概率保持不变,缓解了微调时与预训练时输入不匹配的问题(预训练时输入句子中有mask,而 finetune 时输入是完整无缺的句子,即输入不匹配问题)

缺点

针对有两个及两个以上连续字组成的词,随机mask字割裂了连续字之间的相关性,使模型不太容易学习到词的语义信息。主要针对这一短板,因此 google 此后发表了 BERT-WWM,国内的哈工大联合讯飞发表了中文版的 BERT-WWM

为什么采用了80%, 10%, 10%的策略?

  • 若所有参与训练的 token 被 100% 的 [MASK],模型就只能根据其他 token 的信息和语序结构来预测当前词,而无法利用到这个词本身的信息。因为从未出现在训练过程中,等于模型从未接触到该信息,整个语义空间损失了部分信息。采用 80% 的概率下应用 [MASK],既可以让模型去学着预测这些单词,又以 20% 的概率保留了语义信息展示给模型

  • 保留下来的信息若全部使用原始 token,那么模型在预训练时可能会偷懒,直接照抄当前 token 信息。假设模型看到一个未被掩盖的 token 是“苹果”,可能会直接记住这个位置的 token 是 "苹果",而不需要去理解周围上下文(如"我吃了一个____")。采用 10% 概率 random token 随机替换当前 token,会让模型不能去死记硬背当前的 token,而去尽力学习单词周边的语义表达和远距离的信息依赖

  • 最后再以 10% 的概率保留原始的token,意义就是保留语言本来的面貌,让信息不至于完全被遮掩,使得模型可以"看清"真实的语言面貌

  • 至于单词带来的负面影响,因为一个单词被随机替换掉的概率只有 15%*10% =1.5%,这个负面影响是可以忽略不计的。 另外文章指出每次只预测15%的单词,因此模型收敛的比较慢

3.2 NSP

Next Sentence Prediction(NSP)的任务是判断句子B是否是句子A的下文。若是的话输出"IsNext",否则输出"NotNext"。训练数据的生成方式是从平行语料中随机抽取的连续两句话,其中 50% 保留抽取的两句话,符合 IsNext 关系;另外 50% 的第二句话是随机从预料中提取的,关系是 NotNext 的。这个关系保存在 [CLS] 符号中

输入 = [CLS] 我 喜欢 玩 [Mask] 联盟 [SEP] 我 最 擅长 的 [Mask] 是 亚索 [SEP]

类别 = IsNext

输入 = [CLS] 我 喜欢 玩 [Mask] 联盟 [SEP] 今天 天气 很 [Mask] [SEP]

类别 = NotNext

在此后的研究(论文《Crosslingual language model pretraining》等)中发现,NSP任务可能并不是必要的,消除 NSP 损失在下游任务的性能上能够与原始BERT持平或略有提高。这可能是由于 BERT 以单句子为单位输入,模型无法学习到词之间的远程依赖关系。针对这一点,后续的RoBERTa、ALBERT、spanBERT都移去了 NSP 任务

BERT预训练模型最多只能输入512个词,因为在 BERT 中,Token,Position,Segment Embeddings 都是通过学习来得到的。在直接使用 Google 的 BERT 预训练模型时,输入最多512个词(还要除掉[CLS]和[SEP]),最多两个句子合成一句。这之外的词和句子会没有对应的embedding

四、特点

优点

  • BERT 的根基源于 Transformer,相比传统 RNN 更加高效,可以并行化处理同时能捕捉长距离的语义和结构依赖
  • BERT 采用了 Transformer 架构中的 Encoder 模块, 不仅仅获得了真正意义上的 bidirectional context,而且为后续微调任务留出了足够的调整空间

缺点

  • BERT 模型过于庞大,参数太多,不利于资源紧张的应用场景
  • BERT 目前给出的中文模型中,是以字为基本 token 单位的,很多需要词向量的应用无法直接使用。同时该模型无法识别很多生僻词,只能以UNK代替
  • BERT 的预训练任务 MLM 中,[MASK] 标记只在训练阶段出现,而在预测阶段不会出现,这就造成了一定的信息偏差,因此训练时不能过多的使用[MASK],否则会影响模型的表现
  • 按照 BERT 的 MLM 任务中的约定,每个 batch 数据中只有 15% 的 token参与了训练,被模型学习和预测,所以BERT收敛的速度比 left-to-right 模型要慢很多(left-to-right模型中每一个token都会参与训练)

BERT处理长文本的方法

BERT预训练模型所接收的最大sequence长度是512

对于长文本(长度超过512的句子),就需要特殊的方式来构造训练样本。核心是如何进行截断

  • head-only 方式:只保留长文本头部信息的截断方式,具体为保存前510个token(留两个位置给 [CLS] 和 [SEP])
  • tail-only 方式:只保留长文本尾部信息的截断方式,具体为保存最后 510 个 token(要留两个位置给 [CLS] 和 [SEP])
  • head+only 方式:选择前 128 个token和最后 382 个token(文本总长度在800以内),或者前 256 个token和最后 254 个token(文本总长度大于800)

五、变长与定长Bert

在批量输入时,定长Bert模型通常有三个输入

  • input_ids:句子分词后通过词表映射得到的结果
  • segment_ids:作用于输入序列中的每个词元,目的是对序列内部的不同语义部分进行精细划分和标记,帮助模型理解输入文本中不同句子或语义片段之间的关系,从而更好地捕捉语义信息和逻辑结构
  • input_mask:填充掩码,用于指明哪些值是有效值、哪些是填充值。一个批次中的数据通常需要填充到统一序列长度,填充的值通常是 0

变长Bert输入的数据则通常不需要进行填充,使用 cu_seqlens(累积序列长度)来记录每个序列的长度信息。通过 cu_seqlens 数组,模型可以明确每个序列在输入中的起始和结束位置,从而在计算过程中准确地对每个序列进行处理,避免了不同序列信息的混淆,所以不需要填充

cu_seqlens 是从宏观层面管理序列的长度和边界,而 segment_ids 是从微观层面细分序列内部的语义结构,二者的功能和侧重点完全不同

很多情况下,一句话 segment_ids 相同,看起来其也能用于分割文本边界,但并不是这样的,一句话中的 segment_ids 并不一定相同

注意:cu_seqlen是TensorRT中的特殊优化手段,正常训练模型时并不存在

无需填充带来的好处

减少计算量

由于不需要对输入数据进行填充,变长 BERT 在计算过程中可以避免处理大量的填充标记,从而减少了计算量。特别是在处理大量短序列时,这种优势更为明显,可以显著提高模型的推理速度

避免信息稀释

填充操作可能会稀释输入序列中的有效信息,因为模型需要处理大量的无意义填充标记。变长 BERT 避免了填充,使得模型能够更加专注于真实的输入信息,从而提高了模型的性能和准确性

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

GG_Bond21

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

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

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

打赏作者

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

抵扣说明:

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

余额充值