数据准备
import numpy as np
import matplotlib.pyplot as plt
import torch as tr
x_train = np.array([[3.3], [4.4], [5.5], [6.71], [6.93], [4.168], [9.779], [6.182], [7.59], [2.137], [7.042], [10.791], [5.313], [7.997], [3.1]], dtype=np.float32)
y_train = np.array([[1.7], [2.76], [2.09], [3.19], [1.694], [1.573], [3.366], [2.596], [2.53], [1.221], [2.827], [3.465], [1.65], [2.904], [1.3]], dtype=np.float32)
if tr.cuda.is_available():
device = 'cuda:0'
else:
device = 'cpu'
device
'cuda:0'
x_data = tr.from_numpy(x_train).to(device)
y_data = tr.from_numpy(y_train).to(device)
fig, ax = plt.subplots()
ax.scatter(x_data.to('cpu').numpy(), y_data.to('cpu').numpy(), color='tab:red')
ax.set_xlabel("x_train")
ax.set_ylabel("y_train")
plt.show()
构建ANN
class MyModel1d(tr.nn.Module):
def __init__(self):
super(MyModel1d, self).__init__()
self.linear = tr.nn.Linear(1, 1)
def forward(self, x):
x = self.linear(x)
return x
model1d = MyModel1d().to(device)
损失函数和优化器
criterion = tr.nn.MSELoss(reduction='mean')
optimizer = tr.optim.SGD(model1d.parameters(), lr=1e-3)
训练
loss_value = []
for epoch in range(10000):
y_pred = model1d(x_data).to(device)
loss = criterion(y_pred, y_data).to(device)
loss_value.append(loss.item())
optimizer.zero_grad()
loss.backward()
optimizer.step()
fig, ax = plt.subplots(figsize=(20, 5))
ax.plot(np.arange(len(loss_value)), loss_value)
ax.set_xlabel("Epoch")
ax.set_ylabel("Loss")
plt.show()
print("w = ", model1d.linear.weight.item())
print("b = ", model1d.linear.bias.item())
print("拟合函数表达式:", ":%f * x + :%f" % (model1d.linear.weight.item(), model1d.linear.bias.item()))
w = 0.2663855254650116
b = 0.7033794522285461
拟合函数表达式: :0.266386 * x + :0.703379
结果检验
x_test = tr.from_numpy(np.linspace(2, 11, 50, dtype=np.float32).reshape(-1, 1)).to(device)
y_test = model1d(x_test)
fig, ax = plt.subplots()
ax.plot(x_test.to('cpu').numpy(),y_test.to('cpu').data.numpy(), label='fitting line')
ax.scatter(x_data.to('cpu').numpy(), y_data.to('cpu').numpy(), color='tab:red', label='original data')
ax.legend(loc='best')
ax.set_xlabel("x_train")
ax.set_ylabel("y_train")
非线性多项式拟合
线性拟合的函数是一个一次函数,即一元一次函数即可表达。如果需要更高阶的多项式,如二次、三次等等时,计算的思路基本相同。若要拟合的多项式类型为:
$$ y = b + w_1 x + w_2 x^2 + w_3 x^3 $$
从数学角度来看,输入量即自变量仍然只有一个,即$x$。但是从神经网络的角度来看,可以将其看成三个输入量,即将$x$的不同阶次均当作一个单独的输入量,即认为:
$$ x_1 = x\\ x_2 = x^2\\ x_3 = x^3 $$
由此可知,神经网络具有三个输入,但是输出仍然只有一个,依据相同的思路构建NN,并进行训练即可。
数据准备
若原始的数据或者函数为三次多项式
$$ y = 0.9 + 0.5 x + 3 x^2 + 2.4 x^3 $$
利用原始的函数生成数据,并添加一些噪声进行扰动,构建出训练需要的数据
"""原始数据的生成"""
def func0(x):
sol = 0.9 + 0.5 * x + 3 * x**2 + 2.4 * x**3
return sol
x0 = np.linspace(-5, 5, 100)
y0 = func0(x0)
fig, ax = plt.subplots()
ax.plot(x0, y0, color='k', linewidth=2)
ax.grid(True, ls=':')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_title("Originnal Function Curve")
'''对原始数据点添加噪声'''
np.random.seed(1025)
y_noise = np.random.normal(size=y0.shape[0]) * 50 + y0
y_noise = np.float32(y_noise)
fig, ax = plt.subplots()
ax.plot(x0, y0, color='k', linewidth=2, label='Original Function Curve')
ax.scatter(x0, y_noise, color='tab:red', s=20, label='Points Data')
ax.legend(loc='best')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.grid(ls=':')
x1 = x0
x2 = x0**2
x3 = x0**3
x123 = np.float32(np.c_[x1, x2, x3])
x_data2 = tr.from_numpy(x123).to(device)
y_data2 = tr.from_numpy(y_noise.reshape(-1, 1)).to(device)
构建神经网络
class NonlinearModel(tr.nn.Module):
def __init__(self):
super(NonlinearModel, self).__init__()
self.linear = tr.nn.Linear(in_features=3, out_features=1)
def forward(self, x):
x = self.linear(x)
return x
model2 = NonlinearModel().to(device)
criterion2 = tr.nn.MSELoss(reduction='mean')
optimizer2 = tr.optim.SGD(model2.parameters(), lr=0.00001)
loss_value2 = []
for epoch in range(1000):
y_pred2 = model2(x_data2).to(device)
loss2 = criterion2(y_pred2, y_data2).to(device)
loss_value2.append(loss2.item())
optimizer2.zero_grad()
loss2.backward()
optimizer2.step()
print(model2.linear.weight.data)
print(model2.linear.bias.data)
tensor([[0.3810, 2.9940, 2.3216]], device='cuda:0')
tensor([0.6980], device='cuda:0')
plt.plot(loss_value2)
plt.plot(x0, model2(x_data2).to('cpu').data.numpy())
plt.plot(x0, y0)
本站文章如非特别说明,均为原创。未经本人同意,请勿转载!转载请务必注明出处!