Meta Learning 入门:MAML 和 Reptile

本文介绍我最近学习的两个 Meta Learning 的算法:MAML 和 Reptile。原始论文分别见:Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks 和 Reptile: a Scalable Metalearning Algorithm 。文章内容结合了李宏毅老师的课程、toy example,以及我个人的理解,可能文字有点多,但力求通俗易懂。

背景

Meta Learning 中文翻译为“元学习”,它研究的不是如何提升模型解决某项具体的任务(分类,回归,检测)的能力,而是研究如何提升模型解决一系列任务的能力。

如果把训练算法类比成学生在学校的学习,那么传统的机器学习任务对应的是不同科目,例如数学、语文、英语,每个科目上训练一个模型。而 Meta Learning 则是要提升一个学生整体的学习能力,让学生学会学习(就是所谓的 learn to learn)。就像所有的学生都上一样的课,做一样的作业,可偏偏有的学生各科成绩都好,有的学生偏科,而有的学生各科成绩都差。

各科成绩都好的学生,说明他大脑 Meta Learning 的能力强,可以迅速适应不同科目的学习任务。

而对于偏科的学生,他们大脑的 Meta Learning 能力就相对弱一些,只能学习某项具体的任务,换个任务就不 work 了。对这种学生,老师的建议一般是:“在弱科上多花一点时间”,可这么做是有风险的,最糟糕的一种情况是:弱势科目没学好,强势科目成绩反而下降了。可以看到,现如今大多数深度神经网络都是“偏科生”,且不说分类、回归这样差别较大的任务对应的网络模型完全不同,即使同样是分类任务,把人脸识别网络架构用在分类 ImageNet 数据上,就未必能达到很高的准确率。
至于各科成绩都差的学生,说明他们不但 Meta Learning 能力弱,在任何科目上的学习能力都弱,需要被老师重点关照……

Meta Learning 的算法有很多,有些高大上的算法可以针对不同的训练任务,输出不同的神经网络结构和超参数,例如 Neural Architecture Search (NAS) 和 AutoML。这些算法大多都相当复杂,我们普通人难以实现。另外一种比较容易实现的 Meta Learning 算法,就是本文要介绍的 MAML 和 Reptile,它们不改变深度神经网络的结构,只改变网络的初始化参数。

从网络参数初始化谈起

训练神经网络的第一步是初始化参数。当前大多数深度学习框架都收录了不同的参数初始化方法,例如均匀分布、正太分布,或者用 xavier_uniform,kaiming_uniform,xavier_normal,kaiming_normal等算法。除了用随机数,也可以用预训练的网络参数来初始化神经网络,也就是所谓 transfer learning,或者更准确地说是 fine-tuning 的技术。如果不了解 fine-tuning 技术,可以阅读这篇博客:Building powerful image classification models using very little data,它通过微调预训练的 VGG-16 网络,用较少的数据训练了一个高精度的猫\狗分类器(这是我当年跑通的第一个 deep learning 算法,从此走上炼丹的不归路)。fine-tuning 之所以能 work,是因为预训练的神经网络本身就有很强的特征提取能力,能够提取很多有含义的特征,例如毛皮,耳朵,鼻子,眼睛,分辨猫狗,只需要知道这些特征是如何组合的就好了,这比从头开始学习如何提取毛皮、耳朵、鼻子等特征要高效得多。

利用预训练的网络进行参数初始化,相当于赋予了网络很多先验知识。类比我们人类,让一个小学没毕业的人去听高等数学,显然他是无法听懂的;而让一个高考数学满分的高中毕业生去听,他可能要学得轻松得多。如果忽略智商因素,我们人类的大脑从结构上说都是大同小异,为啥表现差别那么大呢?因为它们积累的知识量不同,后者积累的知识更多,也就是常说的“基础扎实”,换成神经网络的术语,就是后者的网络只需要 fine-tune 一下就好了,而前者需要 train from scratch ,要补很多课才行。

通过上面的例子我们发现,预训练的网络比随机初始化的网络有更强的学习能力,因此 fine-tuning 也算是一种 Meta Learning 的算法。它和我们今天要介绍的 MAML 以及 Reptile 都是通过初始化网络参数,使神经网络获得更强的学习能力,从而在少量数据上训练后就能有很好的性能。

训练数据:以 task 为基本单位

对于传统的机器学习问题,每个模型通常只用来解决一个任务,要么是人脸识别,要么是物体分类,要么是物体检测,等等。即使有多输出的网络,例如同时检测人脸的位置和关键点,本质上其训练任务(task)还是一个,换一个任务又要从头开始训练(不考虑 fine-tuning 的技术)。而 MAML 专注于提升模型整体的学习能力,而不是解决某个具体问题的能力,因此,它的训练数据是以 task 为基本单位的,每个 task 都有自己独立的损失函数。训练时,不停地在不同的 task 上切换,从而达到初始化网络参数的目的,最终得到的模型,面对新的 task 时可以学习得更快。

还拿学生的例子类比,Meta Learning 相当于让学生学习多门功课,比如第一节数学,第二节英语,第三节历史,等等……每门功课是一个 task。听说山东高考要考一门“基本能力测试”,这门课会学很多特别杂的知识(类比既检测人脸的位置,又检测人脸关键点坐标的网络),但这归根结底只是一门课而已,并不能因为它学的知识杂就变成了好几门课。

下图是李宏毅老师在 PPT 中给的例子,Task 1 是猫狗分类任务,而 Task 2 是苹果橘子分类任务。Learning Algorithm F 即 Meta Learning 的算法,它在 Task 1 上经过训练,吐出一个分类器 f 1 f^1 f1,用于分类猫和狗,在测试集上算出的损失为 l 1 l^{1} l1,在 Task 2 上又吐出一个分类器 f 2 f^{2} f2 ,损失函数是 l 2 l^{2} l2
在这里插入图片描述
不同 task 图示。图片来源:李宏毅老师的 PPT

我们始终要牢记,Meta Learning 最终的目的是要让模型获得一个良好的初始化参数。这个初始化参数在训练 task 上表现或许并不出色,但以这个参数为起点,去学习新的 task 时,学得会又快又好。而普通的 Learning,则是着眼于解决当前的 task,不会考虑如何面对新的 task。

损失函数的奥妙:初始化参数掌控全场,分任务参数各自为营

李宏毅老师的 PPT 给出了 MAML 损失函数 (1) 和普通训练 (2) 的损失函数的对比。其中 ϕ \phi ϕ代表网络的基础参数, θ ^ n \hat{\theta}^{n} θ^n代表基于网络基础参数学习到的第 n n n 个分任务的参数, l n l^{n} ln 代表以 θ ^ n \hat{\theta}^{n} θ^n 为参数的分任务 n n n 的损失函数。

MAML 中,不同分任务对应一套不同的参数,它们都是基于网络参数 p h i phi phi通过梯度下降得到的。这些参数和初始化参数 ϕ \phi ϕ很像,但又不完全一样,因为 ϕ \phi ϕ是最终我们需要的初始化参数,它不能受制于某个分任务,而是要掌控全场。
在这里插入图片描述
而普通的学习任务,如公式 (2) 不同的分任务对应了同一套参数 ϕ \phi ϕ ,这样得到的 ϕ \phi ϕ将是照顾到所有分任务的全局最优解。但在当前所有训练 task 上的全局最优解,一定是好的初始化值么?下面两图就是反例。
在这里插入图片描述左图为普通训练,右图代表 MAML 初始化。图片来源:李宏毅老师的 PPT
上图中横坐标代表网络参数,纵坐标代表损失函数。浅绿和墨绿两条曲线代表两个 task 的损失函数随参数变化曲线。我们发现如果用公式 (2),我们将得到左图的效果:在靠近墨绿色曲线的附近,找到可以使两个任务损失函数之和最小的参数 ϕ \phi ϕ。但是如果用它作为初始化参数,在 task 2 上训练,我们最终将收敛到 task 2 左侧的 local minima,而不是其右侧更小的 global minima。而使用公式 (1) 时, ϕ \phi ϕ会掌控全场,它不太在意训练集上的损失,而是着眼于最大化网络的学习能力。如右图所示,这个 ϕ \phi ϕ就是很好的初始化参数,往左往右,皆可到达不同任务的 global minima。即:左侧图片得到的全局最优解,并不是模型学习能力最强的地方,也就是说,用这个全局最优解初始化网络参数,再在新任务上做 fine-tuning,最终得到的模型可能不会收敛到新任务的最优解。这就是 MAML 优于 fine-tuning 的地方。

再举个例子,最近教育界常常讲通识教育,素质教育,不能唯成绩论,防止学生变成做题考试的机器。这里面就暗合了 Meta Learning 的道理。我们在学校中学了很多门课,傻子都知道以后工作了并不会门门都用得上,但我们还是得学它们。因为我们要通过学习这些看似无用的课,获取一种宝贵的能力:那就是学习新知识的能力。我们传统的教育,认为门门功课考高分就是优秀,导致产生一些死读书,读死书的学生,最后人生发展并不是很好。现在教育改革的目标,就是教会学生自主学习,着眼于学生未来的发展,而不纠结于把一个类型的题练八百遍,在规定时间按照规定步骤做出来。(至于是不是可行,以及如何通过高考公平地选拔人才,那是另一个话题了)。

评价标准

既然 Meta Learning 是 learn to learn,那么如何证明 Meta Learning 算法的有效性呢?显而易见,只需要证明用这种算法得到的网络模型学习能力很强就行了。具体到我们的 MAML 和 Reptile,只需要证明,用它们这些算法初始化之后的神经网络,在新的任务上训练,其收敛速率与准确率比从随机初始化的神经网络要高。

这里所谓“新任务”,一般是指难度比较大的任务,毕竟难度大的任务才有区分度嘛,要是都像 MNIST 数据那么简单,随便一训练就 99% 的准确率,也看不出网络初始化参数所起的作用了。因此一般用 few-shot learning 的任务来评估 Meta Learning 算法的有效性。所谓 few-shot learning,就是指每类只有少量训练数据的学习任务(MNIST 每个数字都有上万张训练图片,因此不是 few-shot learning)。数据集 Omniglot:brendenlake/omniglot,是一个类似 MNIST 的手写数据集,如下图所示。该数据集包含 1623 类,每类只有 20 个训练数据,因此它属于 few-shot learning 的范畴,经常作为 benchmark 用来衡量 Meta Learning 算法的性能。

在这里插入图片描述
Omniglot

Omniglot 的用法是这样的,从其中采样 N 个类,每个类有 K 个训练两本,组成一个训练任务(task),称为 N-ways K-shot classification。然后再从剩下的类中,继续重复上一步的采样,构建第二个 task,最终构建了 m 个 task。把这 m 个 task 分成训练 task 和测试 task,在训练 task 上训练 Meta Learning 的算法,然后再用测试 task 评估 Meta Learning 得到的算法的学习能力。

MAML

上文中讲了那么多铺垫,终于可以正式开讲 MAML 算法了。抛弃原始论文中复杂的符号表示,还是采用李宏毅老师 PPT 中直观的图片,左侧为 MAML 算法,右侧为传统的预训练算法。
在这里插入图片描述
ϕ 0 \phi^0 ϕ0代表网络初始化的参数,我们采样一个任务(或者好几个任务作为一个 batch,图中显示的是一个任务的情况),编号为 m。如左图第一个绿色箭头所示:基于 ϕ 0 \phi^0 ϕ0 计算网络在任务 m 上的损失函数,然后用梯度下降法优化 ϕ 0 \phi^{0} ϕ0, 以 learning rate α \alpha α得到任务 m m m 独有的网络参数 θ ^ m \hat{\theta}^{m} θ^m,接下来,如左图第二个绿色箭头所示,基于 θ ^ m \hat{\theta}^{m} θ^m计算任务 m 新的损失函数,并求出损失函数在 θ ^ m \hat{\theta}^{m} θ^m 上的梯度。我们不是用这个梯度优化 θ ^ m \hat{\theta}^{m} θ^m,而是优化最初的那个 ϕ 0 \phi^{0} ϕ0,用 learning rate β乘以梯度,加到 ϕ 0 \phi^0 ϕ0
上,得到 ϕ 1 \phi^{1} ϕ1,如第左图一个蓝色箭头所示,该箭头和第二个绿色箭头是平行的,代表 ϕ 0 \phi^{0} ϕ0的更新方向为 θ ^ m \hat{\theta}^{m} θ^m处的梯度. 用完了 θ ^ m \hat{\theta}^{m} θ^m 之后,就把它扔掉了,下次再采样到任务 m m m 时,再基于当时的 ϕ \phi ϕ重新算一遍。(如果这里的 batchsize 不是1,那么在计算各个 task 独有的参数时,还是单独计算,但是计算 ϕ \phi ϕ的更新时,需要把各个 task 在其对应的 θ \theta θ上的梯度加在一起,再更新主任务的参数 ϕ \phi ϕ 。)
在这里插入图片描述

Reptile

Reptile 和 MAML 很像,它的算法如下图所示:
在这里插入图片描述

在这里插入图片描述

总结

我们跳出复杂的公式,可以看到 MAML 和 Reptile 都做了一件事:在避免得到训练 task global minima 的同时,降低训练 task 的总损失函数。对总的损失函数,有点羞哒哒欲拒还迎的感觉。直观可以这样理解:如果直接用所有训练 task 的损失函数之和对 ϕ \phi ϕ的梯度更新它,让损失函数取得 global minima(并不是真正的全局最优,而是“相对来说”的全局最优),会造成一种 task 层面的 overfitting,使得网络只能在训练 task 上取得好成绩,一旦换一个没见过的 task,它就表现得不太好了。反之,用单一 task 的参数的梯度,作为模糊的梯度下降的大方向,大差不差、马马虎虎地降低训练 task 总的损失函数,往往能获得一个较好的初始化参数。以这个初始化参数为起点,在新的任务上稍加训练,它反而能学得又快又好。

至于和 fine-tuning 预训练网络的技术的区别,个人认为最明显的是:预训练神经网络时,往往有它自己的任务,并没有考虑到将来别人拿这个网络做别的用途。所以它一心一意把自己的 task 搞好就万事大吉了,至于它能用在别的任务中,纯粹是无心插柳。而 Meta Learning 从一开始,就不以降低训练 task 损失函数为唯一目标,它的目标是各个 task 都学一点,然后学一组有潜力的初始化参数,以备将来新的训练任务。

  • 8
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值