首页 > 编程知识 正文

reptile有哪些,volatile底层原理

时间:2023-05-06 12:01:21 阅读:174646 作者:1501

论文:2018-On First-Order Meta-Learning Algorithms

算法简介

MAML、FOMAML、reptile都是fewshot任务中的参数初始化问题,这些算法都是寻找模型合理的初始化参数,使模型能更快适应小样本数据,在新的任务中

MAML在论文中是次要的,作者通过简化,发表了first-order MAML,FOMAML。 该算法是一次性的,更容易实施。

reptile也是一种基于梯度的元学习算法。

伪代码

这幅图很经典,但请注意。 我们k (对一个任务的更新次数)通常大于2。 想想如果是1会怎么样。

是的,就像pretrained一样。 也就是说,对多个任务求出最佳(论文的“联合训练”)。 那不行。 在后面的实验2中,可以看到一步和多步的差距。

步骤:

1 .初始化参数

2 .循环迭代I=0,1,2…

3 .对一个meta batch进行采样,每个batch中有多个任务task

在每个task,基于迭代次数k对包含k个batch的minibatch进行采样,

对minibatch内的每个batch采用梯度下降法更新初始化参数,得到’

减去每个task更新的参数’和初始参数,这个减法的结果经过某个映射(把这个差看作某个梯度,加到某个适应性算法上)。 在我们的实现中一般是%%%% )/a,这个a我们一般设定为可变的值。

回到7.2,持续到周期结束。

(后面放入代码详细介绍)

案例:一维sin函数回归问题

采用不同的a、b结构不同的sin函数,作为不同的task,采样(x,y )点进行实验。

从左到右依次是随机初始化网络和MAML、reptile算法给出的初始化参数反复32次后的结果。 (迭代32次,MLp网络)

分析:为什么reptile可以?

方法1:ymt级数展开

首先,我们来看看参数更新的流程。 以两个阶段的SGD为例。

要放置一些定义并仔细观察gi和gi_之间的差异,请注意以下1是初始值,与上面的0相同。 剩下的用0表示:

首先用ymt级数展开gi。 (因为只展开到二阶导,所以后者认为是高次项。 ) :

现在,让我们导出MAML、FOMAML和Reptile。 (这里全部取k=2。 两个步骤。 ) ) ) ) ) ) ) )。

二阶的MAML时,在训练过程中,初始参数先用support set进行一次梯度更新得到3358www.Sina.com/,然后进行参数1的测试设置那么,query set的损失函数要推导出初始参数,loss就会乘以参数1推导出初始参数,而不是推导出参数1。 具体如下:

由于FOMAML的一次简化是参数1引导初始参数的部分,所以留下了loss引导参数1的部分。

reptile将不再赘述,以下等式来自SGD下降过程中的关系:

接下来,替换变量。 (就是改变符号。 ) :

这里需要特别注意的是3358www.Sina.com/。 g2和g2_也不同。 g1表示loss相对于1的梯度,g1_表示loss相对于0的梯度。 这种差异更深地体现在后面。

然后定义两个期望值: AvgGrad和AvgGradInner。 那么,又是变量的置换:

这个置换不容易理解。 请说明一下。

首先,为什么g1_的期待和g2_的期待相等? 因为它们代表参数1,所以1和2的区别是什么?g1和g1_是不一样的

如果这里有疑问的话,回到最初的算法实现的过程,在minibatch中,输入loss对于0的梯度

因此,由于它们的期望相等,batch是随机的,所以0的梯度没有任何关系。

同样,Hi_也是二阶loss相对于0的梯度。

那么导出结束了。 接下来是不同的batch

首先,请参阅一个batch用于一次的梯度下降

loss对0斜率的平均期待是希望在所有batch中减少loss,从而减少整体的任务损失。

另一方面,AvgGradInner是g1_*g2_的导数。 由于坡度在参数更新时会标注负号,所以该值应该最大化。

说明见这个结果的意义。

来说是相同,一个batch在优化的过程中另一个batch也在优化,这样就增加了模型的泛化性和快速学习的能力。

讲完了。第2种方法没看懂。(是基于流形图最优解的)

接下来讲实验
1.在miniImage和omniglot上的实验结果


reptile是牺牲了运算准确度去换时间的。准确率上比MAML还是要稍微差一些。论文上说在miniImage上准确率高一些,这个我没有复现,但是omniglot是要差一些。但是,速度很快。时间大概只花了一半。

2.在一个minibatch里面不同batch在进行梯度更新时,使用这些不同梯度组合的结果:


看这个图的时候,理解一下gi的含义,以及gi与前面的gi_的区别。g2和g1的区别是有先后关系的,是参数一步一步更新的结果的梯度。这个实验是想探究一步一步更新的过程中,使用这个梯度的效果。并且FOML的g2比reptile在k=2时 的g1+g2效果要好。当然k可以等于其它数。

3.关于对数据选取不同的方式在不同参数下的训练情况

这个要注意一下实验条件,也就是作者在图例里的条件。
cycling是循环取,有重叠,而且重叠起来是完全重叠。
replacement是随机取,有重叠,重叠是部分重叠。
separate-tail是完全没有重叠。

分别是在不同的 inner iteration或者是不同的batch下进行的实验,在FOMAML中没有重叠的适应性普遍强一些,有重叠的在参数设置方面要注意一些。而reptile则都能够适应。

最后,放一个图:

这个图不具体,但是很直观的展示了这些算法的区别。这里的MAML是一阶的,沿着g2方向更新,reptile验证g1+g2更新,而我们常规的预训练模型就是沿着g1在更新。知道了这个区别以后,相信你会有更加深入的认识了。

最后,附上核心算法代码:

for i in range(meta_iteration):#外循环meta_step_size =i/meta_iteration*a+(1-i/meta_iteration)*b#a,b参数可调old_vars = self._model_state.export_variables()#save model paraupdates =[]for _ in range(meta_batch_size):#内循环mini_dataset = _sample_mini_dataset(dataset,num_classes,num_shots)mini_batches = self.mini_batches(mini_dataset,inner_batch_size,inner_iters,replacement)#生成一个task的k个batch,用于k步SGDfor batch in mini_batches:inputs,labels = zip(*batch)self.session.run(minimize_op,feed_dict={input_ph:inputs,label_ph:labels}new_vars.append(self._model_state.export_variables())self._model_state.import_variables(old_vars)#对下一个task恢复之前的初始参数new_vars =average_vars(new_vars)#所有更新后的参数取平均self._model_state.import_variables(old_vars-(new_vars-old_vars)*meta_step_size)#外循环对模型参数的更新。

这里需要注意的是meta_step_size是可以自适应变化的。
这个代码是摘出来的核心代码,可以帮助大家理解算法,想复现,可以去github上找找。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。