在学习神经网络时了解到神经网络具有强大得函数拟合能力,因此我针对这个问题做了个实验,使用神经网络对自定义的函数进行拟合。
-
首先定义函数
Y = 5 sin x 1 + 6 cos ( x 2 ) + 7 sin ( x 3 ) Y = 5\sin {x_1} + 6\cos ({x_2}) + 7\sin ({x_3}) Y=5sinx1+6cos(x2)+7sin(x3) -
定义网络 (直接狂堆全连接层,不解释,哈哈哈)
class net(nn.Module):
def __init__(self) -> None:
super(net,self).__init__()
self.linear1 = nn.Linear(3,64)
self.linear2 = nn.Linear(64,128)
self.linear3 = nn.Linear(128,128)
self.linear4 = nn.Linear(128,128)
self.linear5 = nn.Linear(128,128)
self.linear6 = nn.Linear(128,128)
self.linear7 = nn.Linear(128,64)
self.out = nn.Linear(64,1)
self.act = nn.ReLU()
def forward(self,x):
x = self.act(self.linear1(x))
x = self.act(self.linear2(x))
x = self.act(self.linear3(x))
x = self.act(self.linear4(x))
x = self.act(self.linear5(x))
x = self.act(self.linear6(x))
x = self.act(self.linear7(x))
x = self.out(x)
return x
- 准备数据,开始训练
# 定义函数
Y =lambda a,b,c: 5.0*np.sin(a)+6.0*np.cos(b)+7.0*np.sin(c)
# 准备数据,随机十万个数据
x = np.random.randn(100000).astype(np.float32)
# 开始训练
model = net()
model.to('cuda:0')#也可以不加,在cpu上训练
model.train()
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(),lr=0.001)
for _ in range(10):
for epoch in range(100**2):
model.train()
x1 = np.random.choice(x,1000).astype(np.float32)
x2 = np.random.choice(x,1000).astype(np.float32)
x3 = np.random.choice(x,1000).astype(np.float32)
y=[]
for i,(a,b,c) in enumerate(zip(x1,x2,x3)):
y.append(Y(a,b,c).astype(np.float32))
data_x = torch.tensor([x1,x2,x3]).transpose(1,0).cuda()
data_y = torch.tensor(y).view(-1,1).cuda()
out = model(data_x)
loss = criterion(data_y,out)
print(loss.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()
torch.save(model.state_dict(),r'./model.pth')
大概十分钟左右精度就够了,下图是训练时候的损失
- 测试如下:
model = net()
model.load_state_dict(torch.load('./model.pth'))
model.eval()
Y =lambda a,b,c: 5*np.sin(a)+6*np.cos(b)+7*np.sin(c)
# 准备数据
x = np.random.randn(100000).astype(np.float32)
a = x[random.randint(0,10000)]
b = x[random.randint(0,10000)]
c = x[random.randint(0,10000)]
print("{} VS {}".format(Y(a,b,c),model(torch.from_numpy(np.array([a,b,c]).astype(np.float32)))[0]))
测试结果:
当然如果想精度更高可以更长时间的训练。