0% found this document useful (0 votes)
4 views

Lab 9

The document outlines a machine learning project for vehicle type recognition using three different neural network architectures: AlexNet, VGG16, and LeNet. It includes steps for dataset preparation, model training, and evaluation, reporting accuracy, precision, recall, and F1-score for each model. The results indicate varying performance, with AlexNet achieving 22.50% accuracy, VGG16 at 26.67%, and LeNet's performance is yet to be fully summarized.

Uploaded by

sadianazim395
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

Lab 9

The document outlines a machine learning project for vehicle type recognition using three different neural network architectures: AlexNet, VGG16, and LeNet. It includes steps for dataset preparation, model training, and evaluation, reporting accuracy, precision, recall, and F1-score for each model. The results indicate varying performance, with AlexNet achieving 22.50% accuracy, VGG16 at 26.67%, and LeNet's performance is yet to be fully summarized.

Uploaded by

sadianazim395
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

Name:Muhammad Hermen Khan

Enroll:01-136221-054

BS-AI-6A

Dataset Link:https://www.kaggle.com/datasets/kaggleashwin/vehicle-type-recognition/data

!unzip /content/vehicles.zip -d /content/final

from sklearn.metrics import precision_recall_fscore_support,


accuracy_score
import numpy as np

from torch.utils.data import DataLoader, random_split


from torchvision import transforms, datasets
from torchvision import models
from torch import nn, optim
import torch

# Step 1: Dataset Preparation


# Dataset path
data_dir = r"/content/final/Dataset" # Update this to your dataset
path

# Define transformations
transform = transforms.Compose([
transforms.Resize((224, 224)), # Standard input size for most
models
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229,
0.224, 0.225])
])

# Load complete dataset


dataset = datasets.ImageFolder(data_dir, transform=transform)

# Split dataset into training (70%) and testing (30%)


train_size = int(0.7 * len(dataset))
test_size = len(dataset) - train_size
train_dataset, test_dataset = random_split(dataset, [train_size,
test_size])

# Create DataLoaders
batch_size = 32
train_loader = DataLoader(train_dataset, batch_size=batch_size,
shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size,
shuffle=False)

# Number of classes
num_classes = len(dataset.classes)
print(f"Number of classes: {num_classes}")
print(f"Classes: {dataset.classes}")

# Step 2: AlexNet Model


# Initialize the device
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")

# Updated evaluation function to include precision, recall, F1-score


def train_and_evaluate_AlexNet(train_loader, test_loader, num_classes,
epochs=5):
# Load pretrained AlexNet model
model = models.alexnet(pretrained=True).to(device)

# Modify the classifier for the number of classes in the dataset


model.classifier[6] = nn.Linear(model.classifier[6].in_features,
num_classes).to(device)

# Define loss function and optimizer


criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Training loop
for epoch in range(epochs):
model.train()
running_loss = 0.0
for inputs, labels in train_loader:
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f"Epoch {epoch+1}/{epochs} - Loss:
{running_loss/len(train_loader):.4f}")

# Evaluation
model.eval()
all_preds = []
all_labels = []
with torch.no_grad():
for inputs, labels in test_loader:
inputs, labels = inputs.to(device), labels.to(device)
outputs = model(inputs)
_, preds = torch.max(outputs, 1)
all_preds.extend(preds.cpu().numpy())
all_labels.extend(labels.cpu().numpy())
# Calculate metrics
all_preds = np.array(all_preds)
all_labels = np.array(all_labels)

accuracy = accuracy_score(all_labels, all_preds) * 100


precision, recall, f1, _ =
precision_recall_fscore_support(all_labels, all_preds,
average='weighted')

print(f"AlexNet Accuracy on Test Set: {accuracy:.2f}%")


print(f"Precision: {precision:.4f}")
print(f"Recall: {recall:.4f}")
print(f"F1-Score: {f1:.4f}")

# Call the function


train_and_evaluate_AlexNet(train_loader, test_loader, num_classes,
epochs=5)

Number of classes: 4
Classes: ['Bus', 'Car', 'Truck', 'motorcycle']
Using device: cuda

/usr/local/lib/python3.10/dist-packages/torchvision/models/
_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated
since 0.13 and may be removed in the future, please use 'weights'
instead.
warnings.warn(
/usr/local/lib/python3.10/dist-packages/torchvision/models/_utils.py:2
23: UserWarning: Arguments other than a weight enum or `None` for
'weights' are deprecated since 0.13 and may be removed in the future.
The current behavior is equivalent to passing
`weights=AlexNet_Weights.IMAGENET1K_V1`. You can also use
`weights=AlexNet_Weights.DEFAULT` to get the most up-to-date weights.
warnings.warn(msg)
Downloading: "https://download.pytorch.org/models/alexnet-owt-
7be5be79.pth" to /root/.cache/torch/hub/checkpoints/alexnet-owt-
7be5be79.pth
100%|██████████| 233M/233M [00:01<00:00, 150MB/s]
/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Epoch 1/5 - Loss: 1.6853


Epoch 2/5 - Loss: 1.3936
Epoch 3/5 - Loss: 1.3958
Epoch 4/5 - Loss: 1.3907
Epoch 5/5 - Loss: 1.3893
AlexNet Accuracy on Test Set: 22.50%
Precision: 0.0506
Recall: 0.2250
F1-Score: 0.0827

/usr/local/lib/python3.10/dist-packages/sklearn/metrics/
_classification.py:1531: UndefinedMetricWarning: Precision is ill-
defined and being set to 0.0 in labels with no predicted samples. Use
`zero_division` parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is",
len(result))

from torchvision import models


from torch import nn, optim
import torch
from tqdm import tqdm
from sklearn.metrics import precision_recall_fscore_support,
accuracy_score
import numpy as np

# Define the device


device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")

# Training and evaluation function for VGG16


def train_and_evaluate_VGG16(train_loader, test_loader, num_classes,
epochs=5):
# Load the pretrained VGG16 model
model = models.vgg16(pretrained=True).to(device)

# Modify the classifier to match the number of classes in the


dataset
model.classifier[6] = nn.Linear(model.classifier[6].in_features,
num_classes).to(device)

# Define the loss function and optimizer


criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Training loop
for epoch in range(epochs):
model.train()
running_loss = 0.0
for inputs, labels in tqdm(train_loader, desc=f"Epoch
{epoch+1}/{epochs}"):
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()

print(f"Epoch {epoch+1}/{epochs} - Loss:


{running_loss/len(train_loader):.4f}")

# Evaluation
model.eval()
all_preds = []
all_labels = []
with torch.no_grad():
for inputs, labels in test_loader:
inputs, labels = inputs.to(device), labels.to(device)
outputs = model(inputs)
_, preds = torch.max(outputs, 1)
all_preds.extend(preds.cpu().numpy())
all_labels.extend(labels.cpu().numpy())

# Calculate metrics
all_preds = np.array(all_preds)
all_labels = np.array(all_labels)

accuracy = accuracy_score(all_labels, all_preds) * 100


precision, recall, f1, _ =
precision_recall_fscore_support(all_labels, all_preds,
average='weighted')

print(f"VGG16 Accuracy on Test Set: {accuracy:.2f}%")


print(f"Precision: {precision:.4f}")
print(f"Recall: {recall:.4f}")
print(f"F1-Score: {f1:.4f}")

# Call the function


# Ensure train_loader, test_loader, and num_classes are already
defined
train_and_evaluate_VGG16(train_loader, test_loader, num_classes,
epochs=5)

Using device: cuda

/usr/local/lib/python3.10/dist-packages/torchvision/models/
_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated
since 0.13 and may be removed in the future, please use 'weights'
instead.
warnings.warn(
/usr/local/lib/python3.10/dist-packages/torchvision/models/_utils.py:2
23: UserWarning: Arguments other than a weight enum or `None` for
'weights' are deprecated since 0.13 and may be removed in the future.
The current behavior is equivalent to passing
`weights=VGG16_Weights.IMAGENET1K_V1`. You can also use
`weights=VGG16_Weights.DEFAULT` to get the most up-to-date weights.
warnings.warn(msg)
Downloading: "https://download.pytorch.org/models/vgg16-397923af.pth"
to /root/.cache/torch/hub/checkpoints/vgg16-397923af.pth
100%|██████████| 528M/528M [00:03<00:00, 157MB/s]
Epoch 1/5: 67%|██████▋ | 6/9 [00:10<00:05,
1.72s/it]/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(
Epoch 1/5: 100%|██████████| 9/9 [00:14<00:00, 1.56s/it]

Epoch 1/5 - Loss: 3.5817

Epoch 2/5: 100%|██████████| 9/9 [00:13<00:00, 1.47s/it]

Epoch 2/5 - Loss: 1.4097

Epoch 3/5: 100%|██████████| 9/9 [00:12<00:00, 1.44s/it]

Epoch 3/5 - Loss: 1.4017

Epoch 4/5: 100%|██████████| 9/9 [00:13<00:00, 1.46s/it]

Epoch 4/5 - Loss: 1.4482

Epoch 5/5: 100%|██████████| 9/9 [00:13<00:00, 1.47s/it]

Epoch 5/5 - Loss: 1.3835


VGG16 Accuracy on Test Set: 26.67%
Precision: 0.1221
Recall: 0.2667
F1-Score: 0.1671

/usr/local/lib/python3.10/dist-packages/sklearn/metrics/
_classification.py:1531: UndefinedMetricWarning: Precision is ill-
defined and being set to 0.0 in labels with no predicted samples. Use
`zero_division` parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is",
len(result))

import torch
from torch import nn, optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader, random_split
from tqdm import tqdm
from sklearn.metrics import precision_recall_fscore_support,
accuracy_score
import numpy as np

# Define the LeNet model


class LeNet(nn.Module):
def __init__(self, num_classes):
super(LeNet, self).__init__()
self.conv1 = nn.Conv2d(3, 6, kernel_size=5) # 3 input
channels (RGB)
self.conv2 = nn.Conv2d(6, 16, kernel_size=5)
self.fc1 = nn.Linear(16 * 53 * 53, 120) # Adjust input size
for your dataset
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, num_classes)

def forward(self, x):


x = torch.relu(self.conv1(x))
x = torch.max_pool2d(x, kernel_size=2, stride=2)
x = torch.relu(self.conv2(x))
x = torch.max_pool2d(x, kernel_size=2, stride=2)
x = x.view(x.size(0), -1) # Flatten for fully connected
layers
x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
x = self.fc3(x)
return x

# Define the device


device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")

# Define the training and evaluation function


def train_and_evaluate_LeNet(train_loader, test_loader, num_classes,
epochs=5):
# Initialize the LeNet model
model = LeNet(num_classes).to(device)

# Define the loss function and optimizer


criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Training loop
for epoch in range(epochs):
model.train()
running_loss = 0.0
for inputs, labels in tqdm(train_loader, desc=f"Epoch
{epoch+1}/{epochs}"):
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
print(f"Epoch {epoch+1}/{epochs} - Loss:
{running_loss/len(train_loader):.4f}")
# Evaluation
model.eval()
all_preds = []
all_labels = []
with torch.no_grad():
for inputs, labels in test_loader:
inputs, labels = inputs.to(device), labels.to(device)
outputs = model(inputs)
_, preds = torch.max(outputs, 1)
all_preds.extend(preds.cpu().numpy())
all_labels.extend(labels.cpu().numpy())

# Calculate metrics
all_preds = np.array(all_preds)
all_labels = np.array(all_labels)

accuracy = accuracy_score(all_labels, all_preds) * 100


precision, recall, f1, _ =
precision_recall_fscore_support(all_labels, all_preds,
average='weighted')

print(f"LeNet Accuracy on Test Set: {accuracy:.2f}%")


print(f"Precision: {precision:.4f}")
print(f"Recall: {recall:.4f}")
print(f"F1-Score: {f1:.4f}")

# Dataset Preparation
data_dir = r"/content/final/Dataset" # Update with your dataset path
transform = transforms.Compose([
transforms.Resize((224, 224)), # Resize for LeNet input
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229,
0.224, 0.225])
])

dataset = datasets.ImageFolder(data_dir, transform=transform)

# Split into training and testing sets


train_size = int(0.7 * len(dataset))
test_size = len(dataset) - train_size
train_dataset, test_dataset = random_split(dataset, [train_size,
test_size])

# Create DataLoaders
batch_size = 32
train_loader = DataLoader(train_dataset, batch_size=batch_size,
shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size,
shuffle=False)
# Number of classes
num_classes = len(dataset.classes)
print(f"Number of classes: {num_classes}")
print(f"Classes: {dataset.classes}")

# Train and evaluate LeNet


train_and_evaluate_LeNet(train_loader, test_loader, num_classes,
epochs=5)

Using device: cuda


Number of classes: 4
Classes: ['Bus', 'Car', 'Truck', 'motorcycle']

Epoch 1/5: 22%|██▏ | 2/9 [00:01<00:03,


1.75it/s]/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(
Epoch 1/5: 100%|██████████| 9/9 [00:08<00:00, 1.06it/s]

Epoch 1/5 - Loss: 1.3808

Epoch 2/5: 100%|██████████| 9/9 [00:09<00:00, 1.04s/it]

Epoch 2/5 - Loss: 1.0704

Epoch 3/5: 100%|██████████| 9/9 [00:10<00:00, 1.16s/it]

Epoch 3/5 - Loss: 0.7165

Epoch 4/5: 100%|██████████| 9/9 [00:09<00:00, 1.04s/it]

Epoch 4/5 - Loss: 0.5021

Epoch 5/5: 100%|██████████| 9/9 [00:08<00:00, 1.11it/s]

Epoch 5/5 - Loss: 0.2552


LeNet Accuracy on Test Set: 54.17%
Precision: 0.5266
Recall: 0.5417
F1-Score: 0.5285

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, random_split
from torchvision import datasets, transforms
from torch.autograd import Variable
from tqdm import tqdm
import os
from PIL import Image
# 1. ZFNet Model Definition
class ZFNet(nn.Module):
def __init__(self, num_classes):
super(ZFNet, self).__init__()
# Convolutional Layers
self.conv1 = nn.Conv2d(3, 96, kernel_size=7, stride=2,
padding=1) # Output: 96 x 111 x 111
self.conv2 = nn.Conv2d(96, 256, kernel_size=5, stride=2,
padding=1) # Output: 256 x 27 x 27
self.conv3 = nn.Conv2d(256, 384, kernel_size=3, padding=1) #
Output: 384 x 13 x 13
self.conv4 = nn.Conv2d(384, 384, kernel_size=3, padding=1) #
Output: 384 x 13 x 13
self.conv5 = nn.Conv2d(384, 256, kernel_size=3, padding=1) #
Output: 256 x 6 x 6

# Pooling Layer
self.pool = nn.MaxPool2d(kernel_size=3, stride=2)

# Placeholder for flattened size


self._to_linear = None

# Fully Connected Layers


self.fc1 = None
self.fc2 = nn.Linear(4096, 4096)
self.fc3 = nn.Linear(4096, num_classes)

def forward(self, x):


# Pass through convolutional layers
x = torch.relu(self.conv1(x))
x = self.pool(x)
x = torch.relu(self.conv2(x))
x = self.pool(x)
x = torch.relu(self.conv3(x))
x = torch.relu(self.conv4(x))
x = torch.relu(self.conv5(x))
x = self.pool(x)

# Dynamically set the size of fc1


if self._to_linear is None:
self._to_linear = x.view(x.size(0), -1).size(1)
self.fc1 = nn.Linear(self._to_linear, 4096).to(x.device)
# Initialize fc1 dynamically

# Flatten the tensor


x = x.view(x.size(0), -1)

# Pass through fully connected layers


x = torch.relu(self.fc1(x))
x = torch.relu(self.fc2(x))
x = self.fc3(x)
return x

# 2. Dataset Preparation with Random Split


data_transforms = transforms.Compose([
transforms.Resize((224, 224)), # Resize images to 224x224
transforms.RandomHorizontalFlip(), # Augmentation: Flip images
randomly
transforms.ToTensor(), # Convert images to tensor
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229,
0.224, 0.225]) # Normalize to ImageNet stats
])

# Path to your dataset folder (with subfolders like Bus, Car, etc.)
data_dir = '/content/final/Dataset' # Change this path to your
dataset directory

# Load dataset using ImageFolder


dataset = datasets.ImageFolder(data_dir, transform=data_transforms)

# Calculate the size for train/val split (80% train, 20% validation)
train_size = int(0.8 * len(dataset))
val_size = len(dataset) - train_size

# Split the dataset into train and validation sets


train_dataset, val_dataset = random_split(dataset, [train_size,
val_size])

# DataLoaders for batch processing


train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False)

# 3. Initialize the Model, Loss, and Optimizer


num_classes = len(dataset.classes) # Number of classes (e.g., 4
classes: Bus, Car, Motorcycle, Truck)
model = ZFNet(num_classes=num_classes)

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")


model = model.to(device)

# Loss and Optimizer


criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

from sklearn.metrics import precision_recall_fscore_support,


accuracy_score
import numpy as np
# 4. Training the Model with Metrics Calculation
def train_model_with_metrics(model, criterion, optimizer,
num_epochs=25):
best_model_wts = model.state_dict()
best_acc = 0.0

for epoch in range(num_epochs):


print(f'Epoch {epoch}/{num_epochs - 1}')
print('-' * 10)

# Training phase
model.train()
running_loss = 0.0
running_corrects = 0

for inputs, labels in tqdm(train_loader):


inputs, labels = inputs.to(device), labels.to(device)

optimizer.zero_grad()

# Forward
outputs = model(inputs)
loss = criterion(outputs, labels)

# Backward
loss.backward()
optimizer.step()

# Statistics
_, preds = torch.max(outputs, 1)
running_loss += loss.item() * inputs.size(0)
running_corrects += torch.sum(preds == labels.data)

epoch_loss = running_loss / len(train_loader.dataset)


epoch_acc = running_corrects.double() /
len(train_loader.dataset)

print(f'Train Loss: {epoch_loss:.4f} Acc: {epoch_acc:.4f}')

# Validation phase
model.eval()
running_corrects = 0
all_preds = []
all_labels = []

for inputs, labels in val_loader:


inputs, labels = inputs.to(device), labels.to(device)

with torch.no_grad():
outputs = model(inputs)
_, preds = torch.max(outputs, 1)

# Store predictions and labels for metrics


all_preds.extend(preds.cpu().numpy())
all_labels.extend(labels.cpu().numpy())

running_corrects += torch.sum(preds == labels.data)

# Calculate metrics
all_preds = np.array(all_preds)
all_labels = np.array(all_labels)

val_acc = accuracy_score(all_labels, all_preds) * 100


precision, recall, f1, _ =
precision_recall_fscore_support(all_labels, all_preds,
average='weighted')

print(f'Validation Accuracy: {val_acc:.2f}%')


print(f'Precision: {precision:.4f}')
print(f'Recall: {recall:.4f}')
print(f'F1-Score: {f1:.4f}')

# Deep copy the model if it's the best so far


if val_acc > best_acc:
best_acc = val_acc
best_model_wts = model.state_dict()

print(f'Best Validation Accuracy: {best_acc:.2f}%')


model.load_state_dict(best_model_wts)
return model

# Train the model


model = train_model_with_metrics(model, criterion, optimizer,
num_epochs=25)

Epoch 0/24
----------

100%|██████████| 10/10 [00:10<00:00, 1.07s/it]

Train Loss: 1.6090 Acc: 0.2406

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/metrics/_classificatio
n.py:1531: UndefinedMetricWarning: Precision is ill-defined and being
set to 0.0 in labels with no predicted samples. Use `zero_division`
parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is",
len(result))

Validation Accuracy: 23.75%


Precision: 0.0963
Recall: 0.2375
F1-Score: 0.1300
Epoch 1/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.00it/s]

Train Loss: 1.3903 Acc: 0.2656

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/metrics/_classificatio
n.py:1531: UndefinedMetricWarning: Precision is ill-defined and being
set to 0.0 in labels with no predicted samples. Use `zero_division`
parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is",
len(result))

Validation Accuracy: 25.00%


Precision: 0.1450
Recall: 0.2500
F1-Score: 0.1197
Epoch 2/24
----------

100%|██████████| 10/10 [00:10<00:00, 1.00s/it]

Train Loss: 1.3892 Acc: 0.2438

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/metrics/_classificatio
n.py:1531: UndefinedMetricWarning: Precision is ill-defined and being
set to 0.0 in labels with no predicted samples. Use `zero_division`
parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is",
len(result))

Validation Accuracy: 23.75%


Precision: 0.0564
Recall: 0.2375
F1-Score: 0.0912
Epoch 3/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.01it/s]

Train Loss: 1.3818 Acc: 0.2563

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/metrics/_classificatio
n.py:1531: UndefinedMetricWarning: Precision is ill-defined and being
set to 0.0 in labels with no predicted samples. Use `zero_division`
parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is",
len(result))

Validation Accuracy: 21.25%


Precision: 0.1092
Recall: 0.2125
F1-Score: 0.1378
Epoch 4/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.01it/s]

Train Loss: 1.4098 Acc: 0.2625

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/metrics/_classificatio
n.py:1531: UndefinedMetricWarning: Precision is ill-defined and being
set to 0.0 in labels with no predicted samples. Use `zero_division`
parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is",
len(result))

Validation Accuracy: 26.25%


Precision: 0.0689
Recall: 0.2625
F1-Score: 0.1092
Epoch 5/24
----------

100%|██████████| 10/10 [00:10<00:00, 1.00s/it]

Train Loss: 1.3906 Acc: 0.2469


/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/metrics/_classificatio
n.py:1531: UndefinedMetricWarning: Precision is ill-defined and being
set to 0.0 in labels with no predicted samples. Use `zero_division`
parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is",
len(result))

Validation Accuracy: 26.25%


Precision: 0.0689
Recall: 0.2625
F1-Score: 0.1092
Epoch 6/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.00it/s]

Train Loss: 1.3880 Acc: 0.2250

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/metrics/_classificatio
n.py:1531: UndefinedMetricWarning: Precision is ill-defined and being
set to 0.0 in labels with no predicted samples. Use `zero_division`
parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is",
len(result))

Validation Accuracy: 23.75%


Precision: 0.0609
Recall: 0.2375
F1-Score: 0.0969
Epoch 7/24
----------

100%|██████████| 10/10 [00:10<00:00, 1.07s/it]

Train Loss: 1.3881 Acc: 0.2281

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/metrics/_classificatio
n.py:1531: UndefinedMetricWarning: Precision is ill-defined and being
set to 0.0 in labels with no predicted samples. Use `zero_division`
parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is",
len(result))

Validation Accuracy: 27.50%


Precision: 0.1543
Recall: 0.2750
F1-Score: 0.1490
Epoch 8/24
----------

100%|██████████| 10/10 [00:10<00:00, 1.01s/it]

Train Loss: 1.3804 Acc: 0.2531

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/metrics/_classificatio
n.py:1531: UndefinedMetricWarning: Precision is ill-defined and being
set to 0.0 in labels with no predicted samples. Use `zero_division`
parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is",
len(result))

Validation Accuracy: 32.50%


Precision: 0.2684
Recall: 0.3250
F1-Score: 0.2655
Epoch 9/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.00it/s]

Train Loss: 1.3446 Acc: 0.2969

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Validation Accuracy: 48.75%


Precision: 0.4777
Recall: 0.4875
F1-Score: 0.4274
Epoch 10/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.01it/s]

Train Loss: 1.2988 Acc: 0.3688


/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/metrics/_classificatio
n.py:1531: UndefinedMetricWarning: Precision is ill-defined and being
set to 0.0 in labels with no predicted samples. Use `zero_division`
parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is",
len(result))

Validation Accuracy: 45.00%


Precision: 0.3597
Recall: 0.4500
F1-Score: 0.3878
Epoch 11/24
----------

100%|██████████| 10/10 [00:10<00:00, 1.01s/it]

Train Loss: 1.2850 Acc: 0.3656

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(
/usr/local/lib/python3.10/dist-packages/sklearn/metrics/_classificatio
n.py:1531: UndefinedMetricWarning: Precision is ill-defined and being
set to 0.0 in labels with no predicted samples. Use `zero_division`
parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is",
len(result))

Validation Accuracy: 42.50%


Precision: 0.3272
Recall: 0.4250
F1-Score: 0.3669
Epoch 12/24
----------

100%|██████████| 10/10 [00:10<00:00, 1.00s/it]

Train Loss: 1.2114 Acc: 0.4625

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Validation Accuracy: 51.25%


Precision: 0.5125
Recall: 0.5125
F1-Score: 0.4668
Epoch 13/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.00it/s]

Train Loss: 1.1532 Acc: 0.4969

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Validation Accuracy: 52.50%


Precision: 0.5232
Recall: 0.5250
F1-Score: 0.4825
Epoch 14/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.00it/s]

Train Loss: 1.0977 Acc: 0.5156

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Validation Accuracy: 47.50%


Precision: 0.5138
Recall: 0.4750
F1-Score: 0.4652
Epoch 15/24
----------

100%|██████████| 10/10 [00:10<00:00, 1.00s/it]

Train Loss: 1.0509 Acc: 0.5344

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Validation Accuracy: 47.50%


Precision: 0.4834
Recall: 0.4750
F1-Score: 0.4201
Epoch 16/24
----------
100%|██████████| 10/10 [00:09<00:00, 1.02it/s]

Train Loss: 1.0008 Acc: 0.6031

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Validation Accuracy: 53.75%


Precision: 0.5349
Recall: 0.5375
F1-Score: 0.5203
Epoch 17/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.01it/s]

Train Loss: 0.9009 Acc: 0.6188

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Validation Accuracy: 57.50%


Precision: 0.6244
Recall: 0.5750
F1-Score: 0.5744
Epoch 18/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.00it/s]

Train Loss: 0.8418 Acc: 0.6375

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Validation Accuracy: 63.75%


Precision: 0.6349
Recall: 0.6375
F1-Score: 0.6345
Epoch 19/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.00it/s]

Train Loss: 0.8674 Acc: 0.6531


/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Validation Accuracy: 57.50%


Precision: 0.6378
Recall: 0.5750
F1-Score: 0.5597
Epoch 20/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.01it/s]

Train Loss: 0.7596 Acc: 0.7125

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Validation Accuracy: 57.50%


Precision: 0.5731
Recall: 0.5750
F1-Score: 0.5650
Epoch 21/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.00it/s]

Train Loss: 0.6961 Acc: 0.7563

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Validation Accuracy: 60.00%


Precision: 0.6005
Recall: 0.6000
F1-Score: 0.5906
Epoch 22/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.01it/s]

Train Loss: 0.6176 Acc: 0.7563

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(
Validation Accuracy: 58.75%
Precision: 0.6079
Recall: 0.5875
F1-Score: 0.5611
Epoch 23/24
----------

100%|██████████| 10/10 [00:10<00:00, 1.00s/it]

Train Loss: 0.6368 Acc: 0.7344

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Validation Accuracy: 62.50%


Precision: 0.6434
Recall: 0.6250
F1-Score: 0.6148
Epoch 24/24
----------

100%|██████████| 10/10 [00:09<00:00, 1.01it/s]

Train Loss: 0.5416 Acc: 0.7938

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Validation Accuracy: 66.25%


Precision: 0.6651
Recall: 0.6625
F1-Score: 0.6517
Best Validation Accuracy: 66.25%

import torch
from torch import nn, optim
from torchvision import datasets, transforms, models
from torch.utils.data import DataLoader, random_split
from tqdm import tqdm

# Dataset path
data_dir = r"/content/final/Dataset" # Update with your dataset path

# Define transformations (ResNet requires specific normalization)


transform = transforms.Compose([
transforms.Resize((224, 224)), # Resize for ResNet input
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229,
0.224, 0.225])
])

# Load dataset
dataset = datasets.ImageFolder(data_dir, transform=transform)

# Split dataset into training (70%) and testing (30%)


train_size = int(0.7 * len(dataset))
test_size = len(dataset) - train_size
train_dataset, test_dataset = random_split(dataset, [train_size,
test_size])

# Create DataLoaders
batch_size = 32
train_loader = DataLoader(train_dataset, batch_size=batch_size,
shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size,
shuffle=False)

# Number of classes
num_classes = len(dataset.classes)
print(f"Number of classes: {num_classes}")
print(f"Classes: {dataset.classes}")

# Define the device (GPU or CPU)


device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")

# Load a pre-trained ResNet model


model = models.resnet50(pretrained=True).to(device) # You can also
try resnet18, resnet34, etc.

# Modify the fully connected layer to match the number of classes


model.fc = nn.Linear(model.fc.in_features, num_classes).to(device)

# Define loss function and optimizer


criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
from sklearn.metrics import precision_recall_fscore_support,
accuracy_score
import numpy as np

# Training and evaluation loop with metrics


def train_and_evaluate_resnet_with_metrics(train_loader, test_loader,
model, criterion, optimizer, num_classes, epochs=5):
for epoch in range(epochs):
model.train()
running_loss = 0.0
for inputs, labels in tqdm(train_loader, desc=f"Epoch
{epoch+1}/{epochs}"):
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()

print(f"Epoch {epoch+1}/{epochs} - Loss:


{running_loss/len(train_loader):.4f}")

# Evaluation
model.eval()
all_preds = []
all_labels = []

with torch.no_grad():
for inputs, labels in test_loader:
inputs, labels = inputs.to(device), labels.to(device)
outputs = model(inputs)
_, preds = torch.max(outputs, 1)

# Store predictions and labels for metrics calculation


all_preds.extend(preds.cpu().numpy())
all_labels.extend(labels.cpu().numpy())

# Calculate metrics
all_preds = np.array(all_preds)
all_labels = np.array(all_labels)

accuracy = accuracy_score(all_labels, all_preds) * 100


precision, recall, f1, _ =
precision_recall_fscore_support(all_labels, all_preds,
average='weighted')

print(f"\nEvaluation Metrics on Test Set:")


print(f"Accuracy: {accuracy:.2f}%")
print(f"Precision: {precision:.4f}")
print(f"Recall: {recall:.4f}")
print(f"F1-Score: {f1:.4f}")

# Call the updated function to train and evaluate the model with
metrics
train_and_evaluate_resnet_with_metrics(train_loader, test_loader,
model, criterion, optimizer, num_classes, epochs=5)

Number of classes: 4
Classes: ['Bus', 'Car', 'Truck', 'motorcycle']
Using device: cuda
/usr/local/lib/python3.10/dist-packages/torchvision/models/
_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated
since 0.13 and may be removed in the future, please use 'weights'
instead.
warnings.warn(
/usr/local/lib/python3.10/dist-packages/torchvision/models/_utils.py:2
23: UserWarning: Arguments other than a weight enum or `None` for
'weights' are deprecated since 0.13 and may be removed in the future.
The current behavior is equivalent to passing
`weights=ResNet50_Weights.IMAGENET1K_V1`. You can also use
`weights=ResNet50_Weights.DEFAULT` to get the most up-to-date weights.
warnings.warn(msg)
Downloading: "https://download.pytorch.org/models/resnet50-
0676ba61.pth" to /root/.cache/torch/hub/checkpoints/resnet50-
0676ba61.pth
100%|██████████| 97.8M/97.8M [00:00<00:00, 160MB/s]
Epoch 1/5: 100%|██████████| 9/9 [00:10<00:00, 1.19s/it]

Epoch 1/5 - Loss: 0.7649

Epoch 2/5: 100%|██████████| 9/9 [00:10<00:00, 1.15s/it]

Epoch 2/5 - Loss: 0.5734

Epoch 3/5: 100%|██████████| 9/9 [00:11<00:00, 1.22s/it]

Epoch 3/5 - Loss: 0.3695

Epoch 4/5: 100%|██████████| 9/9 [00:10<00:00, 1.22s/it]

Epoch 4/5 - Loss: 0.1897

Epoch 5/5: 100%|██████████| 9/9 [00:10<00:00, 1.21s/it]

Epoch 5/5 - Loss: 0.0882

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Evaluation Metrics on Test Set:


Accuracy: 79.17%
Precision: 0.8028
Recall: 0.7917
F1-Score: 0.7929

import torch
from torch import nn, optim
from torchvision import datasets, transforms, models
from torch.utils.data import DataLoader, random_split
from tqdm import tqdm

# Dataset path
data_dir = r"/content/final/Dataset" # Update with your dataset path

# Define transformations (VGG requires specific normalization)


transform = transforms.Compose([
transforms.Resize((224, 224)), # Resize for VGG16 input
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229,
0.224, 0.225])
])

# Load dataset
dataset = datasets.ImageFolder(data_dir, transform=transform)

# Split dataset into training (70%) and testing (30%)


train_size = int(0.7 * len(dataset))
test_size = len(dataset) - train_size
train_dataset, test_dataset = random_split(dataset, [train_size,
test_size])

# Create DataLoaders
batch_size = 32
train_loader = DataLoader(train_dataset, batch_size=batch_size,
shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size,
shuffle=False)

# Number of classes
num_classes = len(dataset.classes)
print(f"Number of classes: {num_classes}")
print(f"Classes: {dataset.classes}")

# Define the device (GPU or CPU)


device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(f"Using device: {device}")

# Load a pre-trained VGG16 model


model = models.vgg16(pretrained=True).to(device)

# Modify the fully connected layers to match the number of classes


model.classifier[6] = nn.Linear(model.classifier[6].in_features,
num_classes).to(device)

# Define loss function and optimizer


criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

from sklearn.metrics import precision_recall_fscore_support,


accuracy_score
import numpy as np

# Training and evaluation loop with metrics


def train_and_evaluate_vgg16_with_metrics(train_loader, test_loader,
model, criterion, optimizer, num_classes, epochs=5):
for epoch in range(epochs):
model.train()
running_loss = 0.0
for inputs, labels in tqdm(train_loader, desc=f"Epoch
{epoch+1}/{epochs}"):
inputs, labels = inputs.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()

print(f"Epoch {epoch+1}/{epochs} - Loss:


{running_loss/len(train_loader):.4f}")

# Evaluation
model.eval()
all_preds = []
all_labels = []

with torch.no_grad():
for inputs, labels in test_loader:
inputs, labels = inputs.to(device), labels.to(device)
outputs = model(inputs)
_, preds = torch.max(outputs, 1)

# Store predictions and labels for metrics calculation


all_preds.extend(preds.cpu().numpy())
all_labels.extend(labels.cpu().numpy())

# Calculate metrics
all_preds = np.array(all_preds)
all_labels = np.array(all_labels)

accuracy = accuracy_score(all_labels, all_preds) * 100


precision, recall, f1, _ =
precision_recall_fscore_support(all_labels, all_preds,
average='weighted')

print(f"\nEvaluation Metrics on Test Set:")


print(f"Accuracy: {accuracy:.2f}%")
print(f"Precision: {precision:.4f}")
print(f"Recall: {recall:.4f}")
print(f"F1-Score: {f1:.4f}")

# Call the updated function to train and evaluate the model with
metrics
train_and_evaluate_vgg16_with_metrics(train_loader, test_loader,
model, criterion, optimizer, num_classes, epochs=5)

Number of classes: 4
Classes: ['Bus', 'Car', 'Truck', 'motorcycle']
Using device: cuda

/usr/local/lib/python3.10/dist-packages/torchvision/models/
_utils.py:208: UserWarning: The parameter 'pretrained' is deprecated
since 0.13 and may be removed in the future, please use 'weights'
instead.
warnings.warn(
/usr/local/lib/python3.10/dist-packages/torchvision/models/_utils.py:2
23: UserWarning: Arguments other than a weight enum or `None` for
'weights' are deprecated since 0.13 and may be removed in the future.
The current behavior is equivalent to passing
`weights=VGG16_Weights.IMAGENET1K_V1`. You can also use
`weights=VGG16_Weights.DEFAULT` to get the most up-to-date weights.
warnings.warn(msg)
Epoch 1/5: 100%|██████████| 9/9 [00:13<00:00, 1.49s/it]

Epoch 1/5 - Loss: 1.9105

Epoch 2/5: 100%|██████████| 9/9 [00:13<00:00, 1.46s/it]

Epoch 2/5 - Loss: 1.9666

Epoch 3/5: 100%|██████████| 9/9 [00:12<00:00, 1.44s/it]

Epoch 3/5 - Loss: 1.4009

Epoch 4/5: 100%|██████████| 9/9 [00:12<00:00, 1.42s/it]

Epoch 4/5 - Loss: 1.3920

Epoch 5/5: 100%|██████████| 9/9 [00:13<00:00, 1.48s/it]

Epoch 5/5 - Loss: 1.3519

/usr/local/lib/python3.10/dist-packages/PIL/Image.py:1054:
UserWarning: Palette images with Transparency expressed in bytes
should be converted to RGBA images
warnings.warn(

Evaluation Metrics on Test Set:


Accuracy: 42.50%
Precision: 0.4012
Recall: 0.4250
F1-Score: 0.3700

/usr/local/lib/python3.10/dist-packages/sklearn/metrics/
_classification.py:1531: UndefinedMetricWarning: Precision is ill-
defined and being set to 0.0 in labels with no predicted samples. Use
`zero_division` parameter to control this behavior.
_warn_prf(average, modifier, f"{metric.capitalize()} is",
len(result))

Comparative Analysis of Model Performance


Model Accuracy (%) Precision Recall F1-Score
AlexNet 22.50 0.0506 0.2250 0.0827
VGG16 26.67 0.1221 0.2667 0.1671
LeNet 54.17 0.5266 0.5417 0.5285
ZFNet 66.25 0.6651 0.6625 0.6517
ResNet 79.17 0.8028 0.7917 0.7929

You might also like