Implementation of a Neural Network
Implement a neural network for binary classification in PyTorch.
Let’s implement a simple neural network example using a popular framework, torch
.
Introduction to PyTorch
PyTorch is an open-source deep learning framework, quite popular among researchers, developers, and data scientists due to its simplicity, flexibility, and efficiency in building and training deep neural networks. It’s developed and maintained by Facebook’s AI Research Lab (FAIR). PyTorch provides an intuitive and Pythonic interface that enables users to easily construct complex computational graphs for deep learning models.
Binary classification for numerical dataset
An example of implementing a simple neural network using PyTorch is given below. In this example, we’ll create a neural network with one hidden layer for a binary classification task. We’ll use the famous Iris dataset and aim to classify whether a given flower belongs to the Iris setosa species or not.
Note: The slight variation in the plots, each time the code is run, can be attributed to the random initialization of the neural network weights and biases, as well as the randomness introduced during the train-test split. This can lead to different initial conditions and data splits, that result in slightly different training trajectories and test performance.
import torchimport torch.nn as nnimport torch.optim as optimfrom sklearn.datasets import load_irisfrom sklearn.model_selection import train_test_splitfrom sklearn.preprocessing import StandardScalerimport matplotlib.pyplot as plt# Load Iris datasetdata = load_iris()X, y = data.data, data.targetX = X[y != 2] # Consider only two classes: Iris Setosa (0) and Iris Versicolor (1)y = y[y != 2]# Split data into training and testing setsX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)# Normalize featuresscaler = StandardScaler()X_train = scaler.fit_transform(X_train)X_test = scaler.transform(X_test)# Convert NumPy arrays to PyTorch tensorsX_train = torch.tensor(X_train, dtype=torch.float32)y_train = torch.tensor(y_train, dtype=torch.float32)X_test = torch.tensor(X_test, dtype=torch.float32)y_test = torch.tensor(y_test, dtype=torch.float32)# Define the simple neural network modelclass SimpleNeuralNetwork(nn.Module):def __init__(self, input_size, hidden_size, output_size):super(SimpleNeuralNetwork, self).__init__()self.fc1 = nn.Linear(input_size, hidden_size)self.relu = nn.ReLU()self.fc2 = nn.Linear(hidden_size, output_size)self.sigmoid = nn.Sigmoid()def forward(self, x):out = self.fc1(x)out = self.relu(out)out = self.fc2(out)out = self.sigmoid(out)return out# Set the model parametersinput_size = X_train.shape[1]hidden_size = 5output_size = 1# Initialize the modelmodel = SimpleNeuralNetwork(input_size, hidden_size, output_size)# Define the loss function and optimizercriterion = nn.BCELoss() # Binary Cross Entropy Lossoptimizer = optim.SGD(model.parameters(), lr=0.01)# Lists to store training and test lossestrain_losses = []test_losses = []train_accuracies = []test_accuracies = []# Training the modelnum_epochs = 1000for epoch in range(num_epochs):# Forward passoutputs = model(X_train)loss = criterion(outputs, y_train.view(-1, 1))# Backward and optimizeoptimizer.zero_grad()loss.backward()optimizer.step()if (epoch + 1) % 100 == 0:print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')train_losses.append(loss.item())# Compute training accuracypredicted_train = (outputs >= 0.5).squeeze().float()train_accuracy = (predicted_train == y_train).sum().item() / y_train.size(0)train_accuracies.append(train_accuracy)# Evaluate the model on the test setwith torch.no_grad():model.eval()test_outputs = model(X_test)test_loss = criterion(test_outputs, y_test.view(-1, 1))test_losses.append(test_loss.item())# Compute test accuracypredicted_test = (test_outputs >= 0.5).squeeze().float()test_accuracy = (predicted_test == y_test).sum().item() / y_test.size(0)test_accuracies.append(test_accuracy)# Plot the training and test loss curvesplt.figure(figsize=(12, 5))plt.subplot(1, 2, 1)plt.plot(range(1, num_epochs+1), train_losses, label='Training Loss', color='blue')plt.plot(range(1, num_epochs+1), test_losses, label='Test Loss', color='orange')plt.xlabel('Epochs')plt.ylabel('Loss')plt.legend()plt.grid(True)plt.title('Training and Test Loss Curves')# Plot the training and test accuracy curvesplt.subplot(1, 2, 2)plt.plot(range(1, num_epochs+1), train_accuracies, label='Training Accuracy', color='blue')plt.plot(range(1, num_epochs+1), test_accuracies, label='Test Accuracy', color='orange')plt.xlabel('Epochs')plt.ylabel('Accuracy')plt.legend()plt.grid(True)plt.title('Training and Test Accuracy Curves')# Evaluate the model on the test setwith torch.no_grad():model.eval()test_outputs = model(X_test)predicted = (test_outputs >= 0.5).squeeze().float()accuracy = (predicted == y_test).sum().item() / y_test.size(0)print(f'Test Accuracy: {accuracy:.2f}')
Here is the explanation for the code above:
-
Lines 1–6: We import necessary libraries such as
torch
,nn
,optim
,load_iris
,train_test_split
, andStandardScaler
for data preprocessing. We also usematplotlib.pyplot
to visualize the insights. -
Lines 10–27: Data preprocessing involves loading the Iris dataset, filtering it for classes
0
and1
, splitting it into training and test sets, and converting it to PyTorch tensors. -
Lines 30–47: We define the
SimpleNeuralNetwork
neural network with two layers: one with a ReLU activation function and the other with a sigmoid activation function. -
Lines 50–61: We configure by setting model parameters like
input_size
,hidden_size
, andoutput_size
, and create the neural network instancemodel
. -
Lines 64–69: We define the loss function as BCE loss (
nn.BCELoss()
) and choose the optimization method as Stochastic Gradient ...