nlp中的多任务学习手段小结
- 2021 年 4 月 9 日
- AI
之前看的多任务学习太泛了,其实我主要只是想了解一下nlp里可以有哪些多任务的手段能够提高pretrained model的效果。。。
综述什么的就暂时不介绍了。。过两天重新写一篇,之前写的太乱了我自己看了都没法用,无语。
不过总的来说,就应用层面来看,划分为三个方向是比较容易让人理解和接受并且容易找到解决问题的思路和方向:
1、为多任务学习开发更好的网络架构,而不仅仅局限于常见的hard share或者soft share上,这类工作往往集中在开发更好的多任务学习的网络结构的设计上;
网络结构的魔改方面主要集中在找到更好的 任务层次结构上,简单来说就是做低层监督,然后将低层监督得到的representation用做上层网络结构训练的素材。


一个典型的工作是:HMTL a Hierarchical Multi-Task Learning model
HMTL for NLP//github.com/huggingface/hmtl
这个相对于后面要介绍的第三个方向也不多
2、多目标优化,多目标优化本身涉及到的领域是非常广泛的,多任务学习是多目标优化可以发挥作用的一个应用方向;比较少看到关于loss的一些multi object optimization的风骚的loss处理,当然这个其实是可以做的没什么问题,只不过目前nlp里的玩法重点暂时不在于此(个人浅薄,暂时没有找到太多关于multi object optimization应用于nlp的比较出名的工作),
3、更好的辅助任务,这一点在nlp中特别的明显,mlm+nsp,mlm+sop,mlm+rtd等等,都是为了能够通过多个任务的协同训练来得到更好的represent从而满足下游的各种需求。一个典型的代表就是MTDNN了:
本文主要讨论的是第三种情况
关于第一点,更好的网络结构,这个目前用的比较少,因为目前我主要研究的nlp方向中,做复杂的多任务交互模型构建的需求很少,所以暂时不会太深入研究;第二点多目标优化,在另一篇文章里已经做了比较深入的总结了(还没写完),简单来说,多目标优化应用到nlp中的多任务学习上,就是要回答nn中的多loss如何权衡的问题。这个方向的工程压力整体是最小的,因为几乎不需要改动多少核心代码,仅仅是数据构建和loss设计上需要做一些自定义,说到这里,理一下transformer-based的两个可以做mtl of nlp的library
1、huggingface transformers;
huggingface本身的api设计都是针对于单任务的,目前官方正式的api没有包含mtl of nlp的部分,不过这里官方提供了一个很好的demo,从demo上可以看到,通过继承和重写可以很方便地扩展huggingface 的功能(推荐多看看源码,设计还是很不错的)
2、MTDNN
另外就是MTDNN已经实现了一个基于torch和transformer开发的nlp多任务学习框架,代码上来看,设计思路大概是 以XXXmodel,例如bertmodel,xlnetmodel这类不带任务头的模型为hard share的backbone,然后下游的任务头可以定制多个,这实际上是实现了第三种也就是不同辅助任务的设计,下游任务可以是mlm,qa等。(MTDNN=multi task dnn),暂时还没有找到自定义多目标优化的loss设计的接口,不过肯定有吧。。。
2、allennlp;
//medium.com/huggingface/beating-the-state-of-the-art-in-nlp-with-hmtl-b4e1d5c3faf
更接近原生torch的语法,灵活度更高
3、pytorch lightning;(半自动封装,更更接近torch语法)
5、pytorch(我就是torch);
灵活性从上到下依次递增,开发能力从上到下依次递减。
辅助任务的设计(这里用辅助任务的说法感觉有一些不太准确,实际上mlm+sop这类的没有那么主任务和辅助任务之说,相对于下游实际对标的qa、文本匹配这类的任务,他们都是辅助任务):
目前做的最多的工作的方向也是比较多热门论文的方向主要在于辅助任务的设计上,多目标优化从loss层面入手,任务层次结构从网络结构层面入手,辅助任务则是直接思考任务之间的关系,希望寻找到最相关的多个任务来进行多任务学习。单纯从结合上来看,辅助任务+多目标优化的结合是比较自然的。
在这部分上,前人已经总结的挺多的了:

可以看到,大部分的工作还是集中在无监督不带标签的相关任务的设计上,毕竟大部分语料要去打标还是非常费劲的,现在解决问题的范式基本上是:pretrain+finetune独立,或者是下游在自己的语料上先pretrain一下再针对实际应用任务finetune,当然,我个人觉得下游部分也可以在自己的语料上pretrain+finetune多任务学习,一步到位。
总的来说,从个人应用的层面来看,任务的设计是比较复杂的,在现有任务的基础上做搭配是比较简单的,比如pretrain的时候可以灵活组合mlm+不同的nlp中的对比学习式任务(目前比较火,sop,nsp都算是对比学习中的context-instance 类型的,主要考虑把空间和顺序关系拿来做任务用)
参考自:
//ruder.io/multi-task/index.html