BERT微调效果不佳?不如试试这种大规模预训练模型新范式
BERT模型自发布至今已整整两年了,但是其余热仍未消减。从一经问世的轰动,简单应用/微调便可达到某个领域或者任务的SOTA效果;到如今的各种『被吊打』,BERT巨人肩膀上的新宠大致可以分为以下这么几类:
Bigger:更大更多的训练数据与参数,效果更佳,暴力美学。例如RoBERT,Turing NLG等; Smaller:追求更快的速度,更少的内存,简单之美。例如TinyBERT,ALBERT等; Smarter:结合更多更丰富的外部知识,集大成者。例如ERNIE,K-BERT等; Tricker:优化模型结构、预训练任务,鬼斧神工。例如XLNet,Performer等 Cross Domain:更全能全面的解决方案,跨界出圈。例如LXMERT,ViT等 Analyzer:对模型底层设计/原理/效果/可解释性等方面的探究
纵观目前为止的大多数预训练模型,一般都是沿用『Pretraining + Finetuning』两个阶段的模式。第一阶段,通过大量的训练数据(一般是无监督样本)与模型参数,从文本中学习到通用的知识;第二阶段,针对下游特定领域以及任务,利用已有的有监督数据,对上一步的通用模型进行微调,获得领域/任务适应的模型会达到更好的效果。
更好的效果?其实并不一定,实际在应用上述两个阶段的过程中,会遇到许多问题。比如,直接使用预训练BERT太泛化,无法精确学习特定任务的知识,而微调又缺乏足够的有监督数据。这时候就需要想别的方案了:
第一种,标微调有监督数据(有钱就请众包,没钱就......) 第二种,把领域/任务相关的无监督数据加入第一阶段预训练,但这样就和初衷有些矛盾了,到底是该学通用的模型呢?还是学领域专注的模型呢? 第三种,稍微调整一下两阶段应用的方式,变成三个阶段。第一阶段仍然是大规模的预训练(pre-trianing),获得一个general model;第二阶段变成特定领域/任务的预训练(post-training),在general model的基础上,利用领域数据再做一次同样的训练;第三阶段,利用少量的有监督数据Finetune。
就上述三种方案来说,第三种无疑是最合理的。目前也有不少这样的研究,下面来看两篇论文~
Do not stop pretraing
这篇ACL2020的论文更像是一份实验报告,探究了我们上面提及的第三种方案的可行性,即将预训练的模型「重新预训练」至目标任务的领域是否有效果提升。重点研究了两块:domain-adaptive pretraining和task-adaptive pretraining,实验在四个领域(生物、CS、新闻、评论)的八个分类任务上发现均能提高性能。
论文:Don't Stop Pretraining: Adapt Language Models to Domains and Tasks 地址:https://arxiv.org/abs/2004.10964 源码:https://github.com/allenai/dont-stop-pretraining
下面来具体看看
Domain-Adaptive PreTraining
Domain-Adaptive PreTraining(DAPT)是指在第一阶段通用预训练模型的基础上,利用领域内未标注文本继续训练。
为了刻画个领域的相似度,对所有领域的 top 10K个高频词(去停用词)做了重合比对分析,如下。这可以预期将ROBERTA适应不同领域的受益程度,与ROBERTA的领域越不相似,DAPT的潜力就越高。
实验结果如下,可以看到,所有领域的DAPT对原始模型均有提升,而且非常明显!
Task-Adaptive PreTraining
Task-Adaptive PreTraining(TAPT)是指在第一阶段通用预训练模型的基础上,利用任务相关未标注文本继续训练。相比于DAPT,TAPT的数据集相对更小。
从上述实验可以看出,DAPT和TAPT相较于原始RoBERTA都有提升,而且两者共同使用效果更佳。这说明文章开篇所提的第三种方案是可行的,针对特定领域的语料继续对预训练模型进行训练可以带来明显的好处。
Train No Evil
来自清华刘知远老师组的EMNLP2020工作,同样探究了目前NLP预训练模型的新范式。
论文:Train No Evil: Selective Masking for Task-Guided Pre-Training 地址:https://arxiv.org/abs/2004.09733 源码:https://github.com/thunlp/SelectiveMasking
整体思路与'Do not stop pretraing'论文相同,不同的是,这里非常丝滑地利用「Selective Masking」将DAPT和TAPT结合在了一起。
同样是三阶段:
「通用预训练(GenePT)」:即传统的第一阶段,大规模无监督通用泛化数据 + 随机MASK预训练,数据集 大约包括「1000M」单词 「任务主导预训练(TaskPT)」:这一阶段的目的是加入任务和领域相关信息,使用mid-scale 领域相关的无监督数据,数据集 大约包含「10M」词 「微调阶段(Fine-tuneing)」:don't say so much,数据集 大约包含「10K」 词
任务主导预训练(TaskPT)
其实需要看看的就是上面的第二阶段,如何加入任务以及领域信息。前面提及,领域信息可以通过数据集来引入,那么任务相关信息呢?
其实,在文本中,「不同的词对不同任务的贡献是不一样的」,而这些词通常不同。举个栗子,『like』、『hate』之类的词对情感分类任务比较关键,而在关系抽取任务中,谓语和动词相对而言会更重要。于是,在预训练的随机MASK那一步,我们就可以选择mask这些任务相关的词(Selective Masking),使得模型学习到任务信息。
那下一步就是如何去找到这些「任务关键词」了。这里可能有点绕,我们下面通过QA问答的形式来梳理一下
1、如何判断哪些词是更重要的?
假设一个序列 个词组成, ,词的重要度用 表示。设计一个辅助序列 , 每次按顺序扔进一个词,比如当前是 第 步, 此时辅助序列为 ,那么当前词 的打分便可以通过下式计算,
其中, 表示任务t的标签, 表示给定原始序列能得出正确标签的置信度。 表示给定包含在内的部分序列能得出正确标签的置信度,这一项越大表明 越重要。所以 越小表明 越重要,即加上 后的辅助序列与原始序列对任务的贡献越相近。
2、置信度 如何的得到?
利用在特定任务上微调后的BERT模型产出置信度
3、 如何给无监督的领域数据标记任务关键词?
可以看到,上面两步获取重要度词是需要标记数据的,那么 是无监督的,怎么办呢?这时候可以利用上述方法在 数据集上标注一票数据,标签为词语是否为任务关键;然后用这一票标注数据去训练一个模型 ,学习任务关键词语的信息,最后用这个模型 在 数据集 上标注并 MASK 任务关键词。这样处理完的 就可以用于 『任务主导预训练(TaskPT)』了。
实验
Sem14-Rest 和 MR 表示两个任务,Yelp和 Amazon表示两个领域数据集。可以看到,在四组实验中,额外进行再一次预训练均会提升模型效果,且对比了 『Random Mask』与『Selective Mask』,发现『Selective Mask』效果更好。关于更详细的实验说明,大家可以转到原论文观摩~
尾巴
感谢英雄联盟的「辣鸡更新」,以及肥猫主子的「不踩键盘」,让我有空整理下笔记