MAML(Model-Agnostic-Meta-Learning)是Meta-learning(即元学习,又叫Learn-to-Learn)的其中一个类别。有关Meta-learning的理论,可以参考李宏毅教授的B站视频。参考网上博主的一个比较恰当的例子来说明Meta-learning就是:经典的监督学习是让学生去学习某一个单词怎么去读,学生会模仿老师的发音;对于下一个单词(任务),学生会继续模仿老师的发音去学习,但是一旦你给了一个学生不认识的单词,不教发音的话,学生自然就不会了。那么Meta-learning就是来解决这个问题,它是用来教会学生如何去学习,即培养学习能力的技术。同样是这个教单词的例子,Meta-learning这个老师怎么教学呢?他会教学生如何去认识理解音标,这样下次碰到不认识的单词,学生就会根据其音标去正确读取单词,相比之前的学生,经过Meta-learning教出来的学生学习能力更强。
就我个人而言,学习Meta-learning一个最重要的原因,就是它的通用性
。换句话说,在AI领域,Meta-learning可以当做一种可以在许多task上通用的算法使用!这一点我想一直是AI领域研究者都在努力的一个方向吧。特别是强化学习方面,通常一种算法可适配某一个环境,但换一个环境,这个算法可能就拉跨了,我们通常会去费劲去调节这个算法的超参数等,可以说很不方便,那么Meta-learning他针对的不是某一个特定的task,而是去学习如何更快速高效的学习一堆不同的task。元学习面向的不是学习的结果,而是学习的过程。其学习的不是一个直接用于预测的数学模型,而是学习“如何更快更好地学习一个数学模型”。
原论文地址,点这里
参考列表:
①李宏毅Meta-Learning学习笔记
②一篇对MAML解读比较好的知乎文章
③MAML论文解读
快速适应
到不同的子模型上,这里的快速指的是MAML算法只需要用几步甚至一步更新就可以让子模型自己学到能让自己的task快速收敛的初始化参数 θ ′ \theta' θ′(这部分细节后面会详述)。过拟合
。二来是不同的task,他们的样本都是不同的,难以通用化。新的task
上用少量数据进行微调即可学习成功。核心思想
就是用大量不同的tasks去训练meta-learner的初始化参数 θ \theta θ,训练中涉及到二重梯度,即Gradient by gradient,其中第一重梯度我们叫内层梯度,在MAML中只需要涉及单步的更新即可,想想我们之前的监督学习,参数要更新n个epoches甚至更多;第二层梯度我们叫外层梯度,他和我们batch的更新方式一样——多样本SGD更新。然后可以在少量训练数据的新任务上进行微调其模型,从而让新任务具有一个比较不错的初始化参数 θ ′ \theta' θ′。这一节是对Meta-learning这个框架进行说明。
接下来定义一些Meta-learning用到的符号:
N-way K-shot
”,他指的是在一个task中取N个类别,每个类别取K个样本进行训练。从这节开始,作者开始提出MAML算法,一种可以在任何标准数学模型去学习如何初始化参数的meta-learning算法,并且这种算法可以将原模型参数快速适应到各个子模型上,从而使得各个子模型都具有了属于自己比较合适的初始参数 θ ′ \theta' θ′——作者采用的适应方式为单步的梯度更新。
接下来作者指明了这种参数适应 θ → θ ′ \theta\to\theta' θ→θ′(也就是后面Algorithm 1中的内更新)是如何来的?
这种思想起源于比如说训练CNN的时候,网络学习到的特征可以适用于所有采样于 p ( τ ) p(\tau) p(τ)的任务 τ i \tau_i τi,而不是仅仅适用于一个task,当你换一个task的时候,这个特征就不适用了。
那么我们如何设计出这种具有通用化特性的东东呢?
作者的解释如下:首先适应是一个参数更新 θ → θ i ′ \theta\to\theta'_i θ→θi′的过程,因此我们常用gradient-based方式去表达,也就是 θ i ′ ← θ − ∇ θ \theta'_i\gets\theta-\nabla_\theta θi′←θ−∇θ的形式。其次,我们的目标是在训练好的模型 θ \theta θ上进行微调从而在新任务上获取合适的参数 θ i ′ \theta'_i θi′,所以我们要让gradient-based规则在新的task上发挥有效且快速的作用。
这个有效且快速如何实现呢?
其基本的思想就是原模型参数做一个小的改动都可以引起support-set中的task在 L o s s Loss Loss函数上有较大的的Improment。这个可以通过单样本更新来实现,因为多样本更新通过样本平均的形式来估计梯度,虽然稳定性提升但是相对单样本更新欠缺了灵活性。如上图所示,因为 L ( θ ) \mathcal{L}(\theta) L(θ)一个小的方向改动,就能促使子模型的初始参数走向最优方向 θ i ∗ \theta^*_i θi∗!
因此更新可表示成: θ ′ ← θ − α ∇ τ i L ( θ ) \theta'\gets\theta-\alpha\nabla_{\tau_i}\mathcal{L}(\theta) θ′←θ−α∇τiL(θ)。那么快速的实现方式也很直观,就是采用单步单样本
更新,因为我们之前在监督学习中对参数的更新往往要进行 N N N个epoches,现在相当于 N = 1 N=1 N=1;再啰嗦一下,单样本指的是在Meta-learning里面一个样本指的是一个task,类似于SGD,参数的更新是非常快的。
Note:
如果说第一次更新做了原模型将参数适应到各个子模型中,使得子模型们都有了新鲜出炉的初始化参数 θ i ′ \theta'_i θi′。而内更新取决于 θ \theta θ, θ \theta θ直接影响了子模型的参数,因此其值非常重要,故需要去学习并做相应的更新,关于 θ 、 θ 1 ′ 、 θ 2 ′ ⋯ 、 θ j ′ 、 L ( θ i ′ ) \theta、\theta_1'、\theta_2'\cdots、\theta'_j、\mathcal{L}(\theta'_i) θ、θ1′、θ2′⋯、θj′、L(θi′)他们间的关系如下:接下来是整个Meta-learning的重中之重,也是其区别迁移学习的一个点:和一般的参数更新一样,MAML中也是采用了 θ i ′ ← θ − ∇ θ \theta'_i\gets\theta-\nabla_\theta θi′←θ−∇θ的形式,但是其 L o s s Loss Loss函数评估的是Training-set中query-set上的表现,也就是说Meta-learning在乎的是用 θ \theta θ训练出来的 θ i ′ \theta'_i θi′其在子模型上的表现 L ( θ i ′ ) \mathcal{L}(\theta_i') L(θi′),我们不在意 θ \theta θ在Support-set上表现 L ( θ ) \mathcal{L}(\theta) L(θ)如何。借用李宏毅老师的PPT中的一张图说明(当时把笔记直接写图上了):这张图表示的意思就是,可能我的初始化参数 θ \theta θ(就是上图的 ϕ \phi ϕ)表现并不好,因为其在2个 L o s s Loss Loss上的值都比较高,但它可能是个很不错的 θ \theta θ,因为如上图所示,此时 θ \theta θ如果按照内更新
来,他只要一直往同一个方向走,就可以很轻松到达 θ 1 ′ 、 θ 2 ′ \theta_1'、\theta_2' θ1′、θ2′,而此时的 θ 1 ′ 、 θ 2 ′ \theta_1'、\theta_2' θ1′、θ2′在他们各自任务上的表现非常好, L o s s Loss Loss达到全局最小(这里只是借助上图说明,实际问题不一定是全局最小,一般都是局部最小),这才是我们想要的结果——让真正的数学模型有一个不错的参数,这才是真正好的 θ \theta θ。
根据上述特点,我们就可以来学习原模型参数 θ \theta θ,或者说对旧的参数根据子模型在 L o s s Loss Loss上的反馈进行调整更新:
θ ← θ − β ∇ θ L τ i ∼ p ( τ ) ( f θ i ′ ) (1) \theta\gets\theta-\beta\nabla_\theta\mathcal{L}_{\tau_i\sim p(\tau)}(f_{\theta'_i})\tag{1} θ←θ−β∇θLτi∼p(τ)(fθi′)(1)Note:
Hessian矩阵
,虽然如今TF或者PyTorch都可以计算,但是Hessian矩阵的计算量非常大,故作者采用一阶近似的手法完成Hessian-free,具体公式推导参考李宏毅老师的PPT:Emmmm…其实作者是用0和1去取代了二阶导数部分,虽然和真实的会有偏差,但是MAML这样做效果还不错,证明这种近似还是有用的。将我们上述的内容整合起来,就是MAML的伪代码——Algorithm 1:
Note:
更新一次就可以最大化性能
的能力。③虽然训练的时候只用了单步,但是不影响微调的时候你可以使用多步更新。④当我们训练数据少的时候,单步更新可以避免过拟合。这一节开始将MAML这个框架应用于监督学习中的回归与分类以及强化学习中去。虽然三者的数据来源不同以及 L o s s Loss Loss函数不同,但是都能与MAML兼容。
Few-shot learning是Meta-learning在监督学习下的一个典型应用,这是一种在少样本的情况下,利用Meta-learning的方式进行的学习。Few-shot learning利用先前的经验知识来进行少样本任务的训练。虽然Meta-learning在多样本和少量样本下都能使用,但是只有在少量样本的情况下才能发挥Meta-learning的优势,正如李宏毅教授所说,一般情况下在我们做Meta-learning的时候,都假设在做Few-shot learning。
接下来将对监督学习的回归与分类问题进行描述
在2.1小节我们曾定义样本 τ \tau τ在Meta-learning中的定义:
τ = { L ( x 1 , a 1 , ⋯ , x H , a H ) , q ( x 1 ) , q ( x t + 1 ∣ x t , a t ) , H } \tau=\{\mathcal{L}(x_1,a_1,\cdots,x_H,a_H),q(x_1),q(x_{t+1}|x_t,a_t),H\} τ={L(x1,a1,⋯,xH,aH),q(x1),q(xt+1∣xt,at),H},那么在监督学习中 H = 1 H=1 H=1, x i x_i xi相当于监督学习中的一个样本,比如一张图片。在N-way K-shot设置下,任务 τ i \tau_i τi会产生N个类别,其中每个类别从分布 q q q中产生K张独立同分布的图片用作Training-test的Support-set,再加上一定数量的Query-set,从而组成一个task,在Meta-learning中就是一条训练数据,多个task组成在一起就是一个mini-batch。
在回归问题上,作者介绍了MSE损失函数:
L τ i ( f ϕ ) = ∑ x ( j ) , y ( j ) ∼ τ i ∣ ∣ f ϕ ( x ( j ) − y ( j ) ) ∣ ∣ 2 2 (2) \mathcal{L}_{\tau_i}(f_\phi)=\sum_{x^{(j)},y^{(j)}\sim\tau_i}||f_\phi(x^{(j)}-y^{(j)})||^2_2\tag{2} Lτi(fϕ)=x(j),y(j)∼τi∑∣∣fϕ(x(j)−y(j))∣∣22(2)Note:
在分类问题上,作者介绍了使用Cross-entropy做二分类:
L τ i ( f ϕ ) = ∑ x ( j ) , y ( j ) ∼ τ i y ( j ) log f ϕ ( x ( j ) ) + ( 1 − y ( j ) ) log ( 1 − f ϕ ( x ( j ) ) ) (3) \mathcal{L}_{\tau_i}(f_\phi)=\sum_{x^{(j)},y^{(j)}\sim\tau_i}y^{(j)}\log f_\phi(x^{(j)})+(1-y^{(j)})\log(1-f_\phi(x^{(j)}))\tag{3} Lτi(fϕ)=x(j),y(j)∼τi∑y(j)logfϕ(x(j))+(1−y(j))log(1−fϕ(x(j)))(3)
将上述整合成伪代码Algorithm 2:
Note:
Meta learning不仅可以用于监督学习,在RL领域同样适用。Meta learning对强化学习最大的意义在于只需要收集少量的经验样本,就可以学习到适合新task的策略 π ( a ∣ s ) \pi(a|s) π(a∣s)。众所周知,在RL里面,Agent和环境进行交流获取样本的过程是最耗时的,而结合Meta-learning在少量样本上就可以展开学习的特性,可以大大减少Agent收集样本的时间,从而加速RL的学习。这里举个RL里面最开始接触的简单例子——迷宫寻路。Meta-RL会在一些task上进行训练,那么标准的RL算法可以使得Agent走出迷宫,那么当面对一个新的迷宫的时候,Meta-RL将在少量经验样本的基础上,让Agent走出新环境的迷宫。
接下来将对RL问题进行描述:
重新回顾下 τ \tau τ的定义: τ ∼ p ( τ ) \tau\sim p(\tau) τ∼p(τ):
τ = { L ( x 1 , a 1 , ⋯ , x H , a H ) , q ( x 1 ) , q ( x t + 1 ∣ x t , a t ) , H } \tau=\{\mathcal{L}(x_1,a_1,\cdots,x_H,a_H),q(x_1),q(x_{t+1}|x_t,a_t),H\} τ={L(x1,a1,⋯,xH,aH),q(x1),q(xt+1∣xt,at),H}在RL中, τ i \tau_i τi包含了一个初始分布 q i ( x 1 ) q_i(x_1) qi(x1),转移概率矩阵 q ( x t + 1 ∣ x t , a t ) q(x_{t+1}|x_t,a_t) q(xt+1∣xt,at)以及损失函数 L \mathcal{L} L,其一般为负的值函数。时间步为 H H H,所以整个task就是一个MDP,时间步 t ∈ { 1 , ⋯ H } t\in\{1,\cdots H\} t∈{1,⋯H}。
RL的损失函数为(省略折扣因子 γ \gamma γ):
L τ i ( f ϕ ) = E x t , a t ∼ f ϕ , q τ i [ ∑ t = 1 H R i ( x t , a t ) ] (4) \mathcal{L}_{\tau_i}(f_\phi)=\mathbb{E}_{x_t,a_t\sim f_\phi,q\tau_i}[\sum^H_{t=1}R_i(x_t,a_t)]\tag{4} Lτi(fϕ)=Ext,at∼fϕ,qτi[t=1∑HRi(xt,at)](4)Note:
因为式(4)不符合我们对 L o s s Loss Loss的要求,所以可以采用policy-based系列中的值函数来表示,目的在于利用策略梯度上升去做policy improvement。这部分还可以利用其它的一些算法来做,比如TRPO等。
将上述整合成伪代码就是Algorithm 3:
Note:
On-policy
算法,也就是说采集样本的策略 π \pi π要和更新的策略 π \pi π保持一致,学习所用的数据不能脱离目标策略,因此在step:8中需要用 f θ ′ f_{\theta'} fθ′重新进行采样以供step:10中的梯度更新使用(step:10由于一阶近似可以看成是 θ ′ \theta' θ′在做更新)。略
由于博主研究的是深度强化学习,所以实验部分只研究强化学习部分。
略
略
作者提供了学习过程的动态视频,如下图所示:
具体视频网址——点这里。
实验这部分需要结合代码进行复现才能理解。由于篇幅原因,这部分我将放到另一篇MAML实战中。
简单的通用性算法
,其可以适用于任何环境与模型。之前不管是监督学习还是RL,基本都是在特定的task上表现不俗,但是换了一个环境或者任务,就必须通过耗时耗力的调参去适应新的task。而现在我们有了Meta-learning,他拥有同时学习很多不同task的能力!