参考链接: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()