多任务学习-以天池比赛为例的三种思路
几个月前曾关注过天池的多任务学习比赛:NLP中文预训练模型泛化能力挑战赛,本来应该代码写完就应该写这篇总结,不过拖延症患者总是无法按时完成计划!
题目简介
题目是希望选手能够通过算法实现泛化能力更强的中文预训练语言模型,来提高下游业务的准确性,为了评测模型的泛化能力,题目给出了三个不同的任务及对应的数据。
- OCNLI:是第一个非翻译的、使用原生汉语的大型中文自然语言推理数据集;
- OCEMOTION:是包含7个分类的细粒度情感性分析数据集;
- TNEWS:来源于今日头条的新闻版块,共包含15个类别的新闻;简单来说就是需要用一个模型,来实现多个
此外,最重要的一点,题目要求”单模型”,即一个任务只能有一个预测函数,所有任务只能使用同一个bert,在计算图中只能有一个bert来完成任务,不能集成多个模型进行预测;
在验证泛化能力时强加这个要求是否合理这里不做讨论,不过可以看出,题目是一个多任务学习的题目,不过又与平时常见的多任务学习不太一样:通常的多任务学习是在同一个样本上,同时进行多个目标的优化,如Bert中的MLM和NSP,而此次题目却是在多个样本上进行多个任务的学习,不同的任务间并不共享数据。
baseline
实现多任务学习最简单的方式就是共享backbone,然后对不同的任务拼接不同的分类器。参考BERT的训练过程,即在transformer last layer后面接task 相关的分类层即可。不过由于不同样本对应不同的任务,此时我们需要针对每个样本指定对应的分类层。由于笔者只会写keras,而由于tf这种静态图,对每个样本进行switch 不同的层不是很方便,所以实现的时候对每个样本都拼接了三个分类层,然后对loss 进行mask,来屏蔽掉非任务部分。
具体的实现细节还是看代码,代码:multi-task-baseline
样本区分
上面的baseline 是通过拼接不同的分类层来完成多任务学习,本质上是希望模型能对不同对任务进行区分,鉴于预训练语言模型的强大,我们还可以在样本上进行区分,让模型”感知”到任务的不同。而样本上进行区分,最简单的方式就是增加一个”任务说明”了。对GPT这种单向语言模型,可以在样本最前面加一个任务相关的字段,如”文本多分类”/“情感分析”,然后将所有任务都转成生成任务。而对bert这种掩码语言模型,也是类似的,即借鉴PET的思路,将所有任务都转成分类任务,并通过不同的pattern 来区分不同的任务,pattern的结果来区分对应的任务的结果。而pet的思路已经写过很多次了,如之前PET-文本分类的又一个秒解。
不管是GPT还是BERT下,本质都是一样的:借鉴语言模型的生成能力,转化任务类型,对样本增加固定pattern来区分任务类型,最终通过训练语言模型来完成任务。
软区分
上面样本区分提到将任务转化为语言模型,那更进一步的想,在语言模型(seq2seq)下,多任务学习是如何做的呢?笔者认为,在语言模型下可以将多任务学习类比为有条件的文本生成任务,而不同的任务类型对应着不同的条件,由此就可以借鉴条件本文生成的做法来做多任务了。
条件文本生成的做法,笔者了解不多,所以这里直接借鉴苏神基于Conditional Layer Normalization的条件文本生成里提到的做法,即把条件融合到Layer Normalization的$β$和$γ$中去。对不同的条件,来调节所有的LayerNormalization层的平移缩放参数,来进行”软区分”。
而条件,则可以通过任务类型进行embedding后来表达。对应的实验代码multi-task-adapt
实验结果
上面的三个思路中,笔者没有样本区分的思路进行实验,原因是实在想不到三个长度相同的pattern,所以就没写实验~而另外两个思路,从结果上看效果差别不大,甚至baseline 比软区分还有更优一点点,我想原因可能在于三个不同任务的数据量不同,或三个任务的数据量都偏少,导致conditional学习的不充分,理论上至少应该学到与未加conditional效果持平,即此时conditional无效。具体调优就留给感兴趣的读者了。
总结
以上就是笔者三个月前针对天池比赛对多任务学习进行的一些思考与总结,不过时间间隔有些久了,难免有些东西忘了或者记错了,如有发现还望提出。
PS:拖延症该管管了!!