MENU

深度学习Pytorch学习笔记(2)-实现多项式回归

• April 1, 2022 • Read: 2720 • Python,深度学习

数据准备

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()


png

构建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()


png

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")


png

非线性多项式拟合

线性拟合的函数是一个一次函数,即一元一次函数即可表达。如果需要更高阶的多项式,如二次、三次等等时,计算的思路基本相同。若要拟合的多项式类型为:

$$ 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")


png

'''对原始数据点添加噪声'''
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=':')


png

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)

png

plt.plot(x0, model2(x_data2).to('cpu').data.numpy())
plt.plot(x0, y0)


png

Archives Tip
QR Code for this page
Tipping QR Code