BERT:深度双向预训练语言模型

2023-11-08

论文标题:BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
论文链接:https://arxiv.org/abs/1810.04805

一、概述

  1. 简介

BERT(Bidirectional Encoder Representations from Transformers)通过预训练来学习无标注数据中的深度双向表示,预训练结束后通过添加一个额外的输出层进行微调,最终在多个NLP任务上实现了SOTA。

预训练语言模型在实践中证明对提高很多自然语言处理任务有效,其中包括句子层级的任务,比如自然语言推断(natural language inference)和复述(paraphrasing),还有token层级的任务,比如命名实体识别(named entity recognition)和问答(question answering)。

  1. 预训练模型使用方法

在下游任务中应用预训练语言模型表示的方法有两种:feature-based的方法和fine-tuning的方法。举例来说,ELMo这种预训练语言模型使用feature-based的方法,通过将ELMo的预训练的表示作为额外的特征输入到特定于任务的模型中去;GPT使用fine-tuning的方法,通过引入少量的特定于任务的参数,在下游任务中训练时所有的预训练参数。

  1. 语言模型的单向与双向

截止BERT之前的预训练语言模型都是单向的(unidirectional),包括GPT和ELMo,这样的方法对句子层级的任务不是最优的,而且对于token层级的任务比如问答非常有害。BERT使用masked language model(MLM)的方法来预训练,这种方法能够训练一个双向的(directional)语言模型。除了masked language model的预训练的方法,BERT还使用了next sentence prediction的预训练方法。

  1. BERT的贡献
  • BERT证明了双向预训练的重要性;

  • BERT减少了对精心设计的特定于下游任务中的架构的依赖;

  • BERT在11个下游任务上达到了SOTA。

二、BERT

BERT的使用分为两个阶段:预训练(pre-training)和微调(fine-tuning)。预训练阶段模型通过两种不同的预训练任务来训练无标注数据。微调阶段模型使用预训练参数初始化,然后使用下游任务(downstream task)的标注数据来微调参数。

BERT的一个显著特点是它在不同的任务上有统一的架构,使用时只需要在BERT后面接上下游任务的结构即可使用。

  1. 模型架构

BERT的模型架构是一个多层双向的Transformer的encoder。我们标记模型的层数(每一层是一个Tranformer的block)为 L L L,模型的hidden size为 H H H,self-attention head的数量为 A A A。两个比较通用的BERT架构为 B E R T B A S E ( L = 12 , H = 768 , A = 12 , T o t a l    P a r a m e t e r s = 110 M ) BERT_{BASE}(L=12,H=768,A=12,Total\; Parameters=110M) BERTBASE(L=12,H=768,A=12,TotalParameters=110M) B E R T L A R G E ( L = 24 , H = 1024 , A = 16 , T o t a l    P a r a m e t e r s = 340 M ) BERT_{LARGE}(L=24,H=1024,A=16,Total\; Parameters=340M) BERTLARGE(L=24,H=1024,A=16,TotalParameters=340M)

对比GPT,BERT使用了双向self-attention架构,而GPT使用的是受限的self-attention, 即限制每个token只能attend到其左边的token。

  1. BERT输入和输出的表示

BERT的输入表示能够是一个句子或者是一个句子对,这是为了让BERT能够应对各种不同的下游任务。BERT的输入是一个序列,该序列包含一个句子的token或者两个句子结合在一起的token。

具体地,我们会将输入的自然语言句子通过WordPiece embeddings来转化为token序列。这个token序列的开头要加上[CLS]这个特殊的token,最终输出的[CLS]这个token的embedding可以看做句子的embedding,可以使用这个embedding来做分类任务。

由于句子对被pack到了一起,因此我们需要在token序列中区分它们,具体需要两种方式:
①在token序列中两个句子的token之间添加[SEP]这样一个特殊的token;
②我们为每个token添加一个用来学习的embedding来区分token属于句子A还是句子B,这个embedding叫做segment embedding。

具体地,BERT的输入由三部分相加组成:token embeddings、segment embeddings和position embeddings。如下图所示:

BERT input

  1. BERT的预训练

BERT使用两个无监督的任务进行预训练,分别是Masked LM和Next Sentence Prediction(NSP)。如下图所示,我们定义输入的embedding为 E E E,BERT最终输出的[CLS]的embedding为 C ∈ R H C\in \mathbb{R}^{H} CRH,最终输出的第 i t h i^{th} ith个token的embedding为 T i ∈ R H T_{i}\in \mathbb{R}^{H} TiRH

pre-training

  • Task 1: Masked LM

我们有理由相信一个深度双向模型比left-to-right模型和left-to-right和right-to-left简单连接的模型的效果更加强大。不幸的是,标准的条件语言模型只能够够left-to-right或者right-to-left地训练,这是因为双向条件会使每个token能够间接地“看到自己”,并且模型能够在多层上下文中简单地预测目标词。

为了能够双向地训练语言模型,BERT的做法是简单地随机mask掉一定比例的输入token(这些token被替换成[MASK]这个特殊token),然后预测这些被遮盖掉的token,这种方法就是Masked LM(MLM),相当于完形填空任务(cloze task)。被mask掉的词将会被输入到一个softmax分类器中,分类器输出的维度对应词典的大小。在预训练时通常为每个序列mask掉15%的token。与降噪自编码器(denoising auto-encoders)相比,我们只预测被mask掉的token,并不重建整个输入。

这种方法允许我们预训练一个双向的语言模型,但是有一个缺点就是造成了预训练和微调之间的mismatch,这是因为[MASK]这个token不会在微调时出现。为了缓解这一点,我们采取以下做法:在生成训练数据时我们随机选择15%的token进行替换,被选中的token有80%的几率被替换成[MASK],10%的几率被替换成另一个随机的token,10%的几率该token不被改变。然后 T i T_i Ti将使用交叉熵损失来预测原来的token。

  • Task 2: Next Sentence Prediction (NSP)

一些重要的NLP任务如Question Answering (QA)或者Natural Language Inference (NLI)需要理解句子之间的关系,而这种关系通常不会被语言模型直接捕捉到。为了使得模型能够理解句子之间的关系,我们训练了一个二值的Next Sentence Prediction任务,其训练数据可以从任何单语语料库中生成。具体的做法是:当选择句子A和句子B作为训练数据时,句子B有50%的几率的确是句子A的下一句(标签是IsNext),50%的几率是从语料库中随机选择的句子(标签是NotNext)。[CLS]对应的最后一个隐层输出向量被用来训练NSP任务,这个embedding就相当于sentence embedding。虽然这个预训练任务很简单,但是事实上在微调时其在QA和NLI任务上表现出了很好的效果。在前人的工作中,只有sentence embedding被迁移到下游任务中,而BERT会迁移所有的参数来初始化下游任务模型。

  1. BERT的微调

Transformer的self-attention机制允许BERT建模多种下游任务。对于包含句子对的任务,通常的做法是先独立地对句子对中的句子进行编码,然后再应用双向交叉注意(bidirectional cross attention)。而BERT使用self-attention机制统一了这两个过程,这是因为对拼接起来的句子对进行self-attention有效地包含了两个句子之间的双向交叉注意(bidirectional cross attention)。

对于每个任务来说,我们只需要将任务特定的输入输出插入到BERT中然后端到端地微调即可。举例子来说,BERT的预训练输入句子A和句子B在微调时可以类比为:
①paraphrasing任务中的句子对;
②entailment任务中的hypothesis-premise对;
③question answering任务中的question-passage对;
④text classification或者sequence tagging任务中的text-∅对(也就是只输入一个text,不必一定需要两个句子)。

对于BERT的输出,对于一些token-level的任务,BERT的token表示将被输入到一个输出层,比如sequence tagging或者question answering任务;对于entailment或者sentiment analysis这样的任务,可以将[CLS]对应的表示输入到一个输出层。

三、实验

  1. GLUE

我们使用[CLS]这个token的最后一层的隐层向量 C ∈ R H C\in \mathbb{R}^{H} CRH作为聚合的表示,可以认为是sentence embedding。在微调时只引入一个新的权重 W ∈ R K × H W\in R^{K\times H} WRK×H,这里的 K K K代表标签的数量,然后计算标准分类损失 l o g ( s o f t m a x ( C W T ) ) log(softmax(CW^{T})) log(softmax(CWT))。下图展示了BERT在GLUE上的效果:

GLUE

  1. SQuAD v1.1

在这个数据集上,我们将question和passage拼接起来作为一个输入序列(中间是[SEP])。在微调时引入一个start向量 S ∈ R H S\in \mathbb{R}^{H} SRH和一个end向量 E ∈ R H E\in \mathbb{R}^{H} ERH,计算 T i T_i Ti S S S的点积然后通过 s o f t m a x softmax softmax函数作为word i i i是答案的span起始位置的概率: P i = e S ⋅ T i ∑ j e S ⋅ T j P_{i}=\frac{e^{S\cdot T_{i}}}{\sum _{j}e^{S\cdot T_{j}}} Pi=jeSTjeSTi。答案的终止位置也做上述类似处理。从 i i i j j j的候选区间的得分记作 S ⋅ T i + E ⋅ T j S\cdot T_{i}+E\cdot T_{j} STi+ETj,我们挑选 j > i j>i j>i的最大得分区间作为预测的结果。下图展示了BERT在SQuAD v1.1上的效果:

SQuAD v1.1

  1. SQuAD v2.0

SQuAD v2.0有的question在提供的passage中没有答案存在。在微调时我们设置没有答案的问题的span的起始和结束位置都是[CLS]这个token,也就是start和end的可能性空间包含进了[CLS]的位置。在预测时,我们比较没有答案的span得分 s n u l l = S ⋅ C + E ⋅ C s_{null}=S\cdot C+E\cdot C snull=SC+EC和最优的有答案得分 s ^ i , j = m a x j ≥ i S ⋅ T i + E ⋅ T j \hat{s}_{i,j}=max_{j\geq i}S\cdot T_{i}+E\cdot T_{j} s^i,j=maxjiSTi+ETj。当 s ^ i , j > s n u l l + τ \hat{s}_{i,j}>s_{null}+\tau s^i,j>snull+τ时,我们预测这是一个有答案的问题,这里的 τ \tau τ用来在dev set上选择最优的 F 1 F1 F1。下图展示了BERT在SQuAD v2.0上的效果:

SQuAD v2.0

  1. SWAG

微调时BERT的我们为BERT构建4个输入序列,每一个是所给的句子(句子A)和一个可能的延续(句子B)。然后引入一个向量,该向量和每一个输入对应的[CLS]的embedding的点积再通过一个 s o f t m a x softmax softmax层来得到每个选择的得分。下图展示了BERT在SWAG上的效果:

SWAG

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

BERT:深度双向预训练语言模型 的相关文章

随机推荐

  • 力扣刷题系列——位运算篇

    目录 几道常见的位运算算法题 1 不用加号的加法 2 最大单词长度乘积 3 比特位计数 4 整数替换 5 每个元音包含偶数次的最长子字符串 6 绘制直线 7 只出现一次的数字III 8 颠倒二进制位 9 两数相除 几道常见的位运算算法题 以
  • python基础知识三——try与except处理异常语句

    try except介绍 与其他语言相同 在python中 try except语句主要是用于处理程序正常执行过程中出现的一些异常情况 如语法错 python作为脚本语言没有编译的环节 在执行过程中对语法进行检测 出错后发出异常消息 数据除
  • 汇编 - ORG指令详解

    ORG指令 ORG是Origin的缩写 起始地址 源 在汇编语言源程序的开始通常都用一条ORG伪指令来实现规定程序的起始地址 如果不用ORG规定则汇编得到的目标程序将从0000H开始 例如 ORG 2000H START MOV AX 00
  • 使用python批量修改文件名

    使用python对文件名进行批量修改 使用split方法对原文件名进行切分 选择需要的部分进行保留做为新的文件名 也可添加字段 函数说明 split 函数 语法 str split str num string count str n 参数
  • 十六进制串口发送

    字符串转化为十六进制 让串口发送数据 int hexdata lowhexdata unsigned short int hexdatalen 0 unsigned char hexdatalenH8 hexdatalenL8 int le
  • Math类的常用方法

    在本篇文章种 我使用Type就意味着这个是类型的可变的 可以是int 也可以是double long float 1 取绝对值Math abs Type number 返回值是你传入的类型 2 向上取整Math ceil double nu
  • Element Plus 全局修改组件默认属性

    main js 这里已修改ElSelect为示例 import ElementPlus ElSelect from element plus ElSelect props clearable type Boolean default tru
  • SpringBoot集成dynamic-datasource实现多数据源自动注入

    springboot在集成dynamic datasource后配置多数据源其实还是很简单的 pom依赖
  • requests.exceptions.SSLError 请求异常,SSL错误,证书认证失败问题解决

    请求异常 SSL错误 证书认证失败解决方法 在爬取一些网站的数据时 有时候会碰到以下报错 requests exceptions SSLError HTTPSConnectionPool host martin audio com port
  • postman工具批量调用接口

    1 先在Collections中建一个文件夹 然后新建一个接口保存 2 然后选择Run 3 准备一个txt文件 增加要循环的参数json数组 4 选择接口 上传文件 配置参数 Iterations为线程数 Delay为推迟多久 然后点下面的
  • 3Dgame_homework8

    3D游戏 作业8 简单粒子制作 要求 相关理论 粒子系统 Unity 粒子系统 拟物控制 制作过程 准备 实现 光 光晕 星光 制作结果与控制 简单粒子制作 要求 按参考资源 Unity3d Particle System 系统的学习 三
  • Discuz! X3.4:若检测到未登录,返回提示登录链接

    if trim G username return lt lt
  • Java8中 Date和LocalDate的相互转换

    一 简述 Date对象表示特定的日期和时间 而LocalDate Java8 对象只包含没有任何时间信息的日期 因此 如果我们只关心日期而不是时间信息 则可以在Date和LocalDate之间进行转换 二 Date转LocalDate 如果
  • linux svn 修改回退,玩转SVN-版本回退

    当我们想放弃对文件的修改 可以使用 SVN revert 命令 svn revert 操作将撤销任何文件或目录里的局部更改 我们对文件 readme 进行修改 查看文件状态 root runoob svn runoob01 trunk sv
  • Python之模块打包

    1 什么是模块打包 模块打包目的是让自己开发的功能能够实现共享 供给他人使用 包管理索引平台 Python Package Index 2 怎么打包 tar gz格式 这个就是标准压缩格式 里面包含了项目元数据和代码 可以使用Python
  • 2021.06.15

    括号生成 力扣 方法 回溯 回溯算法框架 result def backtrack 路径 选择列表 if 满足结束条件 result add 路径 return for 选择 in 选择列表 做选择 backtrack 路径 选择列表 撤销
  • DeBruijin 【HDU - 2894】【欧拉回路】

    题目链接 可以说这题是着实有趣了 题意 我们给出一个K 现在我们想最多的表示从 的数 也就是00 0 11 1 0 1都是K个 譬如说K 3 我们可以用字典序最小的 00010111 按顺序的用二进制表示 000 001 010 101 0
  • github Page博客速度优化+Cloudflare_https两端配置+解决重定向次数过多问题

    网站加速调优 自从加了CDN之后我的博客偶尔会报错 重定向次数过多 症状 XXX XXX XXX 将您重定向的次数过多 尝试清除 Cookie ERR TOO MANY REDIRECTS 可能原因 参考阿里云cdn解决方案https he
  • Spark机器学习实例

    2020 07 09 引言 Learning Spark 过程中只是简单介绍了mllib中的东西 没有一个完整的实践过程 暂时还没有去找有没有专门做这种的书 好像我看 spark in action 是有这部分内容 后续在看 本篇文章就利用
  • BERT:深度双向预训练语言模型

    论文标题 BERT Pre training of Deep Bidirectional Transformers for Language Understanding 论文链接 https arxiv org abs 1810 04805