MAML——模型无关元学习(reptile)(Meta Learning) & Pytorch实现

      MAML, Model-Agnostic Meta-Learning, 模型无关元学习

      MAML其实做的就是学一个更好的模型参数初始化

      为什么说meta learning能达到怎样的效果,多么有用,但是最后只是落脚在了一个初始化上呢。因为你像预训练pretrain model,也就是一个初始化,如果初始化很好的话,那么模型可能不需要怎么学就能performance很高了

       MAML中的不同任务,指的是例如都是分类任务,但是任务a是分类鸟牛马,而任务b是分类车船飞机,这就是MAML中的不同任务。也就是说,这里的所谓不同任务,其用的模型都是同一个,但是更新过后的参数可能梯度下降会往不同的方向走

      MAML并不是一个深度学习模型,倒是更像一种训练技巧

meta-learning主要分为两个阶段

  • meta-train:用来训练模型参数,使得模型能够学到不同任务中的共同参数
  • meta-test:类似于fine-tuneing阶段,用来微调下游任务。

       首先假设我们首先有数据集D,这个数据集有10个类别,每个类别有100个样本,共1000个样本数据集。

      我们把数据集进行分割,把100个样本分成3份,比例是1:4:5。这三份的样本数量为10,40,50。

      N-way K-shot:在meta-train阶段,假设实验中设置5-way 10-shot,也就是在每个任务task中抽样5个类别,每个类别10份数据,构成一个support set,用在meta-train阶段。这5个类别中,另外的40份数据为query set,可以用在meta-test阶段;而还剩10个类别的50份数据,用来进行微调任务。

MAML的种类

  1. 回归
  2. 分类
  3. 强化学习

不同点只在于loss函数的不同。

Pytorch代码

只是为了理解,实际使用还是要用官方的代码

代码中没有体现下游微调任务

这里为了能和输出结果过sigmoid匹配上,所以classes都是0.几的

import numpy as np

classes = [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]
way = 5
shot = 10
def sample_points(k):
    c = np.random.choice(classes, size=way, replace=False)

    x = np.random.rand(k*way, 16) #16是每一个数据的自身的维度
    y = np.random.choice(c, size=k*way).reshape([-1,1])
    return x,y


class MAML(object):
    def __init__(self):
        """
        定义参数,实验中用到10-way,10-shot
        """
        # 共有10个任务
        self.num_tasks = 10
        
        # 每个任务的数据量:10-shot
        self.num_samples = shot

        # 训练的迭代次数
        self.epochs = 20000
        
        #lr
        self.alpha = 0.0001
        
        # 外循环的学习率,用来更新meta模型的\theta
        self.beta = 0.0001
       
        # meta模型初始化的参数
        self.theta = np.random.normal(size=16).reshape(-1, 1)
      
    # sigmoid函数
    def sigmoid(self,a):
        return 1.0 / (1 + np.exp(-a))
    
    #now let us get to the interesting part i.e training :P
    def train(self):        
        # 循环epoch次数
        for e in range(self.epochs):        
            self.theta_ = []
            
            # meta-train
            # 利用support set
            for i in range(self.num_tasks): 
                #每次循环都是一次新的任务

                # 抽样k个样本出来,k-shot
                XTrain, YTrain = sample_points(self.num_samples)
                
                # 前馈神经网络
                a = np.matmul(XTrain, self.theta)
                YHat = self.sigmoid(a)

                # 计算交叉熵loss
                loss = ((np.matmul(-YTrain.T, np.log(YHat)) - np.matmul((1 -YTrain.T), np.log(1 - YHat)))/self.num_samples)[0][0]
                
                # 梯度计算,更新每个任务的theta_,不需要更新meta模型的参数theta
                gradient = np.matmul(XTrain.T, (YHat - YTrain)) / self.num_samples
                self.theta_.append(self.theta - self.alpha*gradient)
                
            # 初始化meta模型的梯度
            meta_gradient = np.zeros(self.theta.shape)
            
            # meta-test
            # 利用query set
            for i in range(self.num_tasks):
                # 在meta-test阶段,每个任务抽取40个样本出来进行
                XTest, YTest = sample_points(40)

                # 前馈神经网络
                a = np.matmul(XTest, self.theta_[i])#这里用的是刚才meta-train更新过的参数
                YPred = self.sigmoid(a)
                           
                # 这里需要叠加每个任务的loss
                meta_gradient += np.matmul(XTest.T, (YPred - YTest)) / self.num_samples

            # 更新meat模型的参数theta
            self.theta = self.theta - (self.beta * meta_gradient / self.num_tasks)
                                       
            if e % 1000==0:
                print("Epoch {}: Loss {}\n".format(e,loss))
                print('Updated Model Parameter Theta\n')
                print('Sampling Next Batch of Tasks \n')
                print('---------------------------------\n')

if __name__ == '__main__':
    x, y = sample_points(10)
    print(x[0])
    print(y[0])
    model = MAML()
    model.train()
    #self.meta是最终学得的值


 

reptile是MAML的变形

  • 2
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值