首发于深度学习

多任务学习之非深度看起来头大的部分

之前看多标签的时候顺便了解了一下多任务最后居然又回到迁移学习上了:

常见概念的关系:


多任务学习和迁移学习的关系

首先是关于迁移学习和多任务学习的问题,有的地方把多任务学习当作迁移学习的一个分支,有的地方把迁移学习和多任务学习当作两个东西。这篇文献是把多任务学习当作迁移学习的分支,而《迁移学习》这本书里则将二者分开看待。

迁移学习目的在于从源域获取信息然后解决目标域的问题,关注目标域的任务性能;

多任务学习则直接对接多个目标域,关注最终的model在每一个目标域上的任务性能。从代码层面和应用方式层面来看,多任务学习和迁移学习中的一些分支基本没什么区别。所以这里我把多任务学习划为迁移学习的一种。

比如bert,nsp+mlm多任务学习,但是得到的pretrained model基本用来做模型迁移,或者也可以mlm+文本分类之类的任务一起学习也是没什么大问题的。

所以其实没啥太大区别,不用纠结太死。



多任务学习是一种提高模型泛化性能的手段

通过权衡主任务与辅助的相关任务中的训练信息来提升模型的泛化性与表现。从机器学习的视角来看,MTL可以看作一种inductive transfer(先验知识),通过提供inductive bias(某种对模型的先验假设)来提升模型效果。比如,使用L1正则,我们对模型的假设模型偏向于sparse solution(参数要少)(其实是引入了拉普拉斯先验)。在MTL中,这种先验是通过auxiliary task来提供,更灵活,告诉模型偏向一些其他任务,最终导致模型会泛化得更好。

from

多任务学习是 同时考虑多个相关任务的学习过程,目的是利用任务间的内在关系来提高 单个任务学习的泛化性能.

简单来说,就是一种可以提升泛化性能的手段,我发现在nlp里(cv和视频这些不太熟),提高泛化性能的手段相当的多:

1、L1,L2正则化,dropout,batchnorm,weight decay这类;

2、集成;

3、数据增强,nlpaugment,textattack这两个库都实现了相当多的文本数据增强的方法;

4、预训练迁移学习;

5、多任务学习;

6、对抗训练,fgm这类的;

7、对抗样本生成等;

8、基于图的一些数据增强工作

。。。。。

不用纠结太多,和样本相关的提高泛化性能的手段是最好的。泛化性能的好坏本质在数据的分布上,看现在nlp,cv的主流玩法,from pretrained model,finetune,这些实际上都是间接利用了大量的样本。

怎么辨别什么样的任务是多任务学习?看loss就行,多个loss的就是多任务学习。


多任务和单任务:

单任务学习:一次只学习一个任务(task),大部分的机器学习任务都属于单任务学习。

多任务学习:把多个相关(related)的任务放在一起学习,同时学习多个任务。

现在大多数机器学习任务都是单任务学习。对于复杂的问题,也可以分解为简单且相互独立的子问题来单独解决,然后再合并结果,得到最初复杂问题的结果。这样做看似合理,其实是不正确的,因为现实世界中很多问题不能分解为一个一个独立的子问题,即使可以分解,各个子问题之间也是相互关联的,通过一些共享因素或共享表示(share representation)联系在一起。把现实问题当做一个个独立的单任务处理,忽略了问题之间所富含的丰富的关联信息。多任务学习就是为了解决这个问题而诞生的。把多个相关(related)的任务(task)放在一起学习。这样做真的有效吗?答案是肯定的。多个任务之间共享一些因素,它们可以在学习过程中,共享它们所学到的信息,这是单任务学习所具备的。相关联的多任务学习比单任务学习能去的更好的泛化(generalization)效果。

单任务与多任务对比如图1所示:

from

多任务学习有效的原因

为什么把多个相关的任务放在一起学习,可以提高学习的效果?关于这个问题,有很多解释。这里列出其中一部分,以图2中由单隐含层神经网络表示的单任务和多任务学习对比为例。

(1)、多人相关任务放在一起学习,有相关的部分,但也有不相关的部分。当学习一个任务(Main task)时,与该任务不相关的部分,在学习过程中相当于是噪声,因此,引入噪声可以提高学习的泛化(generalization)效果。

(2)、单任务学习时,梯度的反向传播倾向于陷入局部极小值。多任务学习中不同任务的局部极小值处于不同的位置,通过相互作用,可以帮助隐含层逃离局部极小值。

(3)、添加的任务可以改变权值更新的动态特性,可能使网络更适合多任务学习。比如,多任务并行学习,提升了浅层共享层(shared representation)的学习速率,可能,较大的学习速率提升了学习效果。

(4)、多个任务在浅层共享表示,可能削弱了网络的能力,降低网络过拟合,提升了泛化效果。

(5)、多任务学习假设不同任务数据分布之间存在一定的相似性,在此基础上通过共同训练和优化建立任务之间的联系.这种训练模式充分促进任务之间的信息交换并达到了相互学习的目的,尤其是在各自任务样本容量有限的条件下,各个任务可以从其它任务获得一定的启发,借助于学习过程中的信息迁移能间接利用其它任务的数据,从而缓解了对大量标注数据的依赖,也达到了提升各自任务学习性能的目的。

还有很多潜在的解释,为什么多任务并行学习可以提升学习效果(performance)。多任务学习有效,是因为它是建立在多个相关的,具有共享表示(shared representation)的任务基础之上的,因此,需要定义一下,什么样的任务之间是相关的。

from


如何有效地利用多任务学习:


使用相关度高地任务,相关(related)的具体定义很难,但我们可以知道的是,在多任务学习中,related tasks可以提升main task的学习效果,基于这点得到相关的定义:

Related(Main Task,Related tasks,LearningAlg)= 1

LearningAlg(Main Task||Related tasks)> LearningAlg(Main Task) (1)

LearningAlg表示多任务学习采用的算法,

公式(1):第一个公式表示,把Related tasks与main tasks放在一起学习,效果更好;

第二个公式表示,基于related tasks,采用LearningAlg算法的多任务学习Main task,要比单学习main task的条件概率概率更大(所谓地条件概率说白了就是X到y的映射关系)。特别注意,相同的学习任务,基于不同学习算法,得到相关的结果不一样:

Related(Main Task,Related tasks,LearningAlg1)不等于 Related(Main Task,Related tasks,LearningAlg2)




多任务算法的分类

因为nn的多任务学习是研究的重点,目前也发展的很好,所以下面先总结一下传统的一点也不简单的做法:


现有的各种分类方法太过学术,对于上手写代码没什么帮助,这里做个简化好了,

从 input,model,output,loss四个层面出发来总结一下

首先还是先看传统结构化学习方法:

基于任务层面

1、模型参数共享:典型例子,多个input+相同的一个DNN模型,output对接不同任务的任务层,就是一个多输入多输出多loss的简单网络结构(之所以这种方法也列为传统结构化学习方法是因为还有多任务SVM这样的东西。。。)

input 单个或者多个

model 整体是一个

output 多个任务对应多个任务层

loss 多个loss

大概如下图


2、公共特征共享:典型例子,grouplasso,简单来说就是通过模型的特征选择(施加正则项)来对input的数据进行自动特征选择,最终选择出一组最好的公共子特征集对标模型最终收敛的最优结果,这种和第一种不一样,input只能是单个数据集,output可以接多个任务层,毕竟线性回归就是简单的神经网络,也能做很多魔改。

input 单个

model 整体一个

output 多个任务对应多个任务层

loss 多个loss


3、多任务聚类结构

简单来说就是先聚类,每个聚类簇分别进行多任务学习,上图画的很清楚了,原文也解释的很清楚了。

因为做聚类要在同一个数据集上做,所以input是一个

input: 1个

model:多个,不同聚类簇分别一个model

output:不同聚类簇对应多个output,也就是不同任务的任务层;

loss:不同聚类簇对应多个loss


4、多任务子空间学习

这玩意儿和迁移学习里基于特征的迁移方法非常像,简单来说就是对原始特征进行映射(比如NMF、PCA这类的),映射到一个新的空间,在这个空间里,多个任务进行优化,简单来说有两个思路:

1、特征映射和模型训练解耦,特征映射完之后再搭配别的方法做多任务学习;

2、特征映射和模型训练耦合,学习映射的function的同时进行多任务学习;



基于特征层面

前面的基于任务层面的方法本质上对于多个任务都用的一样的特征集(第一个方法nn的例子用的也是公共的隐向量输出)。

基于任务层面的学习方法都是建立在所有任务 或组内任务具有相关性的假设基础上,出发点是判断大部分特征是否具有总体相似度.有时候任务关联性较强时,粗略共享是有效的,但是实际在很多任务中往往存在一些具有任务特异性的特征,这些区分度比较高的特征不能用简单的方式在任务间共享.如果在包含这些特征的任务上强制共享这些特异特征可能会出现以下两种情况:

1 在任务分类的时候由于其它特征的相似性使得这些特异特征被划分到不同的任务类中

2 在约束任务相关性的过程中被消除,其结果是导致负迁移和学习效果的下降.

简单来说,做法就是公共特征一套参数P,特异性特征另一套参数Q

这部分讲的太复杂了,让人望而生畏,

下面这篇里面提到的写的比较好:

基于特征的共享MTL(联合特征学习,Joint feature learning),通过创建一个常见的特征集合来实现多个任务之间基于特征(features)的shared representation,其共享表示如下图所示。

基于特征的共享表示示意图

基于特征共享的MTL输入输出关系如下图所示,其中采用L1正则来保证稀疏性。

基于joint feature的MTL示意图

如上图,等号左边nxp的输入矩阵,乘上一个由k个任务构成的pxk的共享特征矩阵,加上一个nxk的噪声矩阵(不相关部分),就得到了左边的输出矩阵(我比较好奇这样做的目的是啥,model在哪个部分接入。。。求大佬解释)

其他多任务学习方法还有均值约束 MTL:基于均值来约束所有的task,参数共享的高斯处理MTL,低秩约束MTL,交替结构优化MTL等等。


一些多任务学习实际的可能的场景应用:

  • 短视频和hotpotqa的多任务模型例子:方便,一次搞定多个任务,这点对工业界来说十分友好。假设要用k个模型预测k个任务,那么k个模型预测的时间成本、计算成本、存储成本、甚至还有模型的维护成本都是大于一个模型的,咱们聪明的算法小哥哥小姐姐们当然更喜欢多任务学习了,除非多任务学习的效果远远低于单任务学习。
  • 多任务学习不仅方便,还可能效果更好!针对很多数据集比稀疏的任务,比如短视频转发,大部分人看了一个短视频是不会进行转发这个操作的,这么稀疏的行为,模型是很难学好的(过拟合问题严重),那我们把预测用户是否转发这个稀疏的事情和用户是否点击观看这个经常发生事情放在一起学,一定程度上会缓解模型的过拟合,提高了模型的泛化能力。
  • 多任务学习能提高泛化能力,从另一个角度来看,对于数据很少的新任务,也解决了所谓的“冷启动问题”。
  • 多个任务放一起学的另一个好处:数据增强,不同任务有不同的噪声,假设不同任务噪声趋向于不同的方向,放一起学习一定程度上会抵消部分噪声,使得学习效果更好,模型也能更鲁棒。NLP和CV中经常通过数据增强的方式来提升单个模型效果,多任务学习通过引入不同任务的数据,自然而言有类似的效果。
  • 任务互助,某些任务所需的参数可以被其他任务辅助训练的更好,比如任务A由于各种限制始终学不好W1,但是任务B却可以轻松将W1拟合到适合任务A所需的状态,A和B搭配,干活儿不累~。

from

编辑于 2021-04-02 16:42