乍一看到某个问题,你会觉得很简单,其实你并没有理解其复杂性。当你把问题搞清楚之后,又会发现真的很复杂,于是你就拿出一套复杂的方案来。实际上,你的工作只做了一半,大多数人也都会到此为止……。但是,真正伟大的人还会继续向前,直至找到问题的关键和深层次原因,然后再拿出一个优雅的、堪称完美的有效方案。—— 乔布斯
引言
这不到了情人节,还没有对象一起过节。就拉着AI来过。
最开始用10000(1万)轮训练,我差点以为AI差点跟我说“你想吃peach”
后来给她加个0,才听话。
废话不多说,看正文。
主要思路
多项式f(x)=13cosx-5cos2x-2cos3x-cos4x
不同于前一篇,这次来个参数方程,但我们只拟合y
输入参数为[cosx,cos2x,cos3x,cos4x]
需要拟合的参数为[13,-5,-2,-1]
所以不需要激活层,只要一个线性层
验证采用留一法
一共训练100000轮,只能说拟合得太慢
详细代码
#多项式f(x)=13cosx-5cos2x-2cos3x-cos4x
import torch
import numpy as np
import random
import matplotlib.pyplot as plt
t = torch.linspace(-15,15,1000)#生成-15到15的1000个数构成的等差数列
x = 16*torch.sin(t)**3
y = 13*torch.cos(t)-5*torch.cos(2*t)-2*torch.cos(3*t)-torch.cos(4*t)
plt.scatter(x.data.numpy(),y.data.numpy())
plt.show()
def y_features(t):
#[cosx,cos2x,cos3x,cos4x]
t = t.unsqueeze(1)
return torch.cat([torch.cos(t * i) for i in range(1,5)],1)
def x_features(t):
t = t.unsqueeze(1)
return 16*torch.sin(t)**3
t_weights = torch.Tensor([13,-5,-2,-1]).unsqueeze(1)
def target(t):
return t.mm(t_weights) #矩阵相乘
#随机生成训练数据
def get_batch_data(batch_size):
batch_x = torch.randn(batch_size)
#print(batch_x)
features_x = x_features(batch_x)
features_y = y_features(batch_x)
target_x = features_x
target_y = target(features_y)
return target_x,features_y,target_y
#建立模型
class PolynomiaRegression(torch.nn.Module):
def __init__(self):
super(PolynomiaRegression,self).__init__()
self.poly = torch.nn.Linear(4,1)
def forward(self,t):
return self.poly(t)
#开始训练
import math
epochs = 100000
batch_size = 32
model =PolynomiaRegression()
criterion = torch.nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(),0.001)
loss_value = np.inf
loss_holder = []
step = 0
for epoch in range(epochs):
target_x,batch_x,batch_y = get_batch_data(batch_size)
out = model(batch_x)
loss = criterion(out,batch_y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
if(loss<loss_value):
torch.save(model,'model.ckpt') #存模型
loss_value = loss
if(epoch%100==0):
step+=1
loss_holder.append([step,math.sqrt(loss/batch_size)])
if(epoch%1000==0):
print("Epoch:[{}/{}],loss:[{:.6f}]".format(epoch+1,epochs,loss.item()))
if(epoch%10000==0):
predict = model(y_features(t))
plt.plot(x.data.numpy(),predict.squeeze(1).data.numpy(),"r")
loss = criterion(predict,y.unsqueeze(1))
plt.title("Loss:{:.4f}".format(loss.item()))
plt.xlabel("X")
plt.ylabel("Y")
plt.scatter(x,y)
plt.show()
结果
从运行结果可以看到98100轮后(9810*10)基本稳定。但从测试结果看出100000轮都还没过拟合。。。看来还需要多几轮训练。