预训练模型BERT是NLP领域如今最大的网红,BERT的预训练过程学习了大量的自然语言中词、句法以及常识等泛领域的知识。因此,在运用BERT到实际的NLP任务中,通常的做法都是基于特定领域内的少量数据(几千到几万)集,再进行Finetune,以适用于当前的任务和领域。
通常来说,基于BERT进行Finetune效果都会还不错。但是如果你的数据集相对小的时候,你有可能会遇到一些麻烦。本篇基于论文《Revisiting Few-sample BERT Fine-tuning》深入看一下BERT的预训练过程,试着深入分析这一过程,用于指导Finetune的工作。
作者&编辑 | 小Dream哥
1 BERT及其预训练
BERT是一个基于transformer encoder的大型双向模型,基于海量的文本进行预训练,训练的任务包括MLM和NSP。
笔者前面有详细介绍BERT的文章,忘记的同学可以先点击了解:
在论文《Revisiting Few-sample BERT Fine-tuning》中,论文作者细致的发现了BERT在预训练时,在更新参数时做了一些"小动作",如下图:
BERT在预训练时,省略了标准Adam优化器优化过程中的第9和第10步。步骤9和步骤10分别是对步骤7和步骤8中一阶动量和二阶动量的有偏估计的纠正(bias-corrected)。关于为什么步骤7和步骤8中的一阶动量和二阶动量为什么是有偏的,感兴趣的读者可以翻看原文去了解,这里不做繁琐的推演了。
需要说明的是,为什么BERT在预训练时要省略和可以省略这两部呢?笔者猜测,google省略优化步骤主要原因应该是为了提速,毕竟预训练过程的数据量如此之大,BERT又是如此的庞大。那么为什么能做这样的省略呢,笔者猜测,是因为BERT在预训练是用的训练数据集非常之大,数据集的分布已经非常接近于实际的样本分布,因此可以省略上述步骤。
2 BERT的小样本Finetune
如我们上一节讨论的,BERT的预训练过程用的Adam优化器是非标的,可以称为BERT_Adam。然后论文作者发现,如今产业界和学术界大部分的开源BERT库的Adam优化器都是基于这个版本。
作者认为,BERT_Adam会造成Finetune时的不稳定(insstability)。
论文作者做实验发现,在小样本Finetune时,将BERT_Adam换成Adam确实会有更好的效果。笔者用自己的2000左右的数据集,做分类任务,确实也复现到了同样的现象。至此,我们发现了BERT在预训练时一个不小的坑,在小样本Finetune时,需要换回标准Adam优化器,因为小样本需要对一阶动量和二阶动量做bias-correction。
笔者看了下tensorflow和keras的Adam优化器实现,确实是BERT_Adam的实现:
所以,坑我们已经找到了,后续大家在bert Finetune时,最好能够自己重写一下Adam优化器,将其规范为标准的Adam优化器,或者直接用一些标准的开源库。
总结
基于BERT的预训练权重进行Finetune,是NLP领域目前最流行和高效的手段。本文介绍了预训练过程中会出现的一个大坑,即大部分开源的Adam优化器都是非标准的,并介绍了解决的方案。