初探BERTPre-trainSelf-supervise

news2024/11/17 7:47:22

初探Bert

因为一次偶然的原因,自己有再次对Bert有了一个更深层地了解,特别是对预训练这个概念,首先说明,自己是看了李宏毅老师的讲解,这里只是尝试进行简单的总结复述并加一些自己的看法。

说Bert之前不得不说现在的语言模型与芝麻街有密切的联系了:

image-20211205162408602

What is pre-train

以前,在自然语言处理中,是一个任务就有一个对应的模型来使用,但是现在却出现了另外一种设计方法——预训练。

这篇文章分析了预训练模型的由来,我认为就是原来的word embedding由于无法解决不同语义下不同词的不同性,因此才有了这样的大模型。

但是我个人认为Bert这样的预训练模型既可以是属于sentence level的,也可以属于word level的,因为如果从预训练任务上来考虑,BERT是sentence level的;如果从输出层面上来看,每一个word Token对应不同的represence,这样又是word level。

预训练的设计思路是这样的,先通过在大量的文章进行无监督训练,让模型具有一定的语言能力,然后再根据不同的任务进行微调,具体来说可以用下图来表示:

image-20211205162103690

那么现在就可以认为预训练模型其实就是生成embedding vector,即将每一个token转变成embedding vector。以前的方法是用Word2vector,现在来说,就是用预训练模型来实现的

不同的预训练模型可以使用不同的架构,比如说现在的ELMo使用的就是LSTM来实现的,Bert使用的就Transformer来实现的。

How to fine-tuned

我们目前知道了预训练模型其实就是生成了embedding vector ,但是如何用到不同任务领域呢?

那就是需要用到fine-tune来实现了,其实微调的本质就是在预训练模型之后添加一个任务层就好:

image-20211205163113042

为了更好地说明如何微调,这里简单地根据输入和输出将NLP概括成2类的输入问题和4类的输出问题。

首先看输入部分:

  • 输入的是一个句子:那就直接丢入模型中就好;
  • 如果是输入了多个句子(这里以两个句子来说明):将两个句子合并成为一个句子就好,只不过需要对输入的句子做划分,这样才可以说明句子中的token是来自于哪个句子的;这里以QA问题来说明,那么两个句子就是一个句子对<Query, Answer>,只不过需要在两个句子中添加一个分隔符[SEP]
    • image-20211205163747281

输入部分:

  • 单分类问题
    • 这个问题的处理方法,以BERT为例,BERT中是使用了一个特殊的符号[CLS],只要是输入了这个符号在句子的首位置,那么就是说明这是一个分类问题,那么最后预训练模型的输出应该是在第一个位置考虑整个句子的文字情况(也就是在预训练过程中,训练告诉模型,一旦看到了[CLS],就产生和整个句子有关的embedding)。
    • image-20211205164404994
  • 对于多分类问题,就可以用下面的图示的方法来做:
    • image-20211205164621211
  • 问答问题(copy from input)
    • 这个任务具体来说就是根据输入的文本,能狗根据文章中的信息来回答所提问的问题,根据下图来说是就是需要模型能够预测出问题在文中的起始位置s和结束位置e。
    • image-20211205164930033
  • sequence问题
    • 这个问题就来说一下怎么实现seq2seq模型,其实很简单地就可以想到seq2seq的实现方法就是用两个模型的拼接就好(encode和decode),如下图所示,但是这样的模型就存在了一个问题——Decoder没有pre-train,那么就还需要继续训练,这样就与我们预训练的初心相违背了。
      • image-20211205165346055
    • 因此基于这个问题,对预训练模型进行修改如下
      • image-20211205165608011

至此我们已将NLP中存在的任务进行了简要的概述,那么回到这一小节的主题——如何微调。

微调有两种方法:

  • 一种是只需要微调自己的任务层,预训练的部分不需要做改动;
    • image-20211205165954391
  • 另一种就是将预训练的部分和任务层看成一个整体来进行微调的工作(这样的效果更好一些);
    • image-20211205170040743

这里无意间发现了self-supervised learning的定义是来自Yann LeCun,他定义了将这种无监督的训练方法定义叫做自监督的训练,因为模型的输入和输出都是模型自己找到的,并非是人工标注的。

image-20211205210153881

BERT

Abstract

好了,言归正传,BERT的出现真的是在NLP领域掀起了一阵不小的轰动,从BERT文章的Abstract部分就可以看出,BERT是结合了GPT和ELMo两个模型的框架特点——是一个深层次的以Transformer为Backbone的双向架构。这样的设计的方法可以在预训练之后的BERT模型之上添加一个额外的输出层便可以实现各种下游任务(其实这个地方就是微调,跟GPT一样,只需要改上层结构就可以了)。

Introduction

文中说到,NLP中的任务可以分为两个方向:

  • sentence-level tasks——如句子分类、情感分析和语言推理等;
  • token-level tasks——如NER、问答等

在使用预训练模型做特征表示的时候,一般是有两类策略:

  • feature-based——基于特征的,以ELMo为例,使用ELMo的时候需要根据任务构建一个特定的框架,然后将预训练模型得到的特征表示作为模型额外的输入一起输入构造的模型当中。

    • 下图取自Improving a Sentiment Analyzer using ELMo — Word Embeddings on Steroids这篇文章,下图说明了ELMo的工作方式。

      img

      下图是说明feature-based的方式:

      image-20211215180110074
  • fine-tuning——基于微调的,以GPT为例(其实BERT本身也是用的fine-tune),主要就是根据不同的下游任务对模型中的所有参数进行简单的微调即可。

由于标准的语言模型本身是单向的,这样的训练方式就限制了预训练模型表征能力,存在一定的局限性,因此文中提出了改进,即BERT的是基于双向设计的。

但是这个BERT的框架从细节上还是跟我想到的是不一样的,因为原文中只是说其只是采用了Transformer的encoder部分,那么到底是什么样子的,我从别的地方找到了BERT的框架:

image-20211208135108961

模型可以简单的归纳为三个部分,分别是输入层,中间层,以及输出层。这些都和transformer的encoder一致,除了输入层有略微变化

Pretext task

pretext tasl1

BERT是这样设计的(这也是BERT模型的创新点或者贡献之一),提出了MLM(Masked Language Model),这种带掩码的语言模型是这样设计的:

image-20211215175752742
  • 随机把一句话中15%的token(字或词)替换成以下内容:

    1. 这些token有80%的几率被替换成[MASK],例如my dog is hairy→my dog is [MASK]

    2. 有10%的几率被替换成任意一个其它的token,例如my dog is hairy→my dog is apple

    3. 有10%的几率原封不动,例如my dog is hairy→my dog is hairy

      1. 这个地方为什么这样设计,我至今也没搞明白为什么。

        文中在附录C.2中提到了这个MASK的问题,他是这样解释的——“Note that the purpose of the masking strategies is to reduce the mismatch between pre-training and fifine-tuning, as the [MASK] symbol never appears during the fifine-tuning stage.”

        也就是说该策略令到BERT不再只对[MASK]敏感,而是对所有的token都敏感,以致能抽取出任何token的表征信息。意思是说,首先模型是不知道哪个位置是需要被预测的,但是每个位置有15%的可能性是[MASK]这个特殊Token,但是实际上这15%中只有80%才会被替换成[MASK]。

        对于语言模型的预测,文中是这样说的“ the fifinal hidden vectors corresponding to the mask tokens are fed into an output softmax over the vocabulary, as in a standard LM”这样模型就不回仅仅看到[MASK]就预测了,也就是说[MASK]还仅仅是一个Token罢了,模型是不知道这个位置是需要去预测的,因为最后是经过了一个softmax层,故这样的做的目的纯粹就是让模型自己学习预测每个位置的可能性,[MASK]位置可能就是所有token的可能性,但是不评论模型做得是否对。

        同时在附录A.1中也提到“The advantage of this procedure is that the Transformer encoder does not know which words it will be asked to predict or which have been replaced by random words, so it is forced to keep a distributional contextual representation of every input token. Additionally, because random replacement only occurs for 1.5% of all tokens (i.e., 10% of 15%), this does not seem to harm the model’s language understanding capability“。

        也就是说采用MASK的方法可以让预训练模型来学习分布式上下文的表征。

        文章在C.2中也做了消融实验,说明了为什么要这样定义,从验证集的效果上说明了这样定义的效果:

        image-20211208103839836

        In the table, MASK means that we replace the target token with the [MASK] symbol for MLM; SAME means that we keep the target token as is; RND means that we replace the target token with another random token.

这样的设计方法可以不仅仅是只能看前面的语言信息来预测后面的语言信息了。

pretext task2

除了提出了一个语言模型之外,文中还提出了一个任务叫做——“next sentence prediction”(贡献二),这个任务的思想就是给你两个句子(文中称为句子对),让你判断两个句子是不是相邻的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zQ53mzcm-1686469797592)(null)]

仅仅一个MLM任务是不足以让 BERT 解决阅读理解等句子关系判断任务的,Next Sequence Prediction(NSP)任务判断句子B是否是句子A的下文,如果是的话输出’IsNext‘,否则输出’NotNext‘。这样可以使模型学习句子层面上的信息。

到底这个next sentence prediction对预训练模型有没有用,文中也做了消融实验,效果如下:

image-20211208105711683

补充:

在19年有文章说明了这个NSP的效果,对于BERT理解句子层面上的信息,产生的效果作用很小:

Yinhan Liu, Myle Ott, Naman Goyal, Jingfei Du, Man-dar Joshi, Danqi Chen, Omer Levy, Mike Lewis,Luke Zettlemoyer, and Veselin Stoyanov. 2019.Roberta: A robustly optimized bert pretraining ap-proach. arXiv preprint arXiv:1907.11692

下面这篇文章指出了

On the Sentence Embeddings from Pre-trained Language Models

以上这两个创新点是为了预训练BERT而提出的,也就是说通过这两个任务可以让BERT通过自监督学习的两个任务来学习相关的表征然后应用到不同的下游任务。

这篇文章中也总结了在NLP中其他自监督预训练任务

Detail

文章对BERT对工作划分为两个部分:预训练和微调。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-89LlItyC-1686469797772)(null)]

通过上图可以看出,BERT预训练是在大量的无标签的句子对上进行训练的,而在微调的时候,根据不同的任务,使用相同的预训练模型的权重,然后进行微调。

文中说自己训练了两个BERT模型,一个是 B E R T B A S E BERT_{BASE} BERTBASE(L=12,H=768,A=12),另一个是 B E R T L A R G E BERT_{LARGE} BERTLARGE(L=24,H=1024,A=16), 因为该模型的Backbone是采用了Transformer,因此这里的参数都是指代的Transformer里面的参数,这里就不解释了。

输入和输出

BERT预训练的输入被定义为“sequence”,这个sequence被描述为一个或者两个句子的集合,其中序列的词典是由WordPiece方法生成的。

WordPiece这个方法是将每一个单词作为处理单元,但是考虑到单词的复合型(存在词根或词缀)的现象,或者说某些词出现的频率很小,因此会将一个很长的词进行切分,这样的话就可以用一个大小为3w的token 字典来表示了。

# wordpiece就是一个subword的编码方式,经过WordpieceTokenizer 之后,将词变为了word piece, 例如:
input = "unaffable"
output = ["un", "##aff", "##able"] # 其中##表示紧跟的意思

这样子的好处是,可以有效的解决OOV的问题,但是mask wordpiece的做法也被后来(ERNIE以及SpanBERT等)证明是不合理的,没有将字的知识考虑进去,会降低精度,于是google在此版的基础上,进行Whole Word Masking(WWM)的模型。需要注意的是,中文的每个字都是一个word piece,所以WWM的方法在中文中,就是MASK一个词组。

对于输入的sequence来说,第一个Token永远都是[CLS]的特殊token,这个特殊token会在最后的隐藏层中,被用来表示整个句子的分类任务。

另外,为了区分两个句子,文中说到了两个方式:

  • 两个句子之间添加一个特殊的token——[SEP];
  • 针对每一个输入的token,需要添加一个learned 嵌入层(Embedding)来表示token是属于sentenceA还是sentenceB的
    • 在下图中红框里面的E向量就是需要学习的嵌入层Embedding
    • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-omgD9eRT-1686469797553)(null)]

对于BERT的输入(也就是输入到Transformer里面的数据),是由三部分构成的(如下图所示),分别是Token嵌入层(这里没有明确说明是怎么得到的,我在某篇博客看到BERT这部分的实现是用了nn.Embddding来实现的)+句子嵌入层+位置嵌入层(位置嵌入层是经过学习得来的,并非是跟Transformer里面一样是计算出来的)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SsBIXKt8-1686469797572)(null)]

在BERT中,不管是Position Embedding(该向量的取值在模型训练过程中自动学习,用于刻画文本的全局语义信息,并与单字/词的语义信息相融合)还是Segment Embeddings(由于出现在文本不同位置的字/词所携带的语义信息存在差异(比如:“我爱你”和“你爱我”),因此,BERT模型对不同位置的字/词分别附加一个不同的向量以作区分)都是自己学习得到的(也就是说一开始是随机生成的,让模型自己学习)。

这篇文章从源码的角度上分析了为何是使用这三种相加,以及如何使用这三种嵌入层的信息相加。

BERT模型的主要输入是文本中各个字/词(或者称为token)的原始词向量,该向量既可以随机初始化,也可以利用Word2Vector等算法进行预训练以作为初始值;

输出是文本中各个字/词融合了全文语义信息后的向量表示

预训练

在预训练过程中,其实就是围绕着两个任务来做的,一个是Masked LM的训练,另一个就是NSP(Next Sentence Prediction)

其实我一直对如何预训练的过程不了解,也不明白是怎么用这两个任务来做预训练的,文中只是说进行预测,那么到底是怎么预测的还是不知道的,还需要继续探索。

至此,笔记的记录已经结束,原文的剩下部分就是介绍如何微调的,这里就不做讨论了。

参考

  • https://www.nowcoder.com/discuss/351902

  • 部分代码:https://zhuanlan.zhihu.com/p/103226488

  • [PPT下载链接](https://pan.baidu.com/s/1LovEFd4Fswwk0jr8wIKkvA?pwd=ajh9 提取码:ajh9)

  • 关于BERT预训练的knowlage

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EFKESPnV-1686469794665)(null)]

  • 自监督学习: 人工智能的未来从CV到NLP

关于机器学习的作用,LeCun做了一个形象的比喻,如下图所示:强化学习像蛋糕上的樱桃,监督学习像蛋糕上的糖霜,而自监督学习是蛋糕本身。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n22C1i9Y-1686469797756)(null)]

通过这个比喻,可以很好的理解自监督学习在人工智能中的重要基石作用。

  • 什么是自监督学习:https://amitness.com/2020/02/illustrated-self-supervised-learning/

    中文:https://zhuanlan.zhihu.com/p/110278826

  • 我的博客链接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/634504.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ansible远程执行指令,/bin/sh: java: command not foundnon-zero return code

问题描述&#xff1a;ansible远程执行指令&#xff0c;初选指令加载不全&#xff0c; [rootVM-0-6-centos ~]# ansible all -m shell -a "java -version" 10.206.0.15 | FAILED | rc127 >> /bin/sh: java: command not foundnon-zero return code 解决方案&a…

C++(8):IO 库

IO 类 IO 库类型和头文件 iostream 定义了用于读写流的基本类型&#xff0c;fstream 定义了读写命名文件的类型&#xff0c;sstream 定义了读写内存 string 对象的类型。 其中带 w 前缀的类型用来操作宽字符语言 (wchar_t)。宽字符版本的类型和函数前都有一个 w&#xff0c;如…

SAP从入门到放弃系列之PP/DS-part1

翻译一篇大佬文章&#xff0c;了解一下PPDS前世今生和产品功能出现的业务背景。虽然是15年的&#xff0c;但经典永流传~~~&#xff0c;感谢大佬的文章。 原文地址&#xff1a; #S4HANA 1610 use case series: 9a – Production Planning and Detailed Scheduling – PP/DS (b…

【MySQL学习笔记】子查询与联结(连接)

1.子查询 将一条select语句返回的结果用于另一条select语句的where子句中。 执行时&#xff0c;先执行子查询&#xff0c;再执行主查询。 select sid from sc where cid in (select cid from course where cname数据库应用技术);子查询一般与 IN 操作符结合使用&#xff0…

《微服务实战》 第三十二章 微服务链路跟踪-sleuth zipkin

前言 大型分布式微服务系统中&#xff0c;一个系统被拆分成N多个模块&#xff0c;这些模块负责不同的功能&#xff0c;组合成一套系统&#xff0c;最终可以提供丰富的功能。在这种分布式架构中&#xff0c;一次请求往往需要涉及到多个服务服务之间的调用错综复杂&#xff0c;对…

Lenovo Yoga-710-14IKB电脑 Hackintosh 黑苹果efi引导文件

原文来源于黑果魏叔官网&#xff0c;转载需注明出处。&#xff08;下载请直接百度黑果魏叔&#xff09; 硬件配置 硬件型号驱动情况 主板Lenovo Yoga 710 (14") - 14IKB (without dGPU) 处理器Intel i5-7200U (4) 2.50GHz (IKBL)已驱动 内存48 GB ( 海盗船 DDR4 3200…

web worker创建多个 JavaScript 线程 (使用GTP写的文章)

前言 最近在优化公司的一个项目&#xff0c;使用的就是web worker去优化&#xff0c;做了那些优化&#xff0c;一个是状态的优化&#xff0c;&#xff08;通信的状态实时更新&#xff0c;以前的做法是做个定时任务实时获取它的状态&#xff0c;然后让它在页面渲染&#xff0c;这…

【Linux】 -- TCP协议 (一)

TCP协议 Tcp协议可靠性冯诺依曼体系结构 TCP的协议格式序号与确认序号窗口大小六个标志位 确认应答机制 &#xff08;ACK&#xff09;超时重传机制连接管理机制 Tcp协议 TCP全称为 “传输控制协议”&#xff08;Transmission Control Protocol&#xff09; TCP协议被广泛应用…

[linux_C语言_udp的多种实现方法及网络调试中遇到的问题]

linux_C语言_udp的多种实现方法 最基本的方式(不用组播不用sigio信号不使能广播属性)接收端发送端 使用SIGIO信号的方式(使用sigio信号使用广播使能属性)服务端客户端 使用组播模式服务端客户端 tcp和udp的使用区别调试中遇到的问题所有源码下载点这~~ 最基本的方式(不用组播不…

Unix/Linux编程:UDS 流(Stream)

〇、前言 socket 是一种 IPC &#xff08;Inter-Process Communication&#xff0c;进程间通信&#xff09;方法&#xff0c;它允许位于同一主机&#xff08;计算机&#xff09;或使用网络连接起来的不同主机上的应用程序之间交换数据。通过使用Socket&#xff0c;开发人员可以…

【C++】——栈和队列(stack、queue)及优先队列(priority_queue)的介绍和模拟实现

文章目录 1. 前言2. 容器适配器2.1 容器适配器的介绍2.2 STL标准库中stack和queue的底层结构2.3 deque的简单介绍2.4 deque的缺陷2.5 为什么选择deque作为stack和queue的底层默认容器 3. stack3.1 stack的介绍3.2 stack的使用3.3 stack模拟实现 4. queue4.1 queue的介绍4.2 que…

数据分布——长尾分布的处理

前言 长尾分布在分类任务中会提到这个名,这是因为长尾分布这个现象问题会导致在训练过程中会出现出错率高的问题&#xff0c;影响了实验结果。 这里要说的是&#xff0c;长尾分布是一种现象&#xff0c;有的地方说是一种理论或定律&#xff0c;我感觉这样说不太确切&#xff0…

取石子游戏——算法与编程

取石子游戏 目录 问题描述输入输出格式输入格式&#xff1a;输出格式&#xff1a; 输入输出样例输入样例#1&#xff1a;输出样例#1&#xff1a;提示信息 算法尼姆博奕 代码 问题描述 A l i c e Alice Alice和 B o b Bob Bob在玩取石子游戏&#xff0c;摆在他们面前的有 n n n堆…

GIS入门进阶之012

一、引言 空间数据可视化是有效传输与表达地理信息&#xff0c;挖掘空间数据之间的内在联系&#xff0c;揭示地理现象内在规律的重要手段。它通过运用地图学、计算机图形学和图像处理技术&#xff0c;将地学信息的输入、处理、查询、分析与预测的结果采用符号、图形、图像并结合…

OpenGL 材质实现

1.简介 在现实世界里&#xff0c;每个物体会对光产生不同的反应。比如&#xff0c;钢制物体看起来通常会比陶土花瓶更闪闪发光&#xff0c;一个木头箱子也不会与一个钢制箱子反射同样程度的光。有些物体反射光的时候不会有太多的散射&#xff0c;因而产生较小的高光点&#xf…

35岁被淘汰?软件测试工程师职业生涯规划,从技术到管理...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 入门阶段&#xf…

Parallel Desktop中按照的centos在切换root用户时,密码正确,但一直切换不成功,显示su: Authentication failure

目录 一、出现问题二、分析问题三、解决问题四、参考资料 一、出现问题 我的密码明明是输入正确的&#xff0c;但又一直给我报下面的错误 二、分析问题 我怀疑是我密码记错了&#xff0c;所以我点击Log Out&#xff0c;重新去输入了一下密码&#xff0c;发现是正确的我确认…

[学习笔记] [机器学习] 9. 朴素贝叶斯(概率基础、联合概率、条件概率、贝叶斯公式、情感分析)

视频链接数据集下载地址&#xff1a;无需下载 学习目标&#xff1a; 4. 说明条件概率与联合概率 5. 说明贝叶斯公式、以及特征独立的关系 6. 记忆贝叶斯公式 7. 知道拉普拉斯平滑系数 8. 应用贝叶斯公式实现概率的计算 9. 会使用朴素贝叶斯对商品评论进行情感分析 1. 朴素贝叶…

对象进阶-继承、原型-原型链

工厂方法创建对象 我们之前已经学习了如何创建一个对象&#xff0c;那我们要是想要创建多个对象又该怎么办&#xff1f;聪明的同学可能会说&#xff0c;直接在写几个对象不就好了吗&#xff1f;比如下边的代码&#xff1a; var person1 {name: "孙悟空",age: 18,s…

APP自动化测试,Appium+PO模式+Pytest框架实战—项目案例

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 PO模式&#xff1…