转载:blog.csdn.net/tiangcs/art…html
做者:田小成plusgit
论文:《Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks》github
上一篇博客是对这篇论文的纯翻译,此次来说解下这篇论文是怎么作 meta-learning 的,这篇论文是 2017 年发表在 ICML 会议的,算是 optimization based 这个方向的开篇之做,后续的一些文章都有借鉴此论文的 idea。并且这篇论文的思想很简单,可是看明白后会惊讶于做者的思想是如此神奇,简单之中蕴含着大道理。算法
meta learning 俗称元学习,目标是 learn to learn,即学会如何学习。听起来有点绕,大白话解释就是经过以前任务的学习使得模型具有一些先验知识或学习技巧,从而在面对新任务的学习时,不至于一无所知。这更接近于人的学习过程,咱们人在过去的经历中,会不断地积累学习经验,使本身的知识积累变得愈来愈丰富,因此在面对新问题的时候,并非一无所知的,能够自动借鉴以前类似问题的经验来解决新问题。因此元学习也被称为是机器实现通用人工智能的关键技术。markdown
meta-learning 学习的对象是 Tasks,而不是 Samples 样本点,由于 meta-learning 最终要解决的问题是在新的 task 上能够更好的学习,因此要迁移以前 task 上的学习经验。那么在训练阶段,输入的就是不一样的 tasks,以下图所示,全部的 task 都是五分类任务,每一个 task 仍然有训练集和测试集,训练集是 5 类不一样的图片,该 task 的测试集是这 5 类中没有出现过的样本。不一样的 task 对应的 5 个类别是不同的,那么在若干个这样的 task 上训练以后,须要在一个新的任务上进行 meta 的测试/推理,测试任务是从未见过的 5 个类别的样本,让模型在这些样本上进行微调的训练,只不过这时候的模型在训练时就已经具有了以前学习到的 “经验”,从而能够快速适应测试任务。网络
transfer learning 迁移学习,一样也是迁移以前学习到的 “经验”,在新的数据上进行微调,好比用在 ImageNet 大数据集上预训练的 VGG 等模型,在本身的图片数据集上微调 VGG 进行特征提取,不过这里和 meta-learning 有本质的区别,稍后会详细说明。oracle
multi-task learning 是多任务学习,多个任务一块儿进行训练,以达到相互辅助训练的做用,这里的多任务能够是同一数据多个目标任务,也能够是多个数据同一个目标任务,如在人脸识别数据集上,既进行人脸识别任务,又要预测出该人脸的性别和年龄等。app
few shot learning 少样本学习,是指一份数据中可用来训练的样本不多,好比只有 10 条或者 5 条样本,那么这时候用常规的训练方式,是学不出什么的,由于可用信息太少了,那么天然就会想到用 meta-learning 的方式来训练,借助以前任务的先验经验来学习少样本的任务。few shot learning 能够说是 meta learning 在监督学习中的一个典型应用,而 meta-learning 我的以为是一个思想框架,能够用在少样本数据上也能够用在多样本数据上,只不过在 few-shot 的场景下,更能发挥出它的威力。好比一个10条样本的分类数据,用普通的训练方式,可能只取得 10% 的准确率,但用 meta-learning 的方式训练能够取得 70% 的准确率。 样本数量比较多的时候,用普通的训练方式就能够取得不错的效果,好比准确率 95%,用 meta-learning 的方式可能取得 97% 的准确率,但预训练过程就比较麻烦了。框架
few shot learning 中还有两个比较特殊的场景,就是 one shot 和 zero shot,即只有1个样本,甚至是零训练样本的场景,不过不在此次的讨论范围以内,若是你们比较感兴趣能够自行查找这方面的论文,few shot learning 目前也是学术上的研究热点。机器学习
文章开头提到 meta-learning 的研究共有三个方向,第一个方向就是 optimization based meta-learning,而 MAML 是这个方向的开山之做,因此要想知道 MAML 是怎么作的,首先要知道这个方向是如何实现 metalearning 的。
思考一下,咱们平时普通 learn 的模式是怎样训练模型的?以 DNN 网络模型为例,首先是搭建一个网络模型,接着对模型中每层的参数进行初始化,而后不断的进行“前向计算 loss -> 反向传播更新参数”的过程,直到 loss 收敛。这个过程当中,模型初始时对当前数据是一无所知的,因此要经过随机初始化的方式对参数进行赋值,尽管用多种初始化方式,但总归都是随机的。那么有没有方法可让模型从一个给定的位置开始训练呢,而且这个初始位置给的好的话,好比就在全局最优解附近,可能只须要迭代几回模型就收敛了。答案是确定的,这个方向的 metaleaning 就是来作这个事情的。简单总结下就是** optimization based meta-learning 是经过以前大量的类似任务的学习,给网络模型学习到一组不错的/有潜力的/比较万金油的参数,使用这组参数做为初始值,在特定任务上进行训练,只须要微调几回就能够在当前的新任务上收敛了**,这句话有几个值得注意的地方或者使用要求:
乍一看是否是以为和迁移学习有点像,最终形式都是从一组已知参数开始微调,可是这两个方式是有本质的区别的,这个后面还会再讲到。
在开始讲论文以前,先来看一个形象化的例子,这个例子是楼主骑车的时候无心中想到的,和论文的思想很像。这个例子就是老师教学生学习的过程,场景设定是有一个刚开始时对世界一无所知的学生,这个学生但愿经过不断的学习,具有必定的学习技巧或经验,从而能够在新的没有见过的科目上,只须要简单的学习几天,就能够在该科目上考出好成绩。为了达到这个目的,该学生请了一个老师,老师为了训练学生的学习能力,让这个学生同时学习不一样的科目,好比语文、数学、英语等,而后每一个科目都学习七天,七天以后进行各科的考试,老师会计算出该学生的平均考试成绩,并根据此次的平均成绩,对该学生的学习作出相应的指导,好比调整学习路线或者告诉他一些学习技巧等;而后让这个学生再次学习七天并考试一次,老师仍是根据平均成绩进行指导,如此不断地执行这个过程,直到老师以为该学生的考试成绩达标了,好比最近几回的平均成绩均可以到 90 分以上,就中止对这个学生的训练,并认为此时的学生已经具有了很好的学习能力。那么如何检验该学生的学习能力呢?方式就是找一个不曾学过的科目,好比操做系统,让这个学生从零开始学起,七天以后来考试一次,看他在操做系统这门课上的考试成绩如何,若是成绩很好,说明该学生已经具有了很强的学习能力,固然不必定是学习七天就考试,也能够学习一个月或者更久再进行考试。
这个例子中有两个须要思考的问题:
很明显,学的好很差就是经过当前科目上的考试成绩来判断,学习能力强不强,则是经过学习时间来判断,好比学习七天考到90分和学习一天就考到90分,是两种不一样的学习能力。
重头戏来了,先来解读下论文标题:Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks,这个标题中透漏出三个信息:
下图是论文中的伪算法,这里以监督学习中少样本分类场景为例,总体思想都是同样的。
先来解释下这个伪算法:
训练前首要先随机初始化网络模型全部参数
设置一个外层训练结束条件,例如迭代 10000 步等
外层训练就是 Meta 训练过程,上面讲过 Meta 训练的对象是 task,因此 meta 每一次的迭代都要从任务分布 p(T) 中随机抽取一个 batch 的 tasks
针对 3 中的每一个 task,执行下面的过程:
在一个具体的任务 Ti 中随机抽取包含 K 个数据点的训练样本集 D
使用交叉熵损失函数或者均方差损失函数,在 D 上计算出损失函 和损失函数对 的梯度
使用 6 计算出的梯度,在该任务上使用一次梯度降低更新模型参数
从该任务 Ti 中抽样出一个测试集 D’,用于 meta 的参数更新
每一个 task 都执行 6,7,8 三步,直到这一个 batch 的 task 都执行完
这一步就是 meta 的更新过程, 虽然 7 也有更新模型参数,可是那是任务内的局部更新,并无改变外面网络模型的参数,这一步就是要改变网络模型的参数了,仍然是使用梯度降低法进行更新,只不过更新用到的梯度是每一个任务 Ti 在各自的测试集 D’ 上计算出的batch 个梯度的平均梯度,更新的步长是 β。能够把这一步的更新,想象成上面例子中老师根据学生的平均考试成绩来调整其学习方向的过程,考试题目天然是各科上没见过的题目,这也就是第 8 步抽取测试集 D’ 的做用,而后每一个任务用本身更新过的模型参数 在 D',上进行前向计算获得一个 loss,用这个 loss 再对 进行求导获得测试集 D′上的梯度,这个梯度就至关因而该任务上的考试成绩。
上面的过程当中有一个问题须要事先说明:能够看到每一个任务内部只更新了一次参数,也就是 6,7 两步只作了一次梯度更新,但其实也能够进行屡次的梯度更新,就是把 6,7 两步重复执行几回。那做者这里为何只写一次呢?这就是做者高明的地方了,那就是作了一个最大化假设。咱们的最终目的是但愿 MAML 训练出的参数,在新的任务上进行少许几回的微调就能够收敛,那最好的结果就是只更新一次就收敛了,因此在 MAML 训练过程当中,做者就特地设计每一个任务内部只更新一次参数,以此来训练这个模型 “更新一次就能够最大化性能”的能力。类比到上面讲的例子,那就是老师但愿该学生具有强大的学习能力,在新的没有见过的科目上只学习一天就能够考出好成绩,为了训练该学生的这个能力,就让他在训练的每一个科目上都学习一自然后考试一次,老师根据平均考试成绩调整学生的学习方向,不断地重复这个过程,直到平均考试成绩能够到 90 分以上就结束训练,此时老师就认为这个学生具有了“在新科目上学习一天就能考出好成绩”的能力。
基于上面的分析,楼主本身画了一个流程图来表示通用 MAML 的训练更新过程:
这个图中是以 task 内部更新 k 次参数为例的,k=1 的时候就和 MAML 如出一辙了。
下面到了一个容易犯困的环节,伟大的思想背后天然要有坚实的数学理论支撑,MAML 的数学过程就是其训练更新的过程,理解了数学过程才能更好的理解 MAML 的思想。不过在论文中,并无过多的的数学过程介绍,多是做者以为太简单了吧,下面的数学过程也是楼主参考一些资料总结出的。
上图是 MAML 训练时模型参数的更新过程,其中 是网络模型的初始参数,也就是伪算法中的 1 那一步 是任务内部在 上更新一次后的参数,也就是伪算法的第 7 步, 是全部task 在各自测试集 D'上的 loss 和,用 对模型参数 进行求导得出梯度,来进行meta的参数更新,也就是真正更新网络模型的参数。图中右边的过程就是把 meta 梯度降低更新的数学过程展开,其中最关键的一步是蓝色弯箭头标出的那个变换,就是第二个等号到第三个等号的那一步,其它步骤还都比较好理解,下面来详细看下关键这步的变换,其中主要是 对 求导很差求,若是这个能够算出来,剩下的步骤就好说了。
上图就是计算 对 求导的过程,由于 是由 通过一次梯度降低更新获得的, 实际上是一组参数向量,表明网络模型的各个参数,因此能够将求导展开成向量形式,向量每一个元素是 对 的求导,也就是上图中的红框1,那如何计算 对 求导呢?咱们知道 是由 通过梯度降低公式获得的,那么 和 的关系就是下面这样:
也就是 和每一个 都是有关系的, 又是由多个 组成的,因此 对 的求导就是对上面的链路求导的和,每一个路径的求导则是 对 求导结果和 对 的求导结果相乘,也就是上图中红框2所在的公式,其中的关键是红框2的位置,也就是 对 的求导, 是 通过梯度降低公式变过来的,也就是图中的红色5标记的地方, 因此 对 的求导就有两种状况,i=j 和 i!=j, i=j时,计算结果就是红框4所处的公式,i!=j时就是红框3的公式,能够看到这两个公式中都出现了二阶的偏导,二阶偏导求起来比较麻烦会影响到计算速度,因此做者使用了一阶近似的方法 first-order approximation,也就是把公式中的二阶偏导近似为0,这样近似后就简单不少,即 对 的求导在i=j时约等于1,在 i!=j 时约等于0。而后顺着图中的蓝色箭头一步步带入,最后就会获得 对 的求导近似等于 对 的求导,再回到更新 meta 参数的公式来看就简单了:
上图红框标出的公式就是 meta 更新参数时实际作的事情,这个式子能够这样看 这是什么意思呢?
是第 i 个任务在其测试集上计算出的梯度方向,从几何上看,这个式子的更新过程是这样的:
蓝色点表示网络模型真正的参数,绿色第一个箭头表示在其训练集 D 上计算的梯度,绿色第二个箭头表示在其测试集D'上计算出的梯度,蓝色箭头表示 meta 模型网络模型参数的方向,能够看到它就是在每一个任务的测试集的梯度方向上不断的去作更新。从这个过程当中能够看出来,MAML 真正更新网络模型参数时,关心的是测试集上的梯度,而不是每一个任务上训练集的梯度,也就是说,它更新的每一步的目标,都是使得更新后的参数能在之后的测试集上表现的更好,正是由于这样,才能说明 meta 中止更新时的参数具备很好的潜力/学习能力,这个能力使得这组参数在以后新的任务上微调几回就能够在该任务上取得很好的性能,固然理想状况仍是微调一次就能取得不错的成绩,若是一次微调更新效果很差,那还能够再继续屡次的微调更新。这也与咱们最初但愿的目标,即能在新任务上快速适应相吻合,即便该任务只有少许的训练样本,好比10条或者5条,甚至是1条样本,也能快速的学习到一些有效特征。
在看上面的公式的时候,楼主有一个疑问,就是红框3和红框4标注的位置,做者把这个式子近似等于0,并称之为 first-order approximation一阶近似。这个二阶偏导式子是 由 通过一次梯度降低更新推导过来的,若是 是通过两次或者屡次梯度降低更新获得,那么这个式子会不会出现三阶甚至更高阶偏导,若是是的话那还能用近似的方式吗?
带着这个疑问,搜了搜做者 GitHub 的 issue,还真搜到了有人问相似的问题,
做者解答说,即便进行屡次梯度降低更新,这里也只会出现二阶偏导。只恨本身数学太渣,理解不了,哪位数学大佬能够推导下的,麻烦私信我下,哈哈,在此先行谢过。
前面讲过,元学习和迁移学习有类似的地方,形式上都是在以前的任务上进行预训练,而后得到一组参数,而后用这组参数在新的任务继续微调,但它们是有本质的区别的。想一想迁移学习的预训练是怎么训练的,好比在 ImageNet 大数据集上预训练的 RestNet、VGG 这些网络模型,它们在训练的时候是用在 ImageNet 训练集上的 loss 算出来的梯度来更新模型参数的,以训练集上的 loss 为准,关心的是当前模型参数在训练集上的性能如何。而元学习 MAML 在训练期间是用测试集上的 loss 算出的梯度来更新模型参数的,以测试集上的 loss 为准,不关心在当前训练集上的性能,而是关心这组参数在以后的测试集上的性能如何,也就是这组参数的潜力。换句话说,在 MAML 这篇论文中,是看这组参数在更新一次后的模型参数在测试集上可以表现多好,而不是训练期间可以多好,这种潜力也与元学习的大目标相符,即 Learn to learn 学会如何学习从而具有某种学习能力或学习技巧,能够在新的任务上快速学习。类比到上面老师和学生的例子,也很好理解,老师每次都是以学生的平均考试成绩为方向进行调整,这个考试成绩天然是每门功课上没有见过的题目,只有这样才能训练出该学生的学习能力。
从几何上来看,迁移学习预训练模型的参数更新过程是这样的:
这就能看出和 MAML 不同的地方了,迁移学习的预训练每次更新参数时,都是在当前任务上训练集的梯度方向上进行更新。
上面详细讲了论文的思想及数学过程,下面来看下论文中的一些实验及结论。论文中的全部实验都是少样本学习的场景,由于少样本学习是元学习一个典型的应用场景,元学习在少样本上也更能发挥出它的威力。
论文中关于回归问题的例子是,拟合正弦函数曲线,全部任务的分布p(T)就是正弦函数分布 y=a*sin(x+b),不一样的任务只须要抽样不一样的 a和b 便可,按照上面讲的 MAML 训练过程,在若干个不一样 a和b 的正弦函数上进行预训练,而后用预训练出的网络模型在新的正弦函数样本上进行测试,这个新的正弦函数是训练期间没有见过的一组a和b,只给出少许的训练样本,如5个或10个。论文中对比了 MAML 模型和迁移学习预训练模型,在这个新的正弦函数上的预测性能,注意无论是哪一种模型在这个新的任务上都仍是要进行训练的,只不过这个训练是在以前参数的基础上微调,这个新任务对于 meta 来讲就是推理任务,而在任务内部仍是须要微调更新的。下图就是 MAML 模型和预训练模型在新的正弦函数上训练以后,在其测试集上的表现。
左边两个图是 MAML 模型的结果,左边第一个图是用 MAML 的思路训练出的模型,在新正弦函数的 5 个样本上微调以后,进行预测的结果。能够看到新的正弦函数,在训练时只给了分布在右半部分的 5 个点,其中红色线是真实分布,浅绿色线是不进行微调直接用预训练参数进行预测的结果,能够看出来预训练参数跑出的结果已经有了初步的形状。深绿色线是微调一次参数后进行预测的结果,此时预测出的曲线已经基本拟合真实的正弦函数了,在包含训练样本的右半侧能够彻底拟合,在左半边的曲线,模型虽然没有见过这部分的样本但也能够学习出它的周期性质,在形状上基本拟合。左边第二个图不一样的是,给出了新的正弦函数的10个训练样本,能够看到 MAML 在进行一次微调后,基本就能够拟合所有曲线了,在进行十次微调后,拟合程度更进一步。
右边两个图是一样的设置下,迁移学习预训练模型的表现,浅蓝色曲线是直接进行预测的结果,能够看到和真实分布相差甚远,尤为是波峰的位置,彻底没对上,在微调1次和10次以后,相比于不微调,有一点进步,但和真实分布相比,依然相差较大。而且模型发生了过拟合现象,若是样本点只在右半部分,那模型在右半部分的拟合上表现还行,在另外一半的位置上表现更差。若是迁移学习预训练的任务足够多的话,它训练出的模型对应的曲线应该是一条接近水平的直线,由于每一个任务都以训练集上的 loss 为主,这么多任务的 loss 加起来更新参数时,梯度应该接近于0。从几何上理解就是,不少个正弦函数叠加在一块儿,其趋势就是一个水平线,同一个点,多是波峰也多是波谷,中间水平线的位置才能让全部任务上的 loss 最小,这就是迁移学习预训练和元学习的质的差异。
上面的图可能不是很明显,有第三方的做者复现了这个回归实验,而且从新绘制了这部分的图,以下所示,这个图看起来更明显些。
论文中也对微调次数进行了实验,结果以下图:
红色线是 oracle 设置组的结果,oracle 就是在训练时加入了该任务真实的a和b做为特征,至关于提早知道了真实分布,因此在这个设置下训练的模型,在新任务上的 mse loss 基本为 0 ,绿色线是 MAML 的模型,横轴是微调次数,能够看到微调一次的模型,就能够获得很低的 mse 偏差,而随着微调次数增长,性能也逐渐提高,不过由微调1次变为2次,提高还比较明显,后面的提高就不明显了,尤为是在5次微调以后,基本就没有提高了。蓝色线是迁移学习的预训练模型,能够看到无论是微调几回,其 mse 值都很大,与 MAML 的模型相比,更是相差甚远。
分类问题场景是两个少样本学习中常见的基准数据集:MiniImagenet 和 Omniglot,下图是在 Omniglot 数据集上的结果:
其中 5-way 是表示5分类,1-shot 表示训练时每一个类别下只有一个样本,5-shot就是每一个类别下只有5个样本,能够看到无论在哪一个设置下,MAML 模型的表现都是最好的。
下图是在 MiniImagenet 数据集上的结果:
在这个数据上,做者还对比了使用一阶微分近似和不使用的结果,还记得一阶微分近似是啥吗?不记得的话,请往上翻看数学公式部分😀😁😀,能够看到使用了一阶微分近似,在效果上相差不大,可是做者证实在速度上能够提升 33% 左右,这但是一个性价比很高的改进。