文章目录

  • 引言
  • 一、预训练语言模型
    • 1.为什么要进行预训练?
    • 2. BERT预训练-掩码预测任务
    • 3.BERT预训练-下句预测任务
  • 二、BERT的文本处理—subword tokenizer
    • 1. 为什么要学习subword tokenizer?
    • 2. 词表生成与分词
  • 三、BERT embedding
  • 四、BERT微调—句子分类任务
  • 五、BERT微调—序列标注任务
  • 六、BERT微调—关系分类任务
  • 七、BERT微调—样本不均衡问题Focal loss

引言

  本节将按照思维导图逐步了解BERT语言模型(基于transformer的网络结构)。

  BERT带来了新的NLP范式。

一、预训练语言模型

  大规模的预训练语言模型的模型参数量呈几何倍数的增长趋势。下面我们了解BERT预训练的原理。

1.为什么要进行预训练?

  基于词向量为基础的模型并不是在BERT中首次出现。在Word2vec中,词向量表示是有局限性的。这是因为词向量表达固定,无法表达上下文。2017年之前,NLP模型的普遍形态为词向量+encoder

利用LSTM或者Transformer模型通过训练集来学习如何提取上下文信息,最终输出分类标签。这里的训练集指的是具有分类或者NER的标注信息。这种模式有如下缺陷:

  • Encoder部分随机初始化,没有经过预训练,对优化器压力大;
  • 数据集要足够好,足够大,encoder才能学会如何提取上下文信息

这两个缺陷导致2017年以前的模型非常具有局限性。
  基于上述的缺陷,我们现在想要有效的预训练embedding+编码器。有标签的文本数据获取成本大,相比来说,获取大量无标签的文本数据代价很小。所以如何进行预训练呢?这就涉及到在大量无标签的文本上进行自监督学习(self-supervised training)。

2. BERT预训练-掩码预测任务

  掩码预测任务与Word2vec中CBOW非常神似,但略有不同。

  • 一方面,CBOW语言模型输入的是一个时间窗口,并不一定是一个句子;掩码预测任务输入的是一个句子(sentence)
  • 另一方面,CBOW当中被预测的词是不做输入的;但掩码预测任务会遮掩某个词(用”[MASK]"字符替换原词)然后用于输入
  • CBOW中是一句话预测一个词,掩码预测任务一句话可以遮掩多个字

  掩码预测任务中,输入是句子当中遮掩掉几个词(用”[MASK]"字符替换原词),经过BERT网络输出每个字的向量表征。在遮掩的这个字的位置上要经过一个线性层来预测这个位置是哪个字的概率。掩码预测任务存在的问题:在下游任务中,eg:预测一个句子的情感是不会有[Mask]的。因此,在实现掩码任务时,需要遮掩的字只占语料全体的字数的一小部分(15%);在这15%里面:

  • 一部分(80%)被遮掩,也就是替换为[MASK];
  • 一部分(10%)随机替换为其他词(仍然需要预测此处的token应该是什么);
  • —部分(10%)保留原词(仍然需要预测此处的token);

这样做的目的是使得模型能够区分这个词放在这里是否合理,使得模型具有判断这句话是否合理的能力,加深了模型对语言的理解。BERT模型在经过预训练之后天生就能够做一些下游任务,比如:纠错任务。

3.BERT预训练-下句预测任务

  下句预测指的是:判断句子B是否是句子A的下文。此时,BERT句子的输入会是[CLS] A sent [SEP] B sent [SEP]格式

  我们经常通过句首的第一个token来表示句子整体的语义关系,在上下句预测的任务当中,上下句的关系是保存在输入的[CLS]符号的当中,在预测时使用BertPooler提取整个输入序列的表征:

这里要注意:不是直接拿[CLS]的向量表征;而是要经过BertPooler这个模块,其中包含MLP,tanh操作得到一个向量表示,再输入到2分类层,BertPooler也是参与预训练的,预训练会更新整个bert的模型参数,微调时候其实是可以更新部分参数,后面会有介绍。

用了 Masked LM 和 Next Sentence Prediction 两种方法分别捕捉词语和句子级别的 representation

二、BERT的文本处理—subword tokenizer

1. 为什么要学习subword tokenizer?

  subword tokenizer就是将长的复杂的单词分成成短的简单的单词,eg:句子” play the song little robin redbreast”在输入模型时变为”[CLS] play the song red ##bre ##ast [SEP]”。Tokenizer是预训练时候用了哪个,后面微调就要用哪个。使用subword tokenizer的原因是:

  • 传统词表示方法:是先对各个句子进行分词,然后再统计并选出频数最高的前N个词组成词表·词表一般较大,一是尾部词训练不充分,二是显存占用较大
  • 传统词表示方法无法很好的处理未知或罕见的词汇(OOV问题)
  • 传统词tokenization方法不利于模型学习词缀之间的关系
    E.g.模型学到的“old”, “older”,and “oldest”之间的关系无法泛化到“smart”, “smarter”,and“smartest”。
  • Character embedding作为OOV的解决方法粒度太细,且推理时候显存开销较大:
    一个原本长度为12的句子,采用character embedding,则输入的大小变为12*16 (假设设置词字母长度最
    大为16)
  • Subword粒度在词与字符之间,能够较好的平衡OOV问题

常见的subword模型:Byte Pair Encoding (BPE), WordPiece

2. 词表生成与分词

  BPE算法生成词表过程如下:

  1. 准备一个语料库;确定期望的Subword词表大小;
  2. 将单词拆分为成最小单元。比如英文中26个字母加上各种符号,这些作为初始词表;
  3. 在语料上统计单词内相邻单元对的频数,选取频类最高的单元对合并成新的Subword单元;
  4. 重复第3步直到:达到第1步设定的Subword词表大小或下一轮迭代中token最高频数为1

假设现在语料库中有如下词汇(及其频率):

观察词汇表大小在每一步如何变化

  BPE算法编码:得到Subword词表后,针对每一个单词,我们可以采用如下的方式来进行编码:

  • 将词典中的所有子词按照长度由大到小进行排序;
  • 对于要进行分词的单词w,依次遍历排好序的词典。查看当前子词是否是该单词的子字符串(贪婪的最长匹配),如果是,则输出当前子词,并对剩余单词字符串继续匹配;
  • 如果遍历完字典后,仍不匹配,则将剩余字符串替换为特殊符号输出,如””;

  WordPiece算法生成词表的步骤与BPE类似;加上”##”前缀表示token不作为一个完整单词的开始部分。与BPE的最大区别在于,如何选择两个子词进行合并∶BPE选择频数最高的相邻子词合并,而WordPiece选择能够提升语言模型概率最大的相邻子词加入词表;

  • 假设句子S=(t1,t2,tn)S =(t_1, t_2,t_n)S=(t1,t2,tn)由n个子词组成,表示子词,且假设各个子词之间是独立存在的
  • 句子的语言模型似然值等价于所有子词概率的乘积:logP(S)=∑i=1nP(ti)logP(S)= \sum_{i=1}^nP(t_i)logP(S)=i=1nP(ti)
  • 假设把相邻位置的iiijjj两个子词进行合并,合并后产生的子词记为zzz,此时句子似然值的变化可表示为:
    logP(tz)−(logP(tx)+logP(ty))=logP(tz)P(tx)P(ty)logP(t_z)- (logP(t_x)+ logP(t_y)) =log\frac{P(t_z)}{P(t_x)P(t_y)}logP(tz)(logP(tx)+logP(ty))=logP(tx)P(ty)P(tz)
    很容易发现,似然值的变化就是两个子词之间的互信息。

简而言之,WordPiece每次选择合并的两个子词,他们具有最大的互信息值,也就是两子词在语言模型上具有较强的关联性,它们经常在语料中以相邻方式同时出现。
Wordpiece举例:

  • 英文:采用BERT-base-uncased tokenizer
    30522个单词;英文转化为小写
    eg:
    句子“play the song little robin redbreast”经过BERT的wordpiece tokenizer后变为”[‘play’, ‘the’, ‘song’, ‘little’, ‘robin’, ‘red’, ‘##bre’, '##ast ]”
  • 中文:采用Google Chinese BERT-base-uncased
    21128个单词;不区分大小写;
    中文汉字拆开(split_Chinese_character);
    eg:
    句子”我很喜欢一首歌: yesterday once more.”处理为['我,‘很’,‘喜’, ‘欢’,'一,'首, ‘歌’, ‘:’,‘yes’, ‘##ter’, ‘##day’, ‘on’, ‘##ce’, ‘more’, ‘.’]

三、BERT embedding

  BERT的嵌入层包含三种embedding

  • Token embedding
    对应着Subword词表分词后的每一个单词
  • Segmentation embedding
    将句子的上一句与下一句进行区分对待,涉及到预训练任务当中的下句预测
  • Position embedding
    位置编码,为了能够让模型反映句子的顺序信息,位置编码研究前沿如今是相对位置编码

四、BERT微调—句子分类任务

  句子分类任务就是把文本按照一定的规则分门别类,文本分类有以下应用场景:

  那么,在下游任务中,如何进行BERT句子分类任务的微调?不妨以单个句子分类为例(还有句子对分类,判定句子对是否同义),比如,我们现在想要对“想看黑寡妇”进行情感分类,首先将“想看黑寡妇”转换成BERT模型的输入形式,在句前加[CLS]符号,句尾加[SEP]符号,使用subword tokenizer进行分词,将这样处理好的文本输入到BERT模型中,得到句子的向量表征(句子中的每个字均有向量表征),通过BertPooler模块,取[CLS]的向量表征,经过MLP,tanh操作后得到一个整句的向量表征,再经过分类层得到分类结果。

由于NLP中句子是不定长的,所以可以通过Pooling层将变长的向量转换成特定的size。除了使用BertPooler模块,还可以增加一个Pooling操作,将句子表征转化成句子级别的向量。这里的Pooling操作指:

  • Max-Pooling
  • Average-Pooling
  • Attention-Pooling


  分类任务微调的损失函数:假设模型对分类任务的训练样本为(x,y)(x,y)(x,y),预测类别为ccc的概率为pcp_cpc,则损失函数为
CE(PC,X)=−I(y=c)∗log(pc)CE(P_C,X)=-I(y=c)*log(p_c)CE(PC,X)=I(y=c)log(pc)

有了损失函数就可以利用梯度的更新做网络的训练。
  分类任务微调的原理与一般的网络训练没有区别。微调时,如果不固定参数,所有层的参数会更新。你可以选择固定某些层的参数,比如:embedding层。

五、BERT微调—序列标注任务

  序列标注任务指的是对于待标注的一段序列x={x1,x2,...,xn}x=\{x_1, x_2,..., x_n\}x={x1x2...xn},我们需要给每个xix_ixi预测一个标签(tag)yi(tag)y_i(tag)yi,标签(tag)(tag)(tag)集合是T={t1,t2,...,tm}T=\{t_1,t_2,...,t_m\}T={t1,t2,...,tm}。在不同的序列标注任务中对应的标签不一样。

  • 中文分词任务
    定义的标签(tag)(tag)(tag)集合是{BeginMiddleEndSingle}\{Begin \ Middle\ End\ Single\}{BeginMiddleEndSingle}
    eg:“风险基因协同的神经生物学作用”被分词为
    风险 基因 协同 的 神经 生物学 作用,转化为序列标注任务为:风/B险/E基/B因/E协/B同/E的/s神/B经/E生/B物/M学/E作/B用/E。
  • 命名实体识别:标出句子中的实体;使用BIO标注模式;
    定义的标签(tag)(tag)(tag)集合是实体类型包括{PER,ORG}\{PER,ORG\}{PER,ORG}
    eg:乔/B-PER布/I-PER斯/I-PER 就/O职/O于/O苹/B-ORG 果/I-ORG 公/I-ORG司/I-ORG
  • 词性标注(Part-of-speech, POS tagging):标注出词语的词性;使用BIO标注模式
      BERT序列标注任务微调方法有两种:
  • 方法一:每个token的向量表示经过线性层+softmax
    具体过程为:将BERT模型格式将句子输入到BERT模型当中,然后给出每个词的向量表征,经过线性层+softmax,然后给出每个词的NER标签
  • 方法二:BERT+CRF层
    在BERT模型还没有出现以前,解决这个问题的通用方式是’BiLSTM-CRF’模型。CRF层通过学习标签之间转移的模式来规避’B-PER,I-ORG’这样的问题;

六、BERT微调—关系分类任务

  关系分类任务就是从非结构化文本中抽取出结构化知识;具体为:区分出头实体与尾实体之间的语义关系,比如:

  关系分类任务最直接的应用是构建知识图谱。

  BERT关系分类任务微调方法有三种:

  • 方法一:将句子输入到BERT模型中,然后分别拿到头实体与尾实体的向量表征(实体多个词的表征经过pooling得到),然后将头尾实体向量拼接,再经过线性层分类
  • 方法二:BERT的embedding层中加入关系位置编码。在方法一的基础上加上关系位置编码,告诉BERT模型何处为头实体何处为尾实体。
  • 方法三:在句子中加入新定义的字符(unusedtoken),标识出头尾实体位置;

七、BERT微调—样本不均衡问题Focal loss

  在自然语言处理应用场景中,经常出现样本不均衡场景的问题,这是因为在自然语言的语料库中,一个单词出现的频率与它在频率表里的排名成反比,即频率越高的单词,出现的次数越多。碰到样本不均衡问题时,需要对训练方法做一定的改变。

  • 方法一:重采样
    假设CCC是数据集类别数,nnn是类别iii的样本数量,则从类别iii中采样一个样本的概率:
    instance-balanced sampling:每个样本被等概率的抽到,即
    pi=ni∑j=1Cnjp_i=\frac{n_i}{{\sum_{j=1}^Cn_j}}pi=j=1Cnjni
    Class balanced sampling:每个类别被抽到的概率都相等
    pi=1∑j=1C1p_i=\frac{1}{{\sum_{j=1}^C1}}pi=j=1C11
    一般重采样,假设q∈(0,1)q∈(0,1)q(0,1)
    niq∑j=1Cnjq\frac{n_i^q}{{\sum_{j=1}^Cn_j^q}}j=1Cnjqniq
  • 方法二:重加权(re_weighting):以二分类为例
    正常的交叉熵损失为:
    CE(PC,X)=−I(y=c)∗log(pc)CE(P_C,X)=-I(y=c)*log(p_c)CE(PC,X)=I(y=c)log(pc)
    通过增加一个系数(添加的系数与难度相关),来控制少数类别的样本对总loss的贡献
    CE(PC,X)=−α(c)∗I(y=c)∗log(pc)CE(P_C,X)=-\alpha(c)*I(y=c)*log(p_c)CE(PC,X)=α(c)I(y=c)log(pc)
    Focal loss:
    CE(PC,X)=−(1−pc)γI(y=c)∗log(pc)CE(P_C,X)=-(1-p_c)^{\gamma}I(y=c)*log(p_c)CE(PC,X)=(1pc)γI(y=c)log(pc)
    Focal loss+类别的重加权:
    CE(PC,X)=−α(c)(1−pc)γI(y=c)∗log(pc)CE(P_C,X)=-\alpha(c)(1-p_c)^{\gamma}I(y=c)*log(p_c)CE(PC,X)=α(c)(1pc)γI(y=c)log(pc)

如果对您有帮助,麻烦点赞关注,这真的对我很重要!!!如果需要互关,请评论或者私信!


BERT模型—2.BERT模型预训练与微调相关推荐

  1. Bert模型-自然语言处理中的预训练技术发展史

    为什么Bert最近很火? 其实Bert并没有重大的理论或者模型创新,创新并不算大.主要原因是效果太好了,刷新了很多NLP任务的最好性能,有些任务还被刷爆了.另外一点是Bert具备广泛的通用性,绝大部分 ...

  2. 有效扩展:来自预训练和微调变换器的见解、rct.ai训练出5亿参数的BERT-X模型

    预训练周刊 关于周刊 本期周刊,我们选择了14篇预训练相关的论文,涉及短语检索.网络结构.文本排序.架构扩展.对话选择.语言检测.模型微调.机器翻译.属性注入.阅读理解.蛋白序列学习.蛋白质预测.蛋白 ...

  3. 《预训练周刊》第26期:有效扩展:来自预训练和微调变换器的见解、rct.ai训练出5亿参数的BERT-X模型...

    No.26 智源社区 预训练组 预 训 练 研究 观点 资源 活动 关于周刊 本期周刊,我们选择了14篇预训练相关的论文,涉及短语检索.网络结构.文本排序.架构扩展.对话选择.语言检测.模型微调.机器 ...

  4. 天池零基础入门NLP竞赛实战:Task4-基于深度学习的文本分类3-基于Bert预训练和微调进行文本分类

    Task4-基于深度学习的文本分类3-基于Bert预训练和微调进行文本分类 因为天池这个比赛的数据集是脱敏的,无法利用其它已经预训练好的模型,所以需要针对这个数据集自己从头预训练一个模型. 我们利用H ...

  5. ChatGPT使用拓展资料:BERT 带你见证预训练和微调的奇迹

    ChatGPT 拓展资料:BERT 带你见证预训练和微调的奇迹 SQuAD数据集: {"version":

  6. Tensorflow【实战Google深度学习框架】预训练与微调含代码(看不懂你来打我)

    文章目录 1.前言 2.什么是预训练和微调 3.预训练和微调的作用 4.在一个新任务上微调一个预训练的模型代码实现 1.前言 预训练(pre-training/trained)和微调(fine tun ...

  7. 直播 | AAAI 2021:如何缓解GNN预训练和微调之间的优化误差?

    「AI Drive」是由 PaperWeekly 和 biendata 共同发起的学术直播间,旨在帮助更多的青年学者宣传其最新科研成果.我们一直认为,单向地输出知识并不是一个最好的方式,而有效地反馈和 ...

  8. NAACL 2022 | FACTPEGASUS:抽象摘要的真实性感知预训练和微调

    ©作者 | 董冠霆 单位 | 北京邮电大学 研究方向 | 自然语言理解 论文标题: FactPEGASUS: Factuality-Aware Pre-training and Fine-tuning ...

  9. 端到端语音翻译中预训练和微调的衔接方法

    ST:speech translation,语音翻译 ASR:automatic speech recognition,自动语音识别 MT:machine translation,机器翻译 TCEN: ...

  10. 超越谷歌BERT!依图推出预训练语言理解模型ConvBERT,入选NeurIPS 2020

    机器之心发布 机器之心编辑部 在本文中,本土独角兽依图科技提出了一个小而美的方案--ConvBERT,通过全新的注意力模块,仅用 1/10 的训练时间和 1/6 的参数就获得了跟 BERT 模型一样的 ...

最新文章

  1. 揭开Annotation的面纱
  2. 清理无用的CSS样式比较有用的几个工具
  3. Qt on Android:将Qt调试信息输出到logcat中
  4. XLT格式化XML那点事(C#代码中的问题解决)(二)
  5. x轴z轴代表的方向图片_游戏中到底是Z轴朝上还是Y轴朝上?
  6. 读书笔记--互联网必读《长尾理论》作者克里斯.安德森
  7. 安装 Visual Studio 插件 Visual Assist - C语言零基础入门教程
  8. 漫步微积分十三——高阶导数
  9. SQLite多线程写锁文件解决方案
  10. 应用回归分析第五版电子书_应用回归分析 R语言版_何晓群著_2017年
  11. Windows C语言开发环境实践
  12. SpringBoot--定义全局日期响应格式
  13. python 从useragent中获取操作系统版本号以及浏览器的版本信息
  14. WiFi_数据速率计算公式
  15. 年长车友的单车游记:骑单车游崇明岛(转)
  16. 1466:Girls and Boys:优美的拆散早恋学生?
  17. mac - 让焦点迅速定位到分屏显示中
  18. tortoise冲突处理
  19. 备份谷歌或其他浏览器插件
  20. 暑期参加CSDN编程竞赛的些许心得体会

热门文章

  1. 公历转农历C语言课程设计,(只为学习)公历转农历代码以完成,请高手在此代码基础上写出个农历转公历的代码出来...
  2. 计算机老师教师节祝福语,送给老师教师节祝福语
  3. 【原创】2019.08.15 模拟赛 ※ [USACO19]Left Out / [USACO19]Cow Steeplechase II / bzoj 4972 小Q的方格纸
  4. VPS安装Docker、docker-compose
  5. Gallery模块管理系统相册,支持从相册中选择图片或视频文件、保存图片或视频文件到相册等功能。通过plus.gallery获取相册管理对象
  6. ftp服务器挂载到手机文件夹,ftp服务器挂载到本地
  7. 2021kali系列 -- 破解无线密码
  8. 优盘扩容修复 u盘工具
  9. Windows消息ID大全
  10. COLA 4.0应用架构在CSB集成平台的应用实践