前言
欢迎大家来到预训练语言模型的专题系列分享,本篇推送是该专题系列的第三篇。在前两篇推送[萌芽时代],[风起云涌]中,我们分享了该领域的奠基文章以及声名鹊起却生不逢时的ELMo模型,本期我们带来的文章将会让大家了解文本分类的一些通用技巧,希望大家看完后炼丹技术都能更上一层楼!
同时感谢清华大学自然语言处理实验室整理的体系图,我们将沿此脉络前行,探索预训练语言模型的前沿技术,本期的第一篇文章处于图中绿色框内,另一篇为课外阅读。红色框内的论文在前几期中介绍,大家有兴趣的可以前去一看。
前几期介绍的大多是模型或结构,而这篇文章由 Jeremy Howard 和 Sebastian Ruder 发表于2018年,介绍的是文本分类中语言模型的通用训练技巧。其中的一些技巧,吴老师和我在kaggle 的jigsaw 文本分类比赛中也有应用,并在比赛中拿到了金牌。在未来的推送中,可能还会有详细介绍。
这篇文章认为,目前语言模型在finetune时经常会过拟合到小数据集上,而且容易导致灾难性遗忘。相比于CV模型,NLP模型层数较少,所以需要更多的训练技巧来使其表现更好。而他们在本文中提出了fine-tuning 语言模型的关键技术 ULMFiT,可以大大地提高六个文本分类任务的效果,并且用更少的数据训练就可以达到相当的效果,加强了泛化能力。
首先介绍下ULMFiT的总体框架。之前的很多论文提出的都是预训练 + finetune 两个阶段的训练,而本文提出使用三阶段训练。
文章认为上述第二个阶段很有必要。因为无论通用的语料多样性多么好,都和你目标任务的数据分布有区别。而且在比较小的特定任务数据上finetune语言模型可以很快得到收敛,成本较低。同时,这样finetune以后,即使对比较小的数据集,语言模型也能变得比较鲁棒。
ULMFiT的总体框架(来自论文)
其次,在ELMo,GPT的介绍中我们都提到过,语言模型的不同层其实能够捕捉不同级别的语义特征,比如ELMo底层LSTM更多捕捉语法和词层面的特征,而上层LSTM更多捕捉整句话的语言的特征。既然是不同类型的信息,就应该区分地去进行参数的finetune,所以文章提出了discriminative fine-tuning,即对不同的层使用不同的学习率去学习。因为越靠近最下层Embedding层,模型参数就会含有更多通用信息,不应随任务目标发生很大变化。所以为了降低灾难性遗忘的可能,越下层,就会用更小的学习率来学习,而上层为了让模型能够更快地学习到目标任务的独有信息,会用相对大的学习率。一般层之间的学习率会等比地变化,在这篇文章里,这个比值为2.6, 即上一层参数学习率为下一层的2.6倍。
再者,为了让语言模型能更好地学习到特定任务相关的特征,文章使用了Slanted triangular learning rates (SLTR),让模型在训练初期快速收敛到一个合适的参数区域,接着再进行细致地优化。在现在看来这就是一种warmup策略。warmup已经在神经网络模型中被广泛应用了,huggingface的transformers也有现成的函数来对warmupscheduler进行控制。
SLTR示意图(来自论文)
最后,在目标任务的直接优化过程中,文章提出了几种辅助训练技巧,其中这些我认为比较简单通用。
文章接下来的篇幅从各方面比较了文中技巧对任务的提升,我们可以大致看一下。其中,full 是指优化整个模型,last指只优化最后一层,discr指discriminative fine-tuning, sltr指slanted triangular learning rates,cos指cosine annealing schedule。可以看到,文中提到的几个技术都对误差率的下降有明显的效果。
不同策略下验证错误率(来自论文)
这篇文章的贡献是深远的,它提出了预训练语言模型比较通用的训练方法和技术。这篇文章虽然早于GPT和BERT发表,但是它的框架完全可以在后来的强大模型中提供帮助,让我们NLP的炼丹之旅轻松又愉快!
本篇文章是由复旦计算机系的多位作者发表的。讨论如何在文本分类任务中对BERT模型进行finetune。虽然这篇文章不在体系图,但与第一篇文章在内容上比较相关,而且我们在kaggle比赛中也应用到了,所以一起在这里介绍。我们长话短说,直接来总结一下这篇文章的几个贡献点和有用的技巧。
第一个贡献是,框架相比于上篇文章进行了微调。在通过任务相关数据进行语言模型finetune后,多加了一步可选的stage: 把BERT在领域内相关的其他任务上进行多任务的训练,我认为这是对于ULMFiT的补充。
BERT finetune框架(来自论文)
第二个贡献是对长文本的处理,我们在之后BERT文章中将会介绍,BERT模型能一次处理的最长文本长度为512,有时我们为了降低模型运行时间和占用空间,有可能将这个长度变得更短,这时候就可能要对文本进行截断。文章的结论就是最好的截断方式既不是截头,也不是截尾,应该头尾都截一部分保留最重要信息。
长文本不同处理方式的错误率(来自论文)
第三个贡献是在任务上详细分析了BERT的不同层对文本分类任务的效果。具体做法是,在某一层后直接接分类器进行分类。单层中,以最后一层的效果最好,因为文本分类是更贴近语言层面的任务。而在文章尝试的其他几种选择中,把最后四层concat或者max pooling效果最好。
不同层向量用以分类的错误率(来自论文)
第四个贡献其实是借鉴discriminative fine-tuning,进行层间学习率的下降。越接近底层,含有的通用信息越多,越不应该随着特定任务进行大规模的参数改变,否则有灾难性遗忘风险。在他们的尝试中,学习率2e-5,层间学习率变化因数0.95对BERT来说比较合适的。
不同学习率设置的分类错误率(来自论文)
总之,这篇文章进行了很多完备的实验,来提出和验证了在文本分类任务上,BERT的较好的finetune策略及其效果。文章验证了 : 1) 对于文本分类,BERT的最高层的效果最好 2) 使用合适的层间学习率下降策略,BERT能够克服灾难性遗忘的问题 3) 任务相关或领域内相关数据的语言模型finetune可以大大提升效果 4) 相关的多任务学习也对特定任务有提升效果 5) BERT只需少量的特定数据就可以预训练以提升任务。文章对我们训练BERT模型有很好的指导意义,以后再也不用担心炸炉啦!