[转载]原来收藏的maml的博客消失了,为了以后复习,故整篇拷贝某人的帖子。没有剽窃之意,只为未来之需!!!

Meta Learning 入门:MAML 和 Reptile

SIGAI学习与实践平台发表于SIGAI学习与实践平台订阅

506


小编推荐:

七期飞跃计划还剩7个名额,联系小编,获取你的专属算法工程师学习计划(联系小编SIGAI_NO1)

SIGAI特约作者

尹相楠

里昂中央理工 在读博士

本文介绍两个 Meta Learning 的算法:MAML 和 Reptile。原始论文分别见:

Model-Agnostic Meta-Learning for Fast Adaptation of Deep Networks

下载地址

https://arxiv.org/pdf/1703.03400.pdf

Reptile: a Scalable Metalearning Algorithm

下载地址

https://d4mucfpksywv.cloudfront.net/research-covers/reptile/reptile_update.pdf

文章内容结合了李宏毅老师的课程、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,

地址链接

https://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html

它通过微调预训练的 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。听说山东高考要考一门“基本能力测试”,这门课会学很多特别杂的知识(类比既检测人脸的位置,又检测人脸关键点坐标的网络),但这归根结底只是一门课而已,并不能因为它学的知识杂就变成了好几门课。

下图例子,Task 1 是猫狗分类任务,而 Task 2 是苹果橘子分类任务。Learning Algorithm F 即 Meta Learning 的算法,它在 Task 1 上经过训练,吐出一个分类器f1用于分类猫和狗,在测试集上算出的损失为l1,在 Task 2 上又吐出一个分类器f2,损失函数是l2。

不同 task 图示。图片来源:李宏毅老师的 PPT

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

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

李宏毅老师的 PPT 给出了 MAML 损失函数 (1) 和普通训练 (2) 的损失函数的对比。其中

代表网络的基础参数,

代表基于网络基础参数学习到的第 n 个分任务的参数,

代表以

为参数的分任务 n 的损失函数。

MAML 中,不同分任务对应一套不同的参数,它们都是基于网络参数

通过梯度下降得到的。这些参数和初始化参数

很像,但又不完全一样,因为

是最终我们需要的初始化参数,它不能受制于某个分任务,而是要掌控全场。

而普通的学习任务,如公式 (2) 不同的分任务对应了同一套参数

,这样得到的

将是照顾到所有分任务的全局最优解。但在当前所有训练 task 上的全局最优解,一定是好的初始化值么?下面两图就是反例。

左图为普通训练,右图代表 MAML 初始化。图片来源:李宏毅老师的 PPT

上图中横坐标代表网络参数,纵坐标代表损失函数。浅绿和墨绿两条曲线代表两个 task 的损失函数随参数变化曲线。我们发现如果用公式 (2),我们将得到左图的效果:在靠近墨绿色曲线的附近,找到可以使两个任务损失函数之和最小的参数

。但是如果用它作为初始化参数,在 task 2 上训练,我们最终将收敛到 task 2 左侧的 local minima,而不是其右侧更小的 global minima。而使用公式 (1) 时,

会掌控全场,它不太在意训练集上的损失,而是着眼于最大化网络的学习能力。如右图所示,这个

就是很好的初始化参数,往左往右,皆可到达不同任务的 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 算法,右侧为传统的预训练算法。

MAML 算法图示。图片来源:李宏毅老师的 PPT

代表网络初始化的参数,我们采样一个任务(或者好几个任务作为一个 batch,图中显示的是一个任务的情况),编号为 m。如左图第一个绿色箭头所示:基于

计算网络在任务 m 上的损失函数,然后用梯度下降法优化

,以 learning rate

得到任务 m 独有的网络参数

;接下来,如左图第二个绿色箭头所示,基于

计算任务 m 新的损失函数,并求出损失函数在

上的梯度。我们不是用这个梯度优化

,而是优化最初的那个

,用 learning rate

乘以梯度,加到

上,得到

,如第左图一个蓝色箭头所示,该箭头和第二个绿色箭头是平行的,代表

的更新方向为

处的梯度。用完了

之后,就把它扔掉了,下次再采样到任务 m 时,再基于当时的

重新算一遍。(如果这里的 batchsize 不是1,那么在计算各个 task 独有的参数时,还是单独计算,但是计算

的更新时,需要把各个 task 在其对应的

上的梯度加在一起,再更新主任务的参数

。)

接下来和上一步一样,再以

为新的网络初始化参数,采样一个新的任务 n,第一步梯度下降用于更新得到 n 独有的参数

,第二步梯度下降,用任务 n 的损失函数在

上的梯度,更新主网络参数

,从而得到

。以此类推,最终得到网络的初始化参数。

那么,为什么要先在采样出来的任务上更新一步参数,然后再计算梯度呢?这里只说一下我的直观理解:由于 learning rate 很小,其实在任务 m 上更新完了参数后,得到的

的差别也不大,因此这个梯度一定程度可以让总任务的损失函数降低。但同时,毕竟

还是不一样的,这避免了最终求到的

变成取得所有训练任务损失函数之和的 global minima,从而变成了 model pre-training 那一套。

这个 jupyter notebook 用 pytorch 实现了 MAML 论文中的 toy example

https://github.com/AdrienLE/ANIML/blob/master/ANIML.ipynb

该 toy example 的目标是拟合正弦曲线:

,其中 a、b 都是随机数,每一组 a、b 对应一条正弦曲线,从该正弦曲线采样 K 个点,用它们的横纵坐标作为一组 task,横坐标为神经网络的输入,纵坐标为神经网络的输出。我们希望通过在很多 task 上的学习,学到一组神经网络的初始化参数,再输入测试 task 的 K 个点时,经过快速学习,神经网络能够拟合测试 task 对应的正弦曲线。

对比fine-tune和MAML。图片来源:上文 jupyter notebook 链接

左侧是用常规的 fine-tune 算法初始化神经网络参数。我们观察发现,当把所有训练 task 的损失函数之和作为总损失函数,来直接更新网络参数

,会导致无论测试 task 输入什么坐标,预测的曲线始终是 0 附近的曲线,因为 a 和 b 可以任意设置,所以所有可能的正弦函数加起来,它们的期望值为 0,因此为了获得所有训练 task 损失函数之和的 global minima,不论什么输入坐标,神经网络都将输出 0。

右侧是通过 MAML 训练的网络,把它作为起点,在新任务上训练时,可以很好地拟合目标函数的曲线。

Reptile

Reptile 和 MAML 很像,它的算法如下图所示:

Reptile 算法图示。图片来源:李宏毅老师的 PPT

Reptile 中,每更新一次

,需要 sample 一个 batch 的 task(图中 batchsize=1),并在各个 task 上施加多次梯度下降,得到各个 task 对应的

。然后计算

和主任务的参数

的差向量,作为更新

的方向。这样反复迭代,最终得到全局的初始化参数。

总结

我们跳出复杂的公式,可以看到 MAML 和 Reptile 都做了一件事:在避免得到训练 task global minima 的同时,降低训练 task 的总损失函数。对总的损失函数,有点羞哒哒欲拒还迎的感觉。直观可以这样理解:如果直接用所有训练 task 的损失函数之和对

的梯度更新它,让损失函数取得 global minima(并不是真正的全局最优,而是“相对来说”的全局最优),会造成一种 task 层面的 overfitting,使得网络只能在训练 task 上取得好成绩,一旦换一个没见过的 task,它就表现得不太好了。反之,用单一 task 的参数的梯度,作为模糊的梯度下降的大方向,大差不差、马马虎虎地降低训练 task 总的损失函数,往往能获得一个较好的初始化参数。以这个初始化参数为起点,在新的任务上稍加训练,它反而能学得又快又好。

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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值