元学习:MAML,拟合y=a*sin(x+b)

参考链接:https://www.bilibili.com/read/cv4286995

import numpy as np
import matplotlib.pyplot as plt
pi = np.pi
def sample_points(k):#k为对函数a*sin(x+b)在0到2π的采样点数
    a,b = np.random.uniform(1,2,2)
    x = np.arange(0,2*pi,2*pi/k)
    y = a*np.sin(x+b)
    return x,y,a,b
def draw_sin(a,b,label):
    x = np.arange(0,2*pi,0.1)
    y = a*np.sin(x+b)
    plt.plot(x,y,label = label)
#定义一下基本参数
task_num = 10#任务数目
points_num = 10
alpha = 0.01#子模型的学习率
beta = 0.01#元学习初始化参数更新的学习率
a_init = np.random.normal()
b_init = np.random.normal()#要更新的初始化参数的最初数值
epoch = 10000#元学习模型的更新次数
#寻找最优地元学习初始化参数a_init,b_init,采用MSE,平方损失,然后求梯度的复合函数求导
for epoch_ in range(epoch):
    x_train = []
    y_train = []
    a_train = []
    b_train = []
    #生成每个task的数据
    for i in range(task_num):
        x,y,a_,b_ = sample_points(points_num)
        x_train.append(x)
        y_train.append(y)
    a_gradient = 0
    b_gradient = 0
    loss = 0
    #对每一个task进行一次梯度下降,更新a,b
    #更新之后重新计算一下梯度,并累加,更新a_init和b_init
    for i in range(task_num):
        a_0 = a_init
        b_0 = b_init
        x = x_train[i]
        y = y_train[i]
        y_ = a_0*np.sin(x+b_0)
        a_0 = a_0 - sum(2*alpha*(y_-y)*np.sin(x+b_0))/points_num
        b_0 = b_0 - sum(2*alpha*a_0*(y_-y)*np.cos(x+b_0))/points_num
        y_ = a_0 * np.sin(x+b_0)
        loss += sum(np.square(y-y_))/points_num
        a_gradient += sum(2*alpha*(y_-y)*np.sin(x+b_0))/points_num
        b_gradient += sum(2*alpha*a_0*(y_-y)*np.cos(x+b_0))/points_num
    a_init -= beta+a_gradient
    b_init -= beta+b_gradient
    if epoch_%1000 == 0:
        print("epoch:%d,loss:%f"%(epoch_,loss))

x,y,a_,b_ = sample_points(points_num)
draw_sin(a_,b_,"0")
draw_sin(a_init,b_init,"MAML")
plt.legend()
plt.show()

找到a_init 和 b_init直接画出来,和随机生成的a,b进行比较。

对MAML学习得到a_init 和 b_init,进行0次梯度更新。和新样本比较

x,y,a_,b_ = sample_points(points_num)
draw_sin(a_,b_,"0")
draw_sin(a_init,b_init,"MAML")
plt.legend()
plt.show()

不进行MAML随机生成a,b,进行0次梯度更新。和新样本比较

a = np.random.normal()
b = np.random.normal()
x,y,a_,b_ = sample_points(points_num)
draw_sin(a_,b_,"0")
draw_sin(a,b,"random")
plt.legend()
plt.show()

MAML初始化参数,并进行10次迭代

a_0 = a_init
b_0 = b_init
for i in range(10):
    y_ = a_0 * np.sin(x + b_0)
    a_0 = a_0 - sum(2 * alpha * (y_ - y) * np.sin(x + b_0)) / points_num
    b_0 = b_0 - sum(2 * alpha * a_0 * (y_ - y) * np.cos(x + b_0)) / points_num
x,y,a_,b_ = sample_points(points_num)
draw_sin(a_,b_,"0")
draw_sin(a_0,b_0,"MAML-10")
plt.legend()
plt.show()

 不进行MAML,随机生成a,b,10次迭代

a = np.random.normal()
b = np.random.normal()
a_0 = a
b_0 = b
for i in range(10):
    y_ = a_0 * np.sin(x + b_0)
    a_0 = a_0 - sum(2 * alpha * (y_ - y) * np.sin(x + b_0)) / points_num
    b_0 = b_0 - sum(2 * alpha * a_0 * (y_ - y) * np.cos(x + b_0)) / points_num
x,y,a_,b_ = sample_points(points_num)
draw_sin(a_,b_,"0")
draw_sin(a_0,b_0,"random-10")
plt.legend()
plt.show()

 

MAML初始化参数,并进行100次迭代

a_0 = a_init
b_0 = b_init
for i in range(100):
    y_ = a_0 * np.sin(x + b_0)
    a_0 = a_0 - sum(2 * alpha * (y_ - y) * np.sin(x + b_0)) / points_num
    b_0 = b_0 - sum(2 * alpha * a_0 * (y_ - y) * np.cos(x + b_0)) / points_num
x,y,a_,b_ = sample_points(points_num)
draw_sin(a_,b_,"0")
draw_sin(a_0,b_0,"MAML-100")
plt.legend()
plt.show()

 

不进行MAML,随机生成a,b,100次迭代

a = np.random.normal()
b = np.random.normal()
a_0 = a
b_0 = b
for i in range(100):
    y_ = a_0 * np.sin(x + b_0)
    a_0 = a_0 - sum(2 * alpha * (y_ - y) * np.sin(x + b_0)) / points_num
    b_0 = b_0 - sum(2 * alpha * a_0 * (y_ - y) * np.cos(x + b_0)) / points_num
x,y,a_,b_ = sample_points(points_num)
draw_sin(a_,b_,"0")
draw_sin(a_0,b_0,"random-100")
plt.legend()
plt.show()

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值