8.5 意境级讲解迁移学习

Posted 炫云云

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了8.5 意境级讲解迁移学习相关的知识,希望对你有一定的参考价值。

迁移学习是什么?

迁移学习指的就是,假设你手上有一些跟你现在要进行的task没有直接相关的data,那你能不能用这些没有直接相关的data来帮助我们做一些什么事情。

image-20210519161547194

比如说:你现在做的是猫跟狗的classifer,那所谓没有什么直接相关的data是什么意思呢?没有什么直接相关其实是有很多不同的可能。比如说input distribution 是类似的(一样时动物的图片),但是你的label是无关的(domain是类似的,task是不像的)。还有另外的一个可能是:input domain是不同的,但是task是相同的(猫跟狗的分类,一个招财猫图片,一个是高非狗的图片)

我们在现实生活中,我们在不断的做迁移学习。比如说:你可能是是一名研究生,你可能想知道研究生咋样过日子,你就可以参考爆漫王里面的例子。在保漫王里面漫画家就是研究生,责编就等同于指导教授。漫画家每周画分镜去给责编看,跟责编讨论(就跟指导教授每周去汇报报告一样),画分镜就是跑实验。目标就是投稿就等于投稿期刊。

image-20210519162549432

虽然我们没有一个研究生的守则,但是从爆漫王里面我们可以知道说:身为一个研究生应该要做什么样的事情。那你可能会说:拿漫画跟学术做类比,有点不伦不类的(漫画也是拿生命来做的)。

任务定义

迁移学习在目标领域标注数据较少时可以从相关领域寻找已标注数据进行训练,其主要目标就是将已经学会的知识很快地迁移到一个新的领域中.相比传统的机器学习,它的优势在于允许源域和目标域的样本、任务或者分布可以有较大的差异,能够节省人工标注样本的时间.

通常将已经学习过的领域叫做“源域”,用 D S D_{S} DS来表示; 把需要应用的新的领域叫做“目标域" ,用 D T D_{T} DT 来表示. T S T_{S} TS 表示源任务, T T T_{T} TT 表示目标任务.

Pan 和 Yang 据源领域和目标领域的相似度,将迁移学习做如下分类:

  • 在归纳式迁移学习中,若 D S D_{S} DS 包含有大量标签数据,这时归纳式迁移学习就相当于多任务学习.多任务学习是指知识在不同任务之间的传递,就是将源任务中学习到的知识迁移到目标任务中去.
  • D S D_{S} DS 没有可用的标签数据,这时归纳式迁移学习就相当于自我学习.比如区分汽车和自行车的图像,未标注数据完全来自于一个和已标注数据不同的分布,这种情形被称为自我学习

image-20210519155912882

任务分类

迁移学习有很多的方法,它是很多方法的集合。下面你有可能会看到我说的术语可能跟其他的有点不一样,不同的文献用的词汇其实是不一样的。

我们现在有一个我们想要做的task,有一些跟这个task有关的数据叫做目标数据,有一些跟这个task无关的数据,这个data叫做源数据。这个目标数据有可能是有标签的,也有可能是没有标签的,这个源数据有可能是有标签的,也有可能是没有标签的,所以现在我们就有四种可能,所以之后我们会分这四种来讨论。

image-20210519190728736

研究目标

迁移学习主要解决的是以下两个问题:

( 1) 解决小数据问题.传统机器学习存在一个严重弊端: 假设训练数据与测试数据服从相同的数据分布( 但许多情况并不满足这种假设,通常需要标注大量数据以满足训练要求,有时还会造成数据的浪费) .当训练数据过少时,经典监督学习会出现严重欠拟合问题,而迁移学习可从源域的数据中抽取并迁移知识,用来完成新的学习任务.

( 2) 解决个性化问题.当需要专注于某个目标领域时,源领域范围太广却不够具体.例如专注于农作物识别时,源领域 ImageNet 太广而不适用,利用迁移学习可以将 ImageNet 上的预训练模型特征迁移到目标域,实现个性化.

应用领域

( 1) 自然语言处理: 迁移学习应用于自然语言处理的原因是自然语言领域标注和内容数据稀缺.

可以利用源域( 例如英语) 中标注的样本集来对目标域( 例如法语) 中的样本进行处理.迁移学习能够从长文本中迁移标注和内容知识,帮助处理短文本语言的分析与处理.

( 2) 计算机视觉: 由于图像中可能存在可变的光照、朝向等条件,导致标注数据与未标注数据具有不同的数据属性和统计分布,用传统机器学习显然无法满足要求.迁移学习算法能够将领域适配,进而达到训练效果,提升准确率.

( 3) 医疗健康和生物信息学: 在医学影像分析领域,医学图像训练数据的标注需要先验的医学知识,适合标注此类数据的人群稀少,从而导致训练数据严重稀缺,深度学习将不再适用.可以将迁移学习应用到医学图像的语义映射中,利用图像识别的结果帮助医生对患者进行诊断,从而减轻医生的工作负担,促进医疗实现转型.例如: 胸部 X 光片的图像通常有助于检测结核、肺炎、心脏衰竭、肺癌和结节病等.

( 4) 从模拟中学习: 从模拟中学习是一个风险较小的方式,目前被用来实现很多机器学习系统.源数据域和目标域的特征空间是一样的,但是模拟和现实世界的边缘概率分布是不一样的,即模拟和目标域中的物体看上去是不同的.模拟环境和现实世界的条件概率分布可能是不一样的,不会完全模仿现实世界中的物体交互.Udacity 已经开源了它用来无人驾驶汽车工程教学的模拟器.OpenAI 的 Universe 平台将可能允许用其他视频游戏来训练无人驾驶汽车.另一个必须从模拟中学习的领域是机器人,在实际的机器人上训练模型是非常缓慢和昂贵的,训练机械臂就是一个典型案例.从模拟中学习并且将知识迁移到现实世界的方式能缓解这个问题.

( 5) 用户评价: 例如在评价用于对某服装品牌的情感分类任务中,我们无法收集到非常全面的用户评价的数据.因此当我们直接通过之前训练好的模型进行情感识别时,效果必然会受到影响.迁移学习可以将少量与测试数据相似的数据作为训练集进行训练,能达到较好的分类效果,并且节省大量的时间和精力.

( 6) 推荐系统: 在源领域训练好一个推荐系统,然后应用在稀疏的、新的目标领域.比如已经成熟完善的电影推荐系统就可以应用在书籍推荐系统中.

( 7) 个性化对话: 训练一个通用型的对话系统,该系统可能是闲聊型,也可能是任务型的.我们可以利用迁移学习训练特定领域的小数据集,使这个对话系统适应不同任务.

1、目标域有标签,源域有标签

微调

那现在我们假设target data跟source data都同时有label的情况下,可以的做的事情是:最常见的事情就是:fine-tuning你的model

在现在的task里面,target data( x t , y t x^t,y^t xt,yt)和source data( x s , y s x^s,y^s xs,ys)都是有label的,但是我们通常是假设说:现在target data的数据量是非常少的(如果target data量是很多的话,你就当做一般的machine learning 来train你的model就好了,你也不需要做什么迁移学习),source data是很多的。虽然source data跟我们现在考虑的task没有关系,但我们想知道:在target data很少的情况下,有一大推不相关的source data到底有么有可能会有帮助。

如果你今天的target data的量很少,少到只有几个example而已,这个就叫做one-shot learning。

这样的task的例子是:在语音上最典型的例子就是speaker adaption(话语自适应技术),target data是某一个人的声音,但是这个人的声音你不太有可能有太多的label data(可能对你的machine 说了三句话),但是source data有一大堆的音频data,它是来自于不同人的。你当然不可能直接去用target data去train一个语音辨识系统,这样一定会坏掉的。所以你会希望说:这个有好几 w w w小时的source data在这个task里面有什么帮助。

处理方式是非常直觉的,那你的source data直接去训练一个model,然后接下来fine tune这个model通过target data。可能会遇到的挑战:source data非常的少,所以你在target data 训练出一个好的model,然后在source data上做train,可能就坏掉了。

保守训练

有一个技巧叫做:conservative training,你现在有大量的source data,(比如说:在语音辨识里面就是很多不同speaker的声音),那你拿来做深度网络。target data是某个speaker的声音,如果你直接拿这些去训练的话就坏掉了。你可以在训练的时候加一些约束条件(正则化),让新的model跟旧的model不要差太多。你会希望新的model的output跟旧的model的output在看同一批data的时候越接近越好。或者说新的model跟旧的model L2-Norm差距越小越好(防止overfitting的情形)

image-20210519163330053

层迁移

另外的一个方法是layer transfer,你现在用source data 训练好了一个model,把这个model的某几个layer拿出来copy到新的model里面
。接下来用Target data去训练没有copy的layer(可能你只保留一个layer没有copy),这样的好处就是Target data只需要考虑非常少的参数,这样就可以避免overfitting的情形。当然之后你的Target data够多了,那之后可能还是要fine-tune整个model。

image-20210519163613995

哪些layer应该被transfer,哪些layer不应该去transfer呢?有趣的是在不同的task上面需要被transfer的layer往往是不一样的。比如说在语音辨识上面,我们通常是copy the last few layers(最后几层)。

同样的发音方式,因为口腔结果略有差异,得到的声音是不一样的。深度网络前几层做的事情是从这个声音讯号里面得知现在说话人的发音方式,根据发音方式就可以得到说的词汇。

所以从这个角度来看,深度网络是从发音方式到辨识结果的过程,也就是深度网络后面几层是跟语者是没有关系的,所以它是可以被copy的。

不一样的是从声音讯号到发音方式这一段可能每个人都是不一样的,需要训练。

image-20210519163957886

所以在做语音辨识的时候,常见的做法是把深度网络的后几层是copy。但是在image的时候发现是不一样的,在image的时候是copy前面几层,只train最后几层。

在image的时候你会发现 ,当你source domain上训练了一CNN,CNN通常前几层做的特征提取是最简单的事情(比如前几层做的就是提取直线,简单的几何图形等特征)。所以在image上面前几层学习的东西,它是可以被transfer到其他的task上面。而最后几层CNN的东西往往是没有办法transfer到其他的东西上面去。所以在做影像处理的时候反而是会copy前面几层。

这是一个image在层 迁移上的实验, image分成source跟target,分法是按照class来分的(500 class归为source data,500 classes归为target data)。横轴的意思是:我们在做迁移学习的时候copy了几个layer(copy 0个layer,就是说完全没有做迁移学习),纵轴时候top-1 accuracy,越高越好。

image-20210519164414179

假设source跟target是没关系的,把这个Image net分为source data跟target data的时候,把自然界的东西通通当成source,target都是人造的东西,这样的迁移学习会有什么样的影响。如果source data跟target data是差很多的,那在做迁移学习的时候,你的性能会掉的非常多(如果只是copy前面几个layer的话,性能仍然跟没有跟copy是持平的)。这意味着说:即使source domain跟target domain是非常不一样的,在深度网络的第一个layer,他们仍然做的事情仍然可能是一样的。

多任务学习

接下来是多任务学习,多任务学习跟微调不同是:在微调里面我们关心target domain做的好不好,那在多任务学习里面我们同时关心target domain跟source domain做的好不好。

image-20210519165014527

其实我们今天用深度学习 方法的话,它特别适合拿来做这种多任务学习,因为你可以说:假设有两个不同的task用的同样的feature(都做影像辨识),我学习一个神经网络,中间会分叉出来一部分神经网络去处理taskA,一部分神经网络去处理taskB。这么做的好处是:你的taskA跟taskB他们在前面几个layer会是共用的(有比较多的data,会有比较好的性能)。

这样做的前提是:这两个task有没有共通性,是不是可以共用前面几个layer。

还有一种是input没有办法确定,两个不同task的input都用不同的神经网络把它transfer到同一个domain上去,在同一个domain上你在使用不同的神经网络,一条路去做taskA,一条路去做taskB。如果在这样的task下你也迁移学习,就算tasKA跟taskB的input完全不一样,如果你觉得中间几个layer有共同的地方,你还是可以用这样的model架构来处理。

多任务学习一个很成功的例子就是多语言的语音辨识,假设你现在手上有一大堆不同语言的data(法文,中文,英文等),那你在train你的model的时候,同时可以辨识这五种不同的语言。这个model前面几个layer他们会共用参数,后面几个layer每一个语言可能会有自己的参数,这样做是合理的。虽然是不同的语言,但是都是人类所说的,所以前面几个layer它们可能是share同样的咨询,共用同样的参数。

在机器翻译你也可以拥同样的事情,假设你今天要做中翻英,也要做中翻日,你也把这两个model一起train。在一起train的时候无论是中翻英还是中翻日,你都要把中文的data先做处理,那一部分neural network就可以是两种不同语言的data。

在过去收集了十几种语言,把它们两两之间互相做transfer,做了一个很大 N ∗ N N*N NN的tabel,每一个task都有进步。所以目前发现大部分task,不同人类的语言就算你觉得它们不是非常像,但是它们之间都是可以transfer。

在这里插入图片描述

这边举得例子是从欧洲语言去transfer中文,横轴是中文的data,纵轴是character error rate。假设你一开始用中文train一个model,data很少,error rate很大,随着data越来越多,error rate就可以压到30以下(蓝色线)。但是今天如果你有一大堆的欧洲语言,你把这些欧洲语言跟中文一起去做多任务训练,用这个欧洲语言的data来帮助中文model前面几层让它train更好(橙色线)。

你会发现说:在中文data很少的情况下,你有做迁移学习,你就可以得到比较好的性能。随着中文data越多的时候,中文本身性能越好,就算是中文100小时借用一些从欧洲语言对这个变化也是有微幅帮助的。所以这边的好处是说:假设你做做迁移学习的话,你只需要1/2以下的data就可以跟有两倍的data做的一样好,例如有100多个小时跟有50小时数据迁移学习训练是一样的。

常常有人会担心说:迁移学习会不会有负面的效应,这是会有可能,如果两个task不像的话,你的transfer 就是negative的。但是有人说:总是思考两个task到底之间能不能transfer,这样很浪费时间。所以就会有progressive neural networks。

渐进神经网络

progressive network neural其实是很新的做法。我先train一个task1,train好以后它的参数就固定住,那现在我们要做task2,但是task2它的每一个hidden layer都会去接前一个task1的某一个hidden layer的output。所以在train的时候好处就是:task1跟task2非常不像,首先task1的data不会移动到task2的model,所以task1一定不会比原来更差。task2去借用task1的参数,但是它可以把这些参数直接设为0,这样也不会影响task2的性能。task3也是做一样的事情,task3会同时从task1和task2的hidden layer得到information。

在这里插入图片描述

2、目标域无标签,源域有标签

接下来是:假设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是非常不匹配

在这里插入图片描述

如果你今天直接learn一个model,input是一张image,一直learn下去结果可能就会坏掉。如果我们把一个深度网络当做整体的话,深度网络前面几层我们可以看做是抽取特征,后面几层可以看做classification。我们把这个特征拿来看的话,我们会发现说:不同domain data它的特征完全就不一样,如果把MNIST丢进去的话,它是蓝色的这些点(0-9,总共10群),但是如果你今天是把另外一群image丢进去的话,你会发现抽出来的特征是红色的这一群。所以你会发现说:今天做特征抽取的时候,原来source image跟target image不在同一个位置里面,所以后面的classifier只能把蓝色的做好,红色部分就无能为力。

在这里插入图片描述

域对抗训练

所以该肿么办呢?这边希望做的事情是:前面的特征抽取它可以把domain的特性去除掉,这一招叫做Domain-adversarial training。也就是特征抽取器 output不应该是红色跟蓝色的点分成两群,而是不同的domain应该混在一起(不同domain的特性取消掉)。

那咋样learn这样的特征抽取呢?,这边的做法是在后面接一下域分类器。把特征抽取器output丢给域分类器,域分类器它也是一个classification task,它要做的事情就是:根据特征抽取器给它的特征,判断这个特征来自于哪个domain,在这个task里面,要分辨这些特征是来自MNIST还是来自与MNIST-M。

有一个生成器的output,然后又有判别器,让它的架构非常像GAN。但是跟GAN不一样的事情是:之前在GAN那个task里面,你的generator要做的事情是产生一个image,然后骗过discriminator,这件事很难。但是在这个域对抗训练 里面,要骗过域分类器太简单了。

怎么做呢?有一个解决办法是:不管看到什么东西,特征抽取器output都是0,这样就骗过了classifier。

在这里插入图片描述

所以只是training这个域分类器是不够的,因为特征抽取器可以很轻易骗过域分类器

所以你要在特征抽取器增加它任务的难度,所以特征抽取器它output 特征不仅要骗过域分类器还要同时让laebl predictor做好。这个label predictor它就吃特征抽取器output,然后它的output就是10个class。

在这里插入图片描述

所以今天你的特征抽取器不只要骗过d域分类器,还要满足label predictior的需求。抽出的feature不仅要把domain的特性消掉,同时还要保留原来feature的特性。

那我们把这三个neural放在一起的话。实际上就是一个大型的深度网络,是一个各怀鬼胎的深度网络(一般的深度网络整个参数想要做的事情都是一样的,要minimize loss),在这个深度网络k里面参数是各怀鬼胎的。蓝色label predictor做的事情是把class分类做的正确率越高越好,域分类器做的事情是想正确预测image是属于哪个域。特征抽取器想要做的事情是:要同时提高label predictor正确率,同时想要减低域分类器正确率。

特征抽取器咋样陷害队友呢(域分类器)?这件事情是很容易的,你只要加一个梯度逆转layer就行了。也就是你在做反向传播的时候(feedford和backford),在做backford task的时候你的域分类器传给特征抽取器什么样的value,特征抽取器就把它乘上一个负号。也就是域分类器告诉你说某个value要上升,它就故意下降。

域分类器因为看不到真正的image,所以它最后一定坏掉。因为它所能看到的东西都是特征抽取器告诉它的,所以它最后一定会无法分辨特征抽取器所抽出来的feature是来自哪个domain

今天的问题就是域分类器一定要奋力的挣扎,因为它要努力去判断现在的feature是来自哪个domain。

这是paper中的一些实验结果,做了不同的domain transfer。

在这里插入图片描述

我们来看一些实验结果的话,纵轴代表用不同的方法,在这四个结果里面,你会发现说:如果只用source only的话,性能是比较差的。

接下来是zero-shot-learning

零样本学习

在zero-shot-learning里面呢?跟刚才讲的task是一样的,source data有label,target data没有label。在刚才task里面可以把source data当做训练data,把target data当做testing data,但是实际上在zero-shot learning里面,它的定义又更加严格一点。它的定义是:今天在source data和target data里面,它的task是不一样的。

image-20210519173704606

比如说在影像上面(你可能要分辨猫跟狗),你的source data可能有猫的class,也有狗的class。但是你的target data里面image是草泥马的样子,在source data里面是从来没有出现过草泥马的,如果深度网络看到草泥马,就未免有点强人所难了吧。但是这个task在语音上很早就有解决办法了,其实语音是常常会遇到zero-shot learning的问题。

假如我们把不同的word都当做一个class的话,那本来在training的时候跟testing的时候就有可能看到不同的词汇。你的testing data本来就有一些词汇是在training的时候是没有看过的。

那在语音上我们咋样来解决这个问题呢?不要直接去辨识一段声音是属于哪一个word,我们辨识的是一段声音是属于哪一个音标。然后我们在做一个音标跟word对应关系的表,这个东西也就是词典。在辨识的时候只要辨识出音标就好,再去查表说:这个音标对应到哪一个word。这样就算有一些word是没有在training data里面的,它只要在你的词典里面出现过,你的model可以正确辨识出声音是属于哪一个音标的话,你就可以处理这个问题。

image-20210519173909745

在影像上我们可以把每一个class用它的属性来表示,也就是说:你有一个数据库,这个数据库里面会有所有不同可能的class跟它的属性。假设你要辨识的是动物,但是你training data跟testing data他们的动物是不一样的。但是你有一个数据库,这个数据库告诉你说:每一种动物它是有什么样的属性。比如狗就是毛茸茸,四只脚,有尾巴;鱼是有尾巴但不是毛茸茸,没有脚。

这个属性要更丰富,每一个class都要有不一样的属性(如果两个class有相同的属性的话,方法会坏掉)。那在training的时候,我们不直接辨识每一张image是属于哪一个class,而是去辨识每一张image里面它具备什么样的属性。

所以你的深度网络 的目标就是:看到猩猩的图,就要说:这是一个毛茸茸的动物,没有四只脚,没有尾巴。看到狗的图就要说:这是毛茸茸的动物,有四只脚,有尾巴。

那在testing的时候,就算今天来了你从来没有见过的image,也是没有关系的。你今天深度网络 的目标也不是说:输入的image它是哪一种动物,而是输入这一张image它是具有什么样的属性。所以输入你从来没有见过的动物,你只要把它的属性output出来,然后你就查表看:在数据库里面哪一种动物它的属性跟你现在深度网络 output最接近。有时可能没有一摸一样的也是没有关系的,看谁最接近,那个动物就是你要找的。

在这里插入图片描述

那有时候你的属性可能非常的复杂(属性的维度非常大),你可以做属性embedding。也就是说现在有一个embedding 空间,把training data每一个image都通过一个变换,变成一个embedding 空间上的一个点。然后把所有的属性也都变成embedding 空间上的一个点。

image跟属性都可以描述为向量,要做的事情就是把属性跟image都投影到同一个空间里面。也就是说:你可以想象成是对image的向量,也就是图中的 x x x,跟属性的向量,也就是图中的 y y y都做降维,然后都降到同一个尺寸空间。所以你把 x x x通过一个function f f f都变成embedding 空间上的向量,把 y y y通过另外一个function g g g也都变成embedding 空间上的向量。

这个 g ( ∗ ) g(*) g() f ( ∗ ) f(*) f()都可能是深度网络,那training的时候希望 f f f g g g越接近越好。那在testing的时候如果有一张没有看过的image,你就可以输出这张image 属性embedding后看根哪个属性最像,那你就可以知道它是什么样的image。

但是咋样找这个 f f f g g g呢?你可以说f跟g就是深度网络。input一张image它变成一个vector,或者input 属性变成一个vector。training 目标是希望:假设我们已经知道 y 1 y^1 y1 x 1 x^1 x1的 属性, y 2 y^2 y2 x 2 x^2 x2的 属性,那你就希望说找到一个 f f f g g g,它可以让 x 1 x^1 x1 y 1 y^1 y1投影到embedding 空间以后越接近越好, x 2 x^2 x2 y 2 y^2 y2投影到embedding 空间以后越接近越好。

那现在把 f f f g g g找出来了,那现在假如有一张你从来没见过的image x 3 x^3 x3在你的testing data里面,它也可以透过这个 f f f变成embedding 空间上面的一个向量,接下来你就可以说这个embedding 向量它跟 y 3 y^3 y3最接近,那 y 3 y^3 y3就是它的属性

又是你会遇到一个问题,如果我没有数据库呢?我根本不知道每一个动物的属性是什么,怎么办呢?那你可以借用word 向量。我们知道word 向量的每一个尺寸就代表了现在word某种属性。所以你不一定需要一个数据库去告诉你说:每一个动物的属性是什么。假设你有一组word 向量,这组word 向量里面你知道每一个动物对应的word 向量,那你可以把你的属性直接换成word 向量,再做跟刚才一样的embedding就结束了。

假设我们的train的目标是要让 x n x^n xn通过f、跟 y n y^n yn通过 g g g之后的距离越接近越好。
f ∗ , g ∗ = arg ⁡ min ⁡ f , g ∑ n ∥ f ( x n ) − g ( y n ) ∥ 2 f^{*}, g^{*}=\\arg \\min _{f, g} \\sum_{n}\\left\\|f\\left(x^{n}\\right)-g\\left(y^{n}\\right)\\right\\|_{2} f,g=arg以上是关于8.5 意境级讲解迁移学习的主要内容,如果未能解决你的问题,请参考以下文章

8.6 归纳式迁移学习

DDC——Deep Domain Confusion Maximizing for Domain Invariance

10.1 意境级讲解关系抽取

8.1 模型压缩的方法

21 意境级讲解 共指消解的方法

8.2 知识蒸馏 讲解 意境级