点击上方,选择星标,每天给你送干货!


作者 | 许明

整理 | NewBeeNLP

随着Transformer 在NLP中的表现,Bert已经成为主流模型,然而大家在下游任务中使用时,是不是也会发现模型的性能时好时坏,甚至相同参数切换一下随机种子结果都不一样,又或者自己不管如何调,模型总达不到想象中的那么好,那如何才能让Bert在下游任务中表现更好更稳呢?本文以文本分类为例,介绍几种能帮你提高下游任务性能的方法。

Further Pre-training

最稳定也是最常用的提升下游任务性能的手段就是继续进行预训练了。继续预训练目前有以下几种模式。

二阶段

首先回顾一下,Bert 是如何使用的呢?

我们假设通用泛化语料为







,下游任务相关的数据为







, Bert 即在通用语料







上训练一个通用的Language Model, 然后利用这个模型学到的通用知识来做下游任务,也就是在下游任务上做fine-tune,这就是二阶段模式

大多数情况下我们也都是这么使用的:下载一个预训练模型,然后在自己的数据上直接fine-tune。

三阶段

在论文Universal Language Model Fine-tuning for Text Classification[1]中,作者提出了一个通用的范式ULMFiT:

  1. 在大量的通用语料上训练一个LM(Pretrain);

  2. 在任务相关的小数据上继续训练LM(Domain transfer);

  3. 在任务相关的小数据上做具体任务(Fine-tune)。

那我们在使用Bert 时能不能也按这种范式,进行三阶段的fine-tune 从而提高性能呢?答案是:能!

比如邱锡鹏老师的论文How to Fine-Tune BERT for Text Classification?[2]和Don't Stop Pretraining: Adapt Language Models to Domains and Tasks[3]中就验证了,在任务数据







继续进行pretraining 任务,可以提高模型的性能。

那如果我们除了任务数据没有别的数据时,怎么办呢?简单,任务数据肯定是相同领域的,此时直接将任务数据看作相同领域数据即可。所以,在进行下游任务之前,不妨先在任务数据上继续进行pre-training 任务继续训练LM ,之后再此基础上进行fine-tune。

四阶段

我们在实际工作上,任务相关的label data 较难获得,而unlabeled data 却非常多,那如何合理利用这部分数据,是不是也能提高模型在下游的性能呢?答案是:也能!

  1. 在大量通用语料上训练一个LM(Pretrain);

  2. 在相同领域


















    上继续训练LM(Domain transfer);

  3. 在任务相关的小数据上继续训练LM(Task transfer);

  4. 在任务相关数据上做具体任务(Fine-tune)。

而且上述两篇论文中也给出了结论:先Domain transfer 再进行Task transfer 最后Fine-tune 性能是最好的。

如何further pre-training

how to mask

首先,在further pre-training时,我们应该如何进行mask 呢?不同的mask 方案是不是能起到更好的效果呢?

在Roberta 中提出,动态mask 方案比固定mask 方案效果更好。此外,在做Task transfer 时,由于数据通常较小,固定的mask 方案通常也容易过拟合,所以further pre-training 时,动态随机mask 方案通常比固定mask 效果更好。

而ERNIE 和 SpanBert 中都给出了结论,更有针对性的mask 方案可以提升下游任务的性能,那future pre-training 时是否有什么方案能更有针对性的mask 呢?

刘知远老师的论文Train No Evil: Selective Masking for Task-Guided Pre-Training[4]就提出了一种更有针对性的mask 方案Selective Mask,进行further pre-training 方案,该方案的整体思路是:









  1. 上训练一个下游任务模型











    ;

  2. 利用











    判断token 是否是下游任务中的重要token,具体计算公式为:, 其中




    为完整句子(序列),











    为一个初始化为空的buffer,每次将句子中的token 往buffer中添加,如果加入的token 对当前任务的表现与完整句子在当前任务的表现差距小于阈值,则认为该token 为重要token,并从buffer 中剔除;

  3. 利用上一步中得到的token label,训练一个二分类模型











    ,来判断句子中的token 是否为重要token;

  4. 利用











    ,在domain 数据上进行预测,根据预测结果进行mask ;

  5. 进行Domain transfer pre-training;

  6. 在下游任务进行Fine-tuning。

上述方案验证了更有针对性的mask 重要的token,下游任务中能得到不错的提升。综合下来,Selective Mask > Dynamic Mask > Static Mask

虽然selective mask 有提升,但是论文给出的思路太过繁琐了,本质上是判断token 在下游任务上的影响,所以这里给出一个笔者自己脑洞的一个方案:「通过











在unlabeled 的Domain data 上直接预测,然后通过不同token 下结果的熵的波动来确定token 对下游任务的影响」
。这个方案我没有做过实验,有兴趣的可以试试。

when to stop

在further pretraining 时,该何时停止呢?是否训练的越久下游任务就提升的越多呢?答案是否定的。在进行Task transfer 时,应该训练多少步,论文How to Fine-Tune BERT for Text Classification?[5]进行了实验,最后得出的结论是100k步左右,下游任务上提升是最高的,这也与我自己的实验基本吻合,训练过多就会过拟合,导致下游任务上提升小甚至降低。

此外,由于下游任务数据量的不同,进行多少步结果是最优的也许需要实验测试。这里给出一个更快捷稳妥的方案:借鉴PET本质上也是在训练MLM 任务,我们可以先利用利用PET做fine-tuning,然后将最优模型作为预训练后的模型来进行分类任务fine-tuning,这种方案我实验后的结论是与直接进行Task transfer性能提升上相差不大。不了解PET的可以查看我之前博文PET-文本分类的又一种妙解[6].

how to fine-tuning

不同的fine-tuning 方法也是影响下游任务性能的关键因素。

optimizer

关于优化方案上,Bert 的论文中建议使用与bert 预训练时一致的方案进行fine-tuning,即使用weighted decay修正后的Adam,并使用warmup策略 搭配线性衰减的学习率。不熟悉的同学可以查看我之前的博文optimizer of bert[7]

learning rate

不合适的learning rate可能会导致灾难性遗忘,通常learning rate 在






















之间,更大的learning rate可能就会发生灾难性遗忘,不利于优化。

此外,对transformer 逐层降低学习率也能降低发生灾难性遗忘的同时提升一些性能。

multi-task

Bert在预训练时,使用了两个task:NSP 和 MLM,那在下游任务中,增加一个辅助的任务是否能带来提升呢?答案是否定的。如我之前尝试过在分类任务的同时,增加一个相似性任务:让样本与label desc的得分高于样本与其他样本的得分,但是最终性能并没有得到提升。具体的实验过程请看博文模型增强之从label下手[8]

此外,论文How to Fine-Tune BERT for Text Classification?[9]也任务multi-task不能带来下游任务的提升。

which layer

Bert的结构上是一个12层的transformer,在做文本分类时,通常我们是直接使用最后一层的[CLS]来做fine-tuning,这样是最优的吗?有没有更好的方案?

论文How to Fine-Tune BERT for Text Classification?[10]中针对这个问题也做了实验,对比了不同的layer不同的抽取策略,最终结论是所有层拼接效果最好,但是与直接使用最后一层差距不大。

而论文Hate Speech Detection and Racial Bias Mitigation in Social Media based on BERT model[11]中,作者通过组合多种粒度的语义信息,即将12层的[CLS]拼接后,送人CNN,在Hate Speech Detection 中能带来8个点的提升!cnn.png)

所以在fine-tuning时,也可以想一想到底是哪种粒度的语义信息对任务更重要。

Self-Knowledge Distillation

self-knowledge distillation(自蒸馏)也是一种常用的提升下游任务的手段。做法是先在Task data上fine-tuning 一个模型,然后通过模型得到Task data 的soft labels,然后使用soft labels 代替hard label 进行fine-tuning。更多细节可以查看之前的博文Knowledge Distillation之知识迁移[12]

知识注入

通过注入外部知识到bert中也能提升Bert的性能,常用的方式主要有两种:

  1. 在bert embedding 层注入:通过将外部Embedding 与Bert token-embedding 拼接(相加)进行融合,然后进行transformer一起作用下游;

  2. 在transformer的最后一层,拼接外部embedding,然后一起作用下游。

如Enriching BERT with Knowledge Graph Embeddings for Document Classification[13]中,通过在 transformer的最后一层中拼接其他信息,提高模型的性能。

数据增强

NLP中数据增强主要有两种方式:一种是保持语义的数据增强,一种是可能破坏语义的局部扰动增强。

保持语义通常采用回译法,局部扰动的通常使用EDA,更多细节可以查看之前博文NLP中的数据增强[14]

说个正事哈

由于微信平台算法改版,公号内容将不再以时间排序展示,如果大家想第一时间看到我们的推送,强烈建议星标我们和给我们多点点【在看】。星标具体步骤为:

(1)点击页面最上方深度学习自然语言处理”,进入公众号主页。

(2)点击右上角的小点点,在弹出页面点击“设为星标”,就可以啦。

感谢支持,比心

投稿或交流学习,备注:昵称-学校(公司)-方向,进入DL&NLP交流群。

方向有很多:机器学习、深度学习,python,情感分析、意见挖掘、句法分析、机器翻译、人机对话、知识图谱、语音识别等。

记得备注呦

整理不易,还望给个在看!

【BERT】如何提升BERT在下游任务中的性能相关推荐

  1. 【NLP】如何提升BERT在下游任务中的性能

    作者 | 许明 整理 | NewBeeNLP公众号 随着Transformer 在NLP中的表现,Bert已经成为主流模型,然而大家在下游任务中使用时,是不是也会发现模型的性能时好时坏,甚至相同参数切 ...

  2. 如何提升BERT在下游任务中的性能

    作者 | 许明 转自 | NewBeeNLP公众号 随着Transformer 在NLP中的表现,Bert已经成为主流模型,然而大家在下游任务中使用时,是不是也会发现模型的性能时好时坏,甚至相同参数切 ...

  3. 预训练模型-从BERT原理到BERT调包和微调

    一.BERT原理 BERT取名来自 Bidirectional Encoder Representations from Transformers.架构为:预训练 + fine-tuning(对于特定 ...

  4. HuggingFace-transformers系列的介绍以及在下游任务中的使用

    这篇博客主要面向对Bert系列在Pytorch上应用感兴趣的同学,将涵盖的主要内容是:Bert系列有关的论文,Huggingface的实现,以及如何在不同下游任务中使用预训练模型. 看过这篇博客,你将 ...

  5. BERT模型—1.BERT模型架构

    文章目录 引言 一.Bert模型总览 二.注意力机制 1.Seq2seq中的注意力操作 2.注意力的一般形式(三步曲) 3. transformer中的自注意力机制-Self.Attention 4. ...

  6. 使用有序GUID:提升其在各数据库中作为主键时的性能

    原文出处:https://www.codeproject.com/articles/388157/guids-as-fast-primary-keys-under-multiple-database  ...

  7. .NET Core 3中的性能提升(译文)

    回顾我们准备推出.NET Core 2.0的时候,我写了一篇博文来介绍.NET已经引入的诸多性能优化中的一部分,我很喜欢把它们放在一起讲述,也收获了很多正面反馈,因此我又给.NET Core 2.1, ...

  8. Transformer课程 第7课Gavin大咖 BERT文本分类-BERT Fine-Tuning

    Transformer课程 第7课Gavin大咖 BERT文本分类-BERT Fine-Tuning Part III - BERT Fine-Tuning 4. Train Our Classifi ...

  9. c#中的vector_.NET Core 3 中的性能提升

    (给DotNet加星标,提升.Net技能) 转自:森林蝙蝠原文:devblogs.microsoft.com英文:zhuanlan.zhihu.com/p/66152703 回顾我们准备推出.NET ...

  10. 中国下游处理中的烘干机市场深度研究分析报告

    [报告篇幅]:94 [报告图表数]:147 [报告出版时间]:2021年1月 报告摘要 2019年中国下游处理中的烘干机市场规模达到了XX亿元,预计2026年可以达到XX亿元,未来几年年复合增长率(C ...

最新文章

  1. html5 筛子,html5摇骰子游戏
  2. Excel教程一:将Excel中一列转换成多行
  3. 举例 微积分 拉格朗日方程_变量数学时代——微积分的发明
  4. java库存审核表_JAVA库存案例
  5. Latex 图像、表格编号的字体问题
  6. JAVA-Servlet操纵方法
  7. 【图像重建】基于matlab GUI投影法图像重建【含Matlab源码 861期】
  8. 【转】VNode节点
  9. c语言char a什么意思,C语言中char *a[ ]什么意思,他和char (*)a[ ]有什么什么区别?...
  10. oracle删除lob对象,ORACLE LOB大对象处理
  11. Linux安装后的配置操作
  12. Mac系统开发常见问题-Mac登录界面多了一个其他账户选项
  13. 谁可以参与初创股权分配?
  14. asp.net58同城简单登陆
  15. 真兰仪表通过深交所注册:拟募资17.4亿 上半年净利下降27%
  16. 性能优化案例之:如何将TPS从60提升到2000?
  17. 腾讯敏捷之道,看我就够了
  18. unity实现吸附功能的效果
  19. [灵敏度]底噪的计算
  20. 视频号粉丝裂变2大玩法,实现粉丝狂飙式增长

热门文章

  1. SPI、I2C、I2S
  2. Python PIL 图像缩小、拼接
  3. HtmlCleaner CleanerProperties 参数配置(转自macken博客,链接:http://macken.iteye.com/blog/1579809)...
  4. iOS应用的真机调试
  5. 百度云推广~麻烦各位点一下吧
  6. ADO.Net之SqlConnection、 Sqlcommand的应用
  7. 20165222第三周作业
  8. java实现二叉树遍历
  9. CSS 内边距 和尺寸(收藏)
  10. linux 的常用命令---------第十二阶段(smb、FTP服务)