What is Pytorch?
PyTorch is an open-source machine learning framework that lets you build models for applications such as computer vision and natural language processing
How to install Pytorch
Pytorch can be installed using pip via the command pip install torch
or if you would like torch to utilize your GPU, you can follow the installation guide from Pytorch over here. To discover what CUDA version your GPU is utilizing, you can open the terminal (on windows) and use the command nvidia-smi
and look at the version and choose that version at the Pytorch installation guide.
Tensors
The fundamental data type in pytorch is a tensor, it can be considered as a data type similar to numpy arrays. A list of values can be converted into a tensor by using torch.tensor(list_of_values)
, as shown below
list1 = [1,2,3]
list2 = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
tensor1 = torch.tensor(list1)
print(tensor1)
"""
Output:
tensor([1, 2, 3])
"""
tensor2 = torch.tensor(list2)
print(tensor2)
"""
Output:
tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
"""
You can perform mathematical operations on tensors as you do for numpy for example
tensor1 * tensor2
"""
tensor([[ 1, 4, 9],
[ 4, 10, 18],
[ 7, 16, 27]])
"""
tensor1 + tensor2
"""
tensor([[ 2, 4, 6],
[ 5, 7, 9],
[ 8, 10, 12]])
"""
Dataset and DataLoader
Dataset allows you to establish how your data is loaded via __len__
and __getItem__
. It prevents your entire data from being loaded, by loading them in samples.
DataLoader groups single samples into batches for efficient computation on the GPU, as well as it supports parallel data loading, shuffling and sampling.
To utilise the Dataset and Dataloader we import these functions from torch.utils.data
. Here is an example of creating a custom Dataset and DataLoader.
class DATA:
def __init__(self,x,y):
self.x = torch.tensor(x)
self.y = torch.tensor(y)
def __len__(self):
return len(self.x)
def __getitem__(self, index):
return self.x[index], self.y[index]
x = [[1,2,3],
[4,5,6],
[7,8,9]]
Y = [1,2,3]
dataset = DATA(x,Y)
loader = DataLoader(dataset, batch_size=2, shuffle=True)
for batch_inputs, batch_targets in loader:
print(f"Inputs: {batch_inputs}, Targets: {batch_targets}")
"""
Output
Inputs: tensor([[7, 8, 9],
[1, 2, 3]]), Targets: tensor([3, 1])
Inputs: tensor([[4, 5, 6]]), Targets: tensor([2])
"""
Neural Networks
Neural networks in PyTorch are built using the torch.nn
module. Each model inherits from nn.Module
and defines two main parts:
- Layers: defined in
__init__()
- Forward pass: defined in
forward()
- Backward pass: define in
backward()
class ANN(nn.Module):
def __init__(self):
super().__init__() # Uses the base Neural Network constructor from nn.Module
self.layer1 = nn.Linear(3, 5) # Creates the first layer: input of size 3, output of size 5
self.layer2 = nn.Linear(5, 1) # Creates the second layer: input of size 5, output of size 1
self.optimizer = torch.optim.SGD(self.parameters(), lr=0.01) # Defines the optimizer (Stochastic Gradient Descent) with learning rate 0.01
self.loss_fn = nn.BCELoss() # Defines the loss function (Binary Cross Entropy Loss) for binary classification
def forward(self, x):
# Defines how data flows through the network:
x = self.layer1(x) # Pass input through first layer (3 → 5)
x = torch.relu(x) # Apply ReLU activation to introduce non-linearity
x = self.layer2(x) # Pass through second layer (5 → 1)
x = torch.sigmoid(x) # Apply Sigmoid activation to output probabilities between 0 and 1
return x # Return final prediction
def backward(self, loss):
# Defines the backward propagation step:
self.optimizer.zero_grad() # Clears previously stored gradients
loss.backward() # Computes gradients using backpropagation
self.optimizer.step() # Updates model parameters (weights and biases)
Code implementation
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
class DATA:
def __init__(self,x,y):
self.x = torch.tensor(x)
self.y = torch.tensor(y)
def __len__(self):
return len(self.x)
def __getitem__(self, index):
return self.x[index], self.y[index]
# Define your ANN class
class ANN(nn.Module):
def __init__(self):
super().__init__()
self.layer1 = nn.Linear(3, 5)
self.layer2 = nn.Linear(5, 1)
self.optimizer = torch.optim.SGD(self.parameters(), lr=0.01)
self.loss_fn = nn.BCELoss()
def forward(self, x):
x = self.layer1(x)
x = torch.relu(x)
x = self.layer2(x)
x = torch.sigmoid(x)
return x
def backward(self, loss):
self.optimizer.zero_grad()
loss.backward()
self.optimizer.step()
torch.manual_seed(42)
X = torch.randn(100, 3)
y = (X.sum(dim=1) > 0).float().unsqueeze(1)
dataset = DATA(X,y)
loader = DataLoader(dataset, batch_size=2, shuffle=True)
model = ANN()
epochs = 50
for epoch in range(epochs):
total_loss = 0
correct = 0
total = 0
for batch_X, batch_y in loader:
y_pred = model(batch_X)
loss = model.loss_fn(y_pred, batch_y)
model.backward(loss)
total_loss += loss.item()
predicted = (y_pred >= 0.5).float()
correct += (predicted == batch_y).sum().item()
total += batch_y.size(0)
accuracy = correct / total
if (epoch + 1) % 10 == 0:
print(f"Epoch [{epoch+1}/{epochs}], Loss: {total_loss/len(loader):.4f}, Accuracy: {accuracy:.4f}")
Top comments (0)