目录
摘要
Introduce
Why Need ?
Target Data labelled & Source Data labelled
Model Fine-tuning
Conservative Training
Layer Transfer
Multitask Learning
Progressive Neural Networks
Target Data unlabelled & Source Data labelled
Domain-adversarial training
Zero-shot Learning
Target Data labelled & Source Data unlabelled | Target Data unlabelled & Source Data unlabelled
结论与展望
要做一项任务,但是数据不直接与任务相关。这就涉及到了迁移学习。在现实生活中,我们其实不断在做“迁移学习”,比如学会骑自行车,就比较容易学摩托车,学会了C语言,在学一些其它编程语言会简单很多。我们想让机器也能够像人类一样举一反三,进行联想学习。
对于 Transfer Learning 的分类主要是根据目标数据是否有labels、原数据是否有labels。如果target data和source data都有标签,我们主要是使用 Fine-tuning和Multitask Learning来训练模型,fine-tuning主要是用来微调模型参数的,因为我们可能只有少量的target data的数据(不然直接训练一个模型就行了),Multitask Learning是多任务学习,可以使得在前面几个layer会是共用的,那么就有比较多的data,会有比较好的性能。而对于target data无标签,source data有标签的情况,主要分为Domain-adversarial training和 Zero-shot Learning,对于Domain-adversarial training,我们发现不同domain data它的feature完全就不一样,即便对于相同的目标的task来说,也只能识别一种domain data任务,所以我们需要训练一个网络feature extract 它可以把domain的特性去除掉,设计出来的网络类似于GAN,这就是Domain-adversarial training,而Zero-shot Learning比Domain-adversarial training更严格,连目标的task都不一样。
迁移学习指的就是,假设你手上有一些跟你现在要进行的task没有直接相关的data,那你能不能用这些没有直接相关的data来帮助我们做一些什么事情。比如说:你现在做的是猫跟狗的classifer,那所谓没有什么直接相关的data是什么意思呢?没有什么直接相关其实是有很多不同的可能。比如说input distribution 是类似的(一样时动物的图片),但是你的label是无关的(domain是类似的,task是不像的)。还有另外的一个可能是:input domain是不同的,但是task是相同的(猫跟狗的分类,一个招财猫图片,一个是高非狗的图片)
迁移学习问的问题是:我们能不能再有一些不相关data的情况下,然后帮助我们现在要做的task。
为什么我要考虑迁移学习这样的task呢?举例来说:
我们在现实生活中,我们在不断的做迁移学习。比如说:你可能是是一名研究生,你可能想知道研究生咋样过日子,你就可以参考爆漫王里面的例子。在保漫王里面漫画家就是研究生,责编就等同于指导教授。漫画家每周画分镜去给责编看,跟责编讨论(就跟指导教授每周去汇报报告一样),画分镜就是跑实验。目标就是投稿就等于投稿期刊。
迁移学习有很多的方法,它是很多方法的集合。
我们现在有一个我们想要做的task,有一些跟这个task有关的数据叫做target data,有一些跟这个task无关的data,这个data叫做source data。这个target data有可能是有label的,也有可能是没有label的,这个source data有可能是有label的,也有可能是没有label的,所以现在我们就有四种可能,所以之后分这四种来讨论。
那现在我们假设target data跟source data都同时有label的情况下,可以的做的事情是:最常见的事情就是:fine-tuning你的model
在现在的task里面,target data( xt , yt ) 和source data(xs,ys)是有label的,但是我们通常是假设说:现在target data的数据量是非常少的(如果target data量是很多的话,你就当做一般的machine learning 来train你的model就好了,你也不需要做什么迁移学习),source data是很多的。虽然source data跟我们现在考虑的task没有关系,但我们想知道说:在target data很少的情况下,有一大推不相关的source data到底有没有可能会有帮助?
处理方式是非常直觉的,拿你的source data直接去train一个model,然后接下来fine tune这个model通过target data。可能会遇到的challenge:target data非常的少,所以你在source data train出一个好的model,然后在target data上做train,可能就坏掉了。
有一个技巧叫做:conservative training,你现在有大量的source data,(比如说:在语音辨识里面就是很多不同speaker的声音),那你拿来做neural network。target data是某个speaker的声音,如果你直接拿这些去train的话就坏掉了。你可以在training的时候加一些constraint(regularization),让新的model跟旧的model不要差太多。你会希望新的model的output跟旧的model的output在看同一笔data的时候越接近越好。或者说新的model跟旧的model L2-Norm差距越小越好(防止overfitting的情形)
另外的一个方法是layer transfer,你现在用source data train好了一个model,把这个model的某几个layer拿出来copy到新的model里面 。接下来用target data只去train没有copy的layer(可能你只保留一个layer没有copy),这样的好处就是target data只需要考虑非常少的参数,这样就可以避免overfitting的情形。当然之后你的target data够多了,那之后可能还是要fine-tune整个model。
下图是一个image在layer transfer上的实验, 120多万 image分成source跟target,分法是按照class来分的(500 class归为source data,500classes归为target data)。横轴的意思是:我们在做迁移学习的时候copy了几个layer(copy 0个layer,就是说完全没有做迁移学习),纵轴时候top-1 accuracy,越高越好。
实验结果表明,copy的layer越多,结果是越差。但是copy前面几个layer性能没有很大改变,所以说前面几个layer是可以共用的。如果copy前面几个layer之后加上fine-tune整个model,结果是会变好的。当然这里的targe data是很多的。
下图是上图中红色线的后续实验,如果copy前面几个layer之后加上fine-tune整个model,然后比较:
接下来是多任务学习,多任务学习跟fine tuning不同是:在fine tuning里面我们关心的是target domain做的好不好,那在多任务学习里面我们同时关心target domain跟source domain做的好不好。
左边是相同的输入,不同的task,右边是输入和task都不一样,只是共享中间部分隐藏层的参数。其实我们今天用deep learning base方法的话,它特别适合拿来做这种多任务学习,因为你可以说:假设有两个不同的task用的同样的feature(都做影像辨识),我learn一个neural network,中间会分叉出来一部分network去处理taskA,一部分network去处理taskB。这么做的好处是:你的taskA跟taskB他们在前面几个layer会是共用的(有比较多的data,会有比较好的性能)。这样做的前提是:这两个task有没有共通性,是不是可以共用前面几个layer。
多任务学习一个很成功的例子就是多语言的语音辨识:
常常有人会担心说:迁移学习会不会有负面的效应,这是会有可能,如果两个task不像的话,你的transfer 就是negative的。但是有人说:总是思考两个task到底之间能不能transfer,这样很浪费时间。所以就会有progressive neural networks。
progressive network neural的做法,我先train一个task1,train好以后它的参数就fix住,那现在我们要做task2,但是task2它的每一个hidden layer都会去选择性的接前一个task1的某一个hidden layer的output。所以在train的时候好处就是:首先task2的data不会去动到task1的model,所以task1一定不会比原来更差。task2去借用task1的参数,但是它可以把这些参数直接设为0,这样也不会影响task2的性能。task3也是做一样的事情,task3会同时从task1和task2的hidden layer得到information。
接下来是:假设target data是unlaebl,而source data是label的时候我们可以做什么样的事情呢?
在source data里面有function的input跟output,在target里我们只有function的input,没有function的output。举例来说:我们可以说:source data是MNIST image,target data是MNIST-M image(MNIST image加上一些奇怪的背景)。MNIST是有label的,MNIST-M是没有label的,在这种情况下我们通常是把source data就视作training data,target data视作testing data。产生的问题是:training data跟testing data是非常mismatch
我们会发现说:不同domain data它的feature完全就不一样,如果把MNIST丢进去的话,它是蓝色的这些点(0-9,总共10群),但是如果你今天是把另外一群image丢进去的话,你会发现抽出来的feature是红色的这一群。所以你会发现说:今天做feature extract的时候,原来source image跟target image不在同一个位置里面,所以后面的classifier只能把蓝色的做好,红色部分就无能为力。
所以该怎么办呢?这边希望做的事情是:前面的feature extract 它可以把domain的特性去除掉,这一招较做Domain-adversarial training。也就是feature extract output不应该是红色跟蓝色的点分成两群,而是不同的domain应该混在一起(不同domain的特性取消掉)。
有一个generator 的output,然后又有discriminator,让它的架构非常像GAN。但是跟GAN不一样的事情是:之前在GAN那个task里面,你的generator要做的事情是产生一个image,然后骗过discriminator,这件事很难。但是在这个Domain-adversarial training里面,要骗过domain classifier太简单了。怎么做呢?有一个solution是:不管看到什么东西,output都是0,这样就骗过了classifier。
所以只是training这个domain classifier是不够的,因为feature extract可以很轻易骗过domain classifier,所以你要在feature extract增加它任务的难度,所以feature extract它output feature不仅要骗过domain classifier还要同时让laebl predictor做好。这个label predictor它就吃feature extract output,然后它的output就是10个class。
跟刚才讲的task是一样的,source data有label,target data没有label。在刚才task里面可以把source data当做training data,把target data当做testing data,但是实际上在zero-shot learning里面,它的difine又更加严格一点。它的定义是:今天在source data和target data里面,它的task是不一样的。
比如说在影像上面(你可能要分辨猫跟狗),你的source data可能有猫的class,也有狗的class。但是你的target data里面image是草泥马的样子,在source data里面是从来没有出现过草泥马的,如果machine看到草泥马,就未免有点强人所难了吧。
在影像上我们可以把每一个class用它的attribute来表示,也就是说:你有一个database,这个database里面会有所以不同可能的class跟它的特性。假设你要辨识的是动物,但是你training data跟testing data他们的动物是不一样的。但是你有一个database,这个database告诉你说:每一种动物它是有什么样的特性。比如狗就是毛茸茸,四只脚,有尾巴;鱼是有尾巴但不是毛茸茸,没有脚。
这个attribute要更丰富,每一个class都要有不一样的attribute(如果两个class有相同的attribute的话,方法会fail)。那在training的时候,我们不直接辨识说:每一张image是属于哪一个class,而是去辨识说:每一张image里面它具备什么样的attribute。所以你的neural network target就是说:看到猩猩的图,就要说:这是一个毛茸茸的动物,没有四只脚,没有尾巴。看到狗的图就要说:这是毛茸茸的动物,有四只脚,有尾巴。
在testing时,则根据检测出来的属性来查询数据库,看属性和那个动物最像(接近)
image跟attribute都可以描述为vector,要做的事情就是把attribute跟image都投影到同一个空间里面。也就是说:你可以想象成是对image的vector,也就是图中的x,跟attribute的vector,也就是图中的y都做降维,然后都降到同一个dimension。所以你把x通过一个function f都变成embedding space上的vector,把y通过另外一个function g也都变成embedding space上的vector。
但是咋样找这个f跟g呢?你可以说f跟g就是neural network。input一张image它变成一个vector,或者input attribute 变成一个vector。
又是你会遇到一个问题,如果我没有database呢?我根本不知道每一个动物的attribute是什么,怎么办呢?那你可以借用word vector。我们知道word vector的每一个dimension就代表了现在word某种attribute。所以你不一定需要一个datbase去告诉你说:每一个动物的attribute是什么。假设你有一组word vector,这组word vector里面你知道每一个动物对应的word vector,那你可以把你的attribute直接换成word vector,再做跟刚才一样的embedding就结束了。
接下来我们来讲一下实现的算法:
上面算法的核心思想:成对的数据要尽量拉近,不成对的数据要尽量拆散。
还有另外一个简单的Zero-Shot learning的方法叫做convex combination of semantic embedding(语义嵌入的凸组合)。
我把一张图丢到neural network里面去,它的output没有办法决定是哪一个class,但它觉得有0.5的几率是lion,有0.5的几率是tiger。接下来你在去找lion跟tiger的word vector,然后把lion跟tiger的word vector得到新的vector(用1:1的比例混合,0.5V(tiger)+0.5V(lion)),那你再看哪一个word的vector跟这个混合之后的结果最接近。假设是liger最接近,那这个东西就是liger(狮虎)
以下是这个的实验结果,也是蛮惊人的。我们来比一下人类跟机器的差别,第一张图,CNN判别说是sea lion(海狮),DeViSE(投影到embedding空间的算法)没有得到好的结果,ConSE(NN加词向量的方法)判别为各种sea lion。
target data有label,source data没有label的状况叫做self-taught learning(自我学习)。target label没有label,source data也没有label的状况叫做self-taught clustering(自我聚类)。
迁移学习是一个很有活力的领域,通过迁移学习,我们不需要再去花费巨大代价去重新采集和标定庞大的新数据集,也可以复用现有知识域数据和已有的大量工作不至于完全丢弃。
对于target data和source data都有标签的,我们通常使用的是model fine-tuning,去使用少量的target data微调模型的参数,但是训练时也是有一些小技巧的不然很容易train坏掉,有一个技巧叫做:conservative training,在training的时候加一些constraint(regularization),让新的model跟旧的model不要差太多。另外的一个方法是layer transfer,用source data train好了一个model,把这个model的某几个layer拿出来copy到新的model里面 。接下来用target data只去train没有copy的layer,这样的好处就是target data只需要考虑非常少的参数。上面两种训练的方法,目的都是为了防止过拟合。对于两个不同的task有共通性,我们可以让其共享前面几个layer,这样可以增加一些训练的data(前提两个任务是有共通性)。
对于target data无标签,source data有标签的情况,我们通常用的是Zero-shot Learning,其主要思想是训练一个网络,将source data对于的data x和对应的label y 都投影到同一个空间里面,让对于(x,y)标签对在同一空间的距离越接近越好,那么当我们输入 target data中的x,就能预target data 对于的标签y了。
需要将损失函数设置成上面那个样子,让成对的数据要尽量拉近,不成对的数据要尽量拆散。
最后,对于迁移学习可能会有负面的效应,即如果两个task不像的话,你的transfer可能就是负面的。有一个解决办法是使用progressive neural networks,我觉得这个网络结构的思想很类似于ResNet(残差网络),即后面的网络结构layer,借用前面的特征(参数),如果起不到正面的作用就把这些参数直接设为0。