神经网络曲线拟合

1
2
3
import torch
import torch.nn as nn
from torch.utils.data import Dataset, DataLoader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Data(Dataset):
def __init__(self, x, y):
super(Data, self).__init__()
self.x = x
self.y = y

def __len__(self):
return len(self.x)

def __getitem__(self, index):
xi = self.x[index]
yi = self.y[index]
xi = torch.unsqueeze(xi, 0)
yi = torch.unsqueeze(yi, 0)
return xi, yi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class NN(nn.Module):
def __init__(self):
super(NN, self).__init__()
self.net = nn.Sequential(
nn.Linear(1,60),
nn.Sigmoid(),
nn.Linear(60,10),
nn.Sigmoid(),
nn.Linear(10,1)
)

def forward(self, x):
x = self.net(x)
return x
1
2
3
4
5
6
7
8
9
x_data = torch.linspace(-torch.pi, torch.pi, 1000)
y_data = torch.sin(x_data) + 0.2 * torch.randn_like(x_data)
datas = Data(x_data, y_data)
train_data = DataLoader(dataset=datas, batch_size=100, shuffle=True)

net = NN()

loss = nn.MSELoss()
optim = torch.optim.SGD(net.parameters(), lr=0.2, weight_decay=0.001)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
losses = []
from matplotlib import pyplot as plt
plt.scatter(x_data.numpy(), y_data.numpy(), s=5)


for epoch in range(200):
for X, y in train_data:
y_pred = net(X)
optim.zero_grad()
l = loss(y, y_pred)
l.mean().backward()
optim.step()
losses.append(l.mean().detach().numpy())
if epoch % 10 == 0:
print("Epoch:{}, mean_loss:{}".format(epoch, l.mean()))

y_preds = net.forward(x_data.reshape(-1,1)).reshape(x_data.shape)
plt.plot(x_data.numpy(), y_preds.detach().numpy(), c='r',label='epoch: {}'.format(epoch))

plt.legend()

Epoch:0, mean_loss:0.3094225525856018
Epoch:10, mean_loss:0.15924690663814545
Epoch:20, mean_loss:0.12797050178050995
...
Epoch:180, mean_loss:0.06601860374212265
Epoch:190, mean_loss:0.04816204681992531





<matplotlib.legend.Legend at 0x25d18bca040>

png

1
2
plt.figure()
plt.plot(losses)
[<matplotlib.lines.Line2D at 0x25d18cfac10>]

png