1

I have been given a task to approximate the function 5x^3 - 10x^2 - 5x - 9 using a neural network in pytorch. The training data is the set of integers in the range [-100,100] and I have to test the trained model against a non-integer value. For the same, I have used a neural network with some layers and activation functions and I have also used Batch Normalization. However, the approximated function is far off from the actual function and gives extremely poor results.chart

Given below is the code

import torch
import torch.nn as nn
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt

Define the polynomial function f(x) = 5x^3 - 10x^2 - 5x + 9

def polynomial_function(x): return 5x3 - 10x*2 - 5x + 9

Generate training data for integers in the range [-100, 100]

x_train = np.arange(-100, 101, dtype=np.float32) y_train = polynomial_function(x_train)

Define an improved neural network

class PolynomialApproximator(nn.Module): def init(self): super(PolynomialApproximator, self).init() self.fc1 = nn.Linear(1, 128) self.relu1 = nn.ReLU() self.fc2 = nn.Linear(128, 64) self.relu2 = nn.ReLU() self.fc3 = nn.Linear(64, 1) self.bn1 = nn.BatchNorm1d(128) self.bn2 = nn.BatchNorm1d(64) self.dropout1 = nn.Dropout(0.2) self.dropout2 = nn.Dropout(0.2)

def forward(self, x):
    x = self.fc1(x)
    x = self.bn1(x)
    x = self.relu1(x)
    x = self.dropout1(x)
    x = self.fc2(x)
    x = self.bn2(x)
    x = self.relu2(x)
    x = self.dropout2(x)
    x = self.fc3(x)
    return x

Instantiate the improved model, MAE loss function, and optimizer

model = PolynomialApproximator() criterion = nn.L1Loss() # Mean Absolute Error (MAE) loss optimizer = optim.Adam(model.parameters(), lr=0.001) # Use Adam optimizer for better convergence scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=500, gamma=0.5) # Learning rate scheduler

Training loop

num_epochs = 10000

for epoch in range(num_epochs): model.train()

inputs = torch.from_numpy(x_train.reshape(-1, 1))
targets = torch.from_numpy(y_train.reshape(-1, 1))

optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, targets)
loss.backward()
optimizer.step()
scheduler.step()

if (epoch + 1) % 100 == 0:
    model.eval()
    with torch.no_grad():
        # Calculate MAE for printing accuracy
        mae = torch.mean(torch.abs(outputs - targets))

    print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}, MAE: {mae.item():.4f}')

Evaluate the trained model on a non-integer input

x_test = torch.tensor([[90.5]]) y_test_pred = model(x_test).item()

Compare the function output vs. the NN output

print(f"Polynomial function output at x=78.6: {polynomial_function(90.5)}") print(f"NN output at x=78.6: {y_test_pred}")

Plot the original function and the trained neural network

x_plot = np.linspace(-100, 100, 1000) y_plot_original = polynomial_function(x_plot) y_plot_approximated = model(torch.from_numpy(x_plot.reshape(-1, 1)).float()).detach().numpy()

y_plot_approximated = y_plot_approximated-min(y_plot_approximated)/(max(y_plot_approximated)- min(y_plot_approximated))

y_plot_original = y_plot_original-min(y_plot_original)/(max(y_plot_original)- min(y_plot_original))

x_mean, x_std = y_plot_original.mean(), y_plot_original.std() y_mean, y_std = y_plot_approximated.mean(), y_plot_approximated.std()

y_plot_original = (y_plot_original - x_mean) / x_std y_plot_approximated = (y_plot_approximated - y_mean) / y_std

plt.figure(figsize=(10, 6)) plt.plot(x_plot, y_plot_original, color='pink', label='Original Function', linewidth=2) plt.plot(x_plot, y_plot_approximated, label='NN Approximation', linewidth=2)

plt.scatter(x_test.item(), y_test_pred, color='blue', marker='x', label='Test Point (x=78.6)')

plt.legend() plt.title('Improved Function Approximation using Neural Network') plt.xlabel('x') plt.ylabel('y') plt.grid(True) plt.show()

here is the output

What am I doing wrong ?

Paarth
  • 11
  • 1

0 Answers0