简体   繁体   English

如何在Pytorch / Python中实现多项式回归

[英]How to realize a polynomial regression in Pytorch / Python

I want my neural network to solve a polynomial regression problem like y=(x*x) + 2x -3. 我想让我的神经网络解决多项式回归问题,例如y =(x * x)+ 2x -3。

So right now I created a network with 1 input node, 100 hidden nodes and 1 output node and gave it a lot of epochs to train with a high test data size. 因此,现在我创建了一个具有1个输入节点,100个隐藏节点和1个输出节点的网络,并给它提供了很多训练高测试数据量的纪元。 The problem is that the prediction after like 20000 epochs is okayish, but much worse then the linear regression predictions after training. 问题在于,像20000个纪元之后的预测是可以的,但比训练后的线性回归预测要差得多。

import torch
from torch import Tensor
from torch.nn import Linear, MSELoss, functional as F
from torch.optim import SGD, Adam, RMSprop
from torch.autograd import Variable
import numpy as np


# define our data generation function
def data_generator(data_size=1000):
    # f(x) = y = x^2 + 4x - 3
    inputs = []
    labels = []

    # loop data_size times to generate the data
    for ix in range(data_size):
        # generate a random number between 0 and 1000
        x = np.random.randint(1000) / 1000

        # calculate the y value using the function x^2 + 4x - 3
        y = (x * x) + (4 * x) - 3

        # append the values to our input and labels lists
        inputs.append([x])
        labels.append([y])

    return inputs, labels


# define the model
class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = Linear(1, 100)
        self.fc2 = Linear(100, 1)


    def forward(self, x):
        x = F.relu(self.fc1(x)
        x = self.fc2(x)
        return x


model = Net()
# define the loss function
critereon = MSELoss()
# define the optimizer
optimizer = SGD(model.parameters(), lr=0.01)

# define the number of epochs and the data set size
nb_epochs = 20000
data_size = 1000

# create our training loop
for epoch in range(nb_epochs):
    X, y = data_generator(data_size)
    X = Variable(Tensor(X))
    y = Variable(Tensor(y))


    epoch_loss = 0;


    y_pred = model(X)

    loss = critereon(y_pred, y)

    epoch_loss = loss.data
    optimizer.zero_grad()

    loss.backward()

    optimizer.step()

    print("Epoch: {} Loss: {}".format(epoch, epoch_loss))

# test the model
model.eval()
test_data = data_generator(1)
prediction = model(Variable(Tensor(test_data[0][0])))
print("Prediction: {}".format(prediction.data[0]))
print("Expected: {}".format(test_data[1][0]))

Is their a way to get way better results? 他们有办法获得更好的结果吗? I wondered if I should try to get 3 outputs, call them a, b and c, such that y= a(x*x)+b(x)+c. 我想知道是否应该尝试获得3个输出,分别称为a,b和c,以便y = a(x * x)+ b(x)+ c。 But I have no idea how to implement that and train my neural network. 但是我不知道如何实现它并训练我的神经网络。

For this problem, it might be such easier if you consider the Net() with 1 Linear layer as Linear Regression with inputs features including [x^2, x] . 对于此问题,如果将具有1个Linear层的Net()视为具有[x^2, x]输入Linear Regression ,则可能会更容易。

Generate your data 产生您的资料

import torch
from torch import Tensor
from torch.nn import Linear, MSELoss, functional as F
from torch.optim import SGD, Adam, RMSprop
from torch.autograd import Variable
import numpy as np

# define our data generation function
def data_generator(data_size=1000):
    # f(x) = y = x^2 + 4x - 3
    inputs = []
    labels = []

    # loop data_size times to generate the data
    for ix in range(data_size):
        # generate a random number between 0 and 1000
        x = np.random.randint(2000) / 1000 # I edited here for you

        # calculate the y value using the function x^2 + 4x - 3
        y = (x * x) + (4 * x) - 3

        # append the values to our input and labels lists
        inputs.append([x*x, x])
        labels.append([y])

    return inputs, labels

Define your model 定义你的模型

# define the model
class Net(torch.nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = Linear(2, 1)

    def forward(self, x):
        return self.fc1(x)

model = Net()

Then train it we get: 然后训练它,我们得到:

Epoch: 0 Loss: 33.75775909423828
Epoch: 1000 Loss: 0.00046704441774636507
Epoch: 2000 Loss: 9.437128483114066e-07
Epoch: 3000 Loss: 2.0870876138445738e-09
Epoch: 4000 Loss: 1.126847400112485e-11
Prediction: 5.355223655700684
Expected: [5.355224999999999]

The coeffients 系数

The coefficients a , b , c you are looking for are actually the weight and bias of the self.fc1 : 您要查找的系数abc实际上是self.fc1的权重和偏差。

print('a & b:', model.fc1.weight)
print('c:', model.fc1.bias)

# Output
a & b: Parameter containing:
tensor([[1.0000, 4.0000]], requires_grad=True)
c: Parameter containing:
tensor([-3.0000], requires_grad=True)

In only 5000 epochs, all converges: a -> 1, b -> 4, and c -> -3. 在只有5000时期,所有收敛: a - > 1, b - >如图4所示,和c - > -3。

The model is such a light-weight with only 3 parameters instead of: 该模型非常轻巧,仅包含3个参数,而不是:

(100 + 1) + (100 + 1) = 202 parameters in the old model

Hope this helps you! 希望这对您有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM