0% found this document useful (0 votes)
12 views38 pages

BLDD VIT ResNet50v2 CustomCNN

The document outlines a comprehensive approach to training a Vision Transformer (ViT) model for banana disease recognition using a dataset of images. It includes data preprocessing, model training, validation, and evaluation steps, along with visualizations of training metrics and a confusion matrix for test results. The model achieves high accuracy in classifying various banana diseases based on the provided images.

Uploaded by

shibilbasith4u
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)
12 views38 pages

BLDD VIT ResNet50v2 CustomCNN

The document outlines a comprehensive approach to training a Vision Transformer (ViT) model for banana disease recognition using a dataset of images. It includes data preprocessing, model training, validation, and evaluation steps, along with visualizations of training metrics and a confusion matrix for test results. The model achieves high accuracy in classifying various banana diseases based on the provided images.

Uploaded by

shibilbasith4u
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/ 38

import pandas as pd

import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from PIL import Image
import cv2
from sklearn.model_selection import train_test_split
import torch
from torch.utils.data import Dataset, DataLoader
from torch import nn, optim
from torchinfo import summary
from torchvision.models import vit_b_16, ViT_B_16_Weights
from sklearn.metrics import accuracy_score, confusion_matrix
import os
from pathlib import Path
from tqdm.auto import tqdm
from collections import OrderedDict
import random
import warnings

warnings.filterwarnings("ignore")

# Setting image path and getting list of images


IMAGE_PATH =
Path("/kaggle/input/banana-disease-recognition-dataset/Banana Disease
Recognition Dataset/Original Images/Original Images")
IMAGE_PATH_LIST = list(IMAGE_PATH.glob("*/*.jpg"))
print(f'Total Images = {len(IMAGE_PATH_LIST)}')

classes = sorted(os.listdir(IMAGE_PATH))
print('==' * 20)
print(' ' * 10, f'Total Classes = {len(classes)}')
print('==' * 20)

for c in classes:
total_images_class = list(Path(os.path.join(IMAGE_PATH,
c)).glob("*.jpg"))
print(f'* {c}: {len(total_images_class)} images')

# Visualize a few sample images


NUM_IMAGES = 3
fig, ax = plt.subplots(nrows=len(classes), ncols=NUM_IMAGES,
figsize=(10, 30))
p = 0
for c in classes:
total_images_class = list(Path(os.path.join(IMAGE_PATH,
c)).glob("*.jpg"))
images_selected = random.choices(total_images_class, k=NUM_IMAGES)
for i, img_path in enumerate(images_selected):
img_bgr = cv2.imread(str(img_path))
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
ax[p, i].imshow(img_rgb)
ax[p, i].axis('off')
ax[p, i].set_title(f'Class: {c}\nShape: {img_rgb.shape}')
p += 1
fig.tight_layout()
fig.show()

# Prepare dataframe with image paths and labels


images_path = []
labels = []

for img_path in IMAGE_PATH_LIST:


images_path.append(img_path)
labels.append(img_path.parent.stem)

df_path_and_label = pd.DataFrame({'path': images_path, 'label':


labels})
print(df_path_and_label.head())

# Split the data


SEED = 42
df_train, df_rest = train_test_split(df_path_and_label, test_size=0.3,
random_state=SEED, stratify=df_path_and_label["label"])
df_valid, df_test = train_test_split(df_rest, test_size=0.5,
random_state=SEED, stratify=df_rest["label"])

# Define label mapping: class string to numerical value


label_map = dict(zip(classes, range(len(classes))))
print(label_map)

# Define transforms from ViT_B_16_Weights


weights = ViT_B_16_Weights.DEFAULT
auto_transforms = weights.transforms()
print(auto_transforms)

# Updated Custom dataset class: precompute label mapping during


initialization
class CustomImageDataset(Dataset):
def __init__(self, df: pd.DataFrame, label_map: dict, transforms):
# Use a copy and precompute numeric labels
df = df.copy()
df["numeric_label"] = df["label"].map(label_map)
self.df = df.reset_index(drop=True)
self.transforms = transforms

def __len__(self):
return len(self.df)

def __getitem__(self, idx):


image_path = self.df.iloc[idx, 0]
label = self.df.iloc[idx]["numeric_label"]
image = Image.open(image_path).convert("RGB")
image = self.transforms(image)
return image, label

# Create dataset instances


train_dataset = CustomImageDataset(df_train, label_map,
auto_transforms)
valid_dataset = CustomImageDataset(df_valid, label_map,
auto_transforms)

# Use fewer workers for DataLoader (e.g., 4)


BATCH_SIZE = 8
NUM_WORKERS = 4

train_dataloader = DataLoader(dataset=train_dataset,
batch_size=BATCH_SIZE, shuffle=True, num_workers=NUM_WORKERS)
valid_dataloader = DataLoader(dataset=valid_dataset,
batch_size=BATCH_SIZE, shuffle=True, num_workers=NUM_WORKERS)

# Visualize a batch
batch_images, batch_labels = next(iter(train_dataloader))
print("Batch images shape:", batch_images.shape, "and Batch labels
shape:", batch_labels.shape)

# Check GPU availability and set device


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

# Load ViT-16 model and modify last layer for current number of
classes
model = vit_b_16(weights=weights)
summary(model=model, input_size=[8, 3, 224, 224], col_width=15,
col_names=["input_size", "output_size", "num_params", "trainable"],
row_settings=["var_names"])

for param in model.conv_proj.parameters():


param.requires_grad = False
for param in model.encoder.parameters():
param.requires_grad = False

# Confirm parameters have been frozen


summary(model=model, input_size=[8, 3, 224, 224], col_width=15,
col_names=["input_size", "output_size", "num_params", "trainable"],
row_settings=["var_names"])

output_shape = len(classes)
model.heads = nn.Sequential(OrderedDict([('head',
nn.Linear(in_features=768, out_features=output_shape))]))
summary(model=model, input_size=[8, 3, 224, 224], col_width=15,
col_names=["input_size", "output_size", "num_params", "trainable"],
row_settings=["var_names"])

# Define loss and optimizer


loss_fn = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)

def train_step(model: torch.nn.Module, dataloader:


torch.utils.data.DataLoader,
loss_fn: torch.nn.Module, optimizer:
torch.optim.Optimizer):
model.train()
train_loss = 0.
train_accuracy = 0.
for _, (X, y) in enumerate(dataloader):
X, y = X.to(device), y.to(device)
optimizer.zero_grad()
y_pred_logit = model(X)
loss = loss_fn(y_pred_logit, y)
train_loss += loss.item()
loss.backward()
optimizer.step()
y_pred_prob = torch.softmax(y_pred_logit, dim=1)
y_pred_class = torch.argmax(y_pred_prob, dim=1)
train_accuracy += accuracy_score(y.cpu().numpy(),
y_pred_class.detach().cpu().numpy())
train_loss = train_loss / len(dataloader)
train_accuracy = train_accuracy / len(dataloader)
return train_loss, train_accuracy

def save_checkpoint(filename, model, epoch, loss, optimizer, metric):


state = {'filename': filename,
'model': model.state_dict(),
'epoch': epoch,
'loss': loss,
'optimizer': optimizer.state_dict(),
'metric': metric}
torch.save(state, filename)

def valid_step(model: torch.nn.Module, dataloader:


torch.utils.data.DataLoader,
loss_fn: torch.nn.Module):
model.eval()
valid_loss = 0.
valid_accuracy = 0.
with torch.inference_mode():
for _, (X, y) in enumerate(dataloader):
X, y = X.to(device), y.to(device)
y_pred_logit = model(X)
loss = loss_fn(y_pred_logit, y)
valid_loss += loss.item()
y_pred_prob = torch.softmax(y_pred_logit, dim=1)
y_pred_class = torch.argmax(y_pred_prob, dim=1)
valid_accuracy += accuracy_score(y.cpu().numpy(),
y_pred_class.detach().cpu().numpy())
valid_loss = valid_loss / len(dataloader)
valid_accuracy = valid_accuracy / len(dataloader)
return valid_loss, valid_accuracy

def train(model: torch.nn.Module, train_dataloader:


torch.utils.data.DataLoader,
valid_dataloader: torch.utils.data.DataLoader, loss_fn:
torch.nn.Module,
optimizer: torch.optim.Optimizer, epochs: int = 10):
results = {"train_loss": [], "train_accuracy": [], "valid_loss":
[], "valid_accuracy": []}
best_valid_loss = float('inf')
for epoch in tqdm(range(epochs)):
train_loss, train_accuracy = train_step(model=model,
dataloader=train_dataloader, loss_fn=loss_fn, optimizer=optimizer)
valid_loss, valid_accuracy = valid_step(model=model,
dataloader=valid_dataloader, loss_fn=loss_fn)
if valid_loss < best_valid_loss:
best_valid_loss = valid_loss
save_checkpoint("best_model.pth", model, epoch,
best_valid_loss, optimizer, valid_accuracy)
print(f'Epoch: {epoch + 1} | Train Loss: {train_loss:.4f} |
Train Accuracy: {train_accuracy:.4f} | Valid Loss: {valid_loss:.4f} |
Valid Accuracy: {valid_accuracy:.4f}')
results["train_loss"].append(train_loss)
results["train_accuracy"].append(train_accuracy)
results["valid_loss"].append(valid_loss)
results["valid_accuracy"].append(valid_accuracy)
return results

# Training parameters and seeds


EPOCHS = 100
torch.cuda.manual_seed(SEED)
torch.manual_seed(SEED)
MODEL_RESULTS = train(model, train_dataloader, valid_dataloader,
loss_fn, optimizer, EPOCHS)

def loss_metric_curve_plot(model_results: dict):


train_loss = model_results["train_loss"]
valid_loss = model_results["valid_loss"]
train_accuracy = [float(value) for value in
model_results["train_accuracy"]]
valid_accuracy = [float(value) for value in
model_results["valid_accuracy"]]
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))
axes = axes.flat
axes[0].plot(train_loss, color="red", label="Train")
axes[0].plot(valid_loss, color="blue", label="Valid",
linestyle='--')
axes[0].spines["top"].set_visible(False)
axes[0].spines["right"].set_visible(False)
axes[0].set_title("CrossEntropyLoss", fontsize=12,
fontweight="bold", color="black")
axes[0].set_xlabel("Epochs", fontsize=10, fontweight="bold",
color="black")
axes[0].set_ylabel("Loss", fontsize=10, fontweight="bold",
color="black")
axes[0].legend()
axes[1].plot(train_accuracy, color="red", label="Train")
axes[1].plot(valid_accuracy, color="blue", label="Valid",
linestyle='--')
axes[1].spines["top"].set_visible(False)
axes[1].spines["right"].set_visible(False)
axes[1].set_title("Accuracy", fontsize=12, fontweight="bold",
color="black")
axes[1].set_xlabel("Epochs", fontsize=10, fontweight="bold",
color="black")
axes[1].set_ylabel("Score", fontsize=10, fontweight="bold",
color="black")
axes[1].legend()
fig.tight_layout()
fig.show()

loss_metric_curve_plot(MODEL_RESULTS)

def predictions(test_dataloader: torch.utils.data.DataLoader):


checkpoint = torch.load("best_model.pth")
loaded_model = vit_b_16(weights=weights)
loaded_model.heads = nn.Sequential(OrderedDict([('head',
nn.Linear(in_features=768, out_features=output_shape))]))
loaded_model.load_state_dict(checkpoint["model"])
loaded_model.to(device)
loaded_model.eval()
y_pred_test = []
with torch.inference_mode():
for X, _ in tqdm(test_dataloader):
X = X.to(device)
y_pred_logit = loaded_model(X)
y_pred_prob = torch.softmax(y_pred_logit, dim=1)
y_pred_class = torch.argmax(y_pred_prob, dim=1)
y_pred_test.append(y_pred_class.detach().cpu())
y_pred_test = torch.cat(y_pred_test)
return y_pred_test
# Prepare test DataLoader
test_dataset = CustomImageDataset(df_test, label_map, auto_transforms)
test_dataloader = DataLoader(dataset=test_dataset,
batch_size=BATCH_SIZE, shuffle=False, num_workers=NUM_WORKERS)
y_pred_test = predictions(test_dataloader)
print(f'Accuracy Test =
{round(accuracy_score(df_test["label"].map(label_map),
y_pred_test.numpy()), 4)}')

confusion_matrix_test =
confusion_matrix(df_test["label"].map(label_map), y_pred_test.numpy())
fig, ax = plt.subplots(figsize=(10, 4.5))
sns.heatmap(confusion_matrix_test, cmap='Oranges', annot=True,
annot_kws={"fontsize": 9, "fontweight": "bold"},
linewidths=1.2, fmt=' ', linecolor="white", square=True,
xticklabels=classes, yticklabels=classes,
cbar=False, ax=ax)
ax.set_title("Confusion Matrix Test", fontsize=15, fontweight="bold",
color="darkblue")
ax.tick_params('x', rotation=90)
fig.show()

Total Images = 408


========================================
Total Classes = 7
========================================
* Banana Black Sigatoka Disease: 67 images
* Banana Bract Mosaic Virus Disease: 50 images
* Banana Healthy Leaf: 86 images
* Banana Insect Pest Disease: 86 images
* Banana Moko Disease: 55 images
* Banana Panama Disease: 41 images
* Banana Yellow Sigatoka Disease: 23 images
path
label
0 /kaggle/input/banana-disease-recognition-datas... Banana Panama
Disease
1 /kaggle/input/banana-disease-recognition-datas... Banana Panama
Disease
2 /kaggle/input/banana-disease-recognition-datas... Banana Panama
Disease
3 /kaggle/input/banana-disease-recognition-datas... Banana Panama
Disease
4 /kaggle/input/banana-disease-recognition-datas... Banana Panama
Disease
{'Banana Black Sigatoka Disease': 0, 'Banana Bract Mosaic Virus
Disease': 1, 'Banana Healthy Leaf': 2, 'Banana Insect Pest Disease':
3, 'Banana Moko Disease': 4, 'Banana Panama Disease': 5, 'Banana
Yellow Sigatoka Disease': 6}
ImageClassification(
crop_size=[224]
resize_size=[256]
mean=[0.485, 0.456, 0.406]
std=[0.229, 0.224, 0.225]
interpolation=InterpolationMode.BILINEAR
)
Batch images shape: torch.Size([8, 3, 224, 224]) and Batch labels
shape: torch.Size([8])
Using device: cuda

Downloading: "https://download.pytorch.org/models/vit_b_16-
c867db91.pth" to /root/.cache/torch/hub/checkpoints/vit_b_16-
c867db91.pth
100%|██████████| 330M/330M [00:01<00:00, 210MB/s]

{"model_id":"e97a19f7213640598339fe3c82118a19","version_major":2,"vers
ion_minor":0}

Epoch: 1 | Train Loss: 0.7721 | Train Accuracy: 0.7569 | Valid Loss:


0.5587 | Valid Accuracy: 0.8750
Epoch: 2 | Train Loss: 0.1039 | Train Accuracy: 0.9722 | Valid Loss:
0.2439 | Valid Accuracy: 0.9219
Epoch: 3 | Train Loss: 0.0123 | Train Accuracy: 1.0000 | Valid Loss:
0.2401 | Valid Accuracy: 0.8906
Epoch: 4 | Train Loss: 0.0080 | Train Accuracy: 1.0000 | Valid Loss:
0.2705 | Valid Accuracy: 0.9594
Epoch: 5 | Train Loss: 0.0028 | Train Accuracy: 1.0000 | Valid Loss:
0.2012 | Valid Accuracy: 0.9688
Epoch: 6 | Train Loss: 0.0018 | Train Accuracy: 1.0000 | Valid Loss:
0.1995 | Valid Accuracy: 0.9688
Epoch: 7 | Train Loss: 0.0016 | Train Accuracy: 1.0000 | Valid Loss:
0.1920 | Valid Accuracy: 0.9688
Epoch: 8 | Train Loss: 0.0013 | Train Accuracy: 1.0000 | Valid Loss:
0.2084 | Valid Accuracy: 0.9594
Epoch: 9 | Train Loss: 0.0012 | Train Accuracy: 1.0000 | Valid Loss:
0.2647 | Valid Accuracy: 0.9594
Epoch: 10 | Train Loss: 0.0011 | Train Accuracy: 1.0000 | Valid Loss:
0.2022 | Valid Accuracy: 0.9688
Epoch: 11 | Train Loss: 0.0009 | Train Accuracy: 1.0000 | Valid Loss:
0.1998 | Valid Accuracy: 0.9688
Epoch: 12 | Train Loss: 0.0009 | Train Accuracy: 1.0000 | Valid Loss:
0.1920 | Valid Accuracy: 0.9688
Epoch: 13 | Train Loss: 0.0008 | Train Accuracy: 1.0000 | Valid Loss:
0.2655 | Valid Accuracy: 0.9594
Epoch: 14 | Train Loss: 0.0008 | Train Accuracy: 1.0000 | Valid Loss:
0.1911 | Valid Accuracy: 0.9688
Epoch: 15 | Train Loss: 0.0007 | Train Accuracy: 1.0000 | Valid Loss:
0.1922 | Valid Accuracy: 0.9688
Epoch: 16 | Train Loss: 0.0006 | Train Accuracy: 1.0000 | Valid Loss:
0.1908 | Valid Accuracy: 0.9688
Epoch: 17 | Train Loss: 0.0006 | Train Accuracy: 1.0000 | Valid Loss:
0.1921 | Valid Accuracy: 0.9688
Epoch: 18 | Train Loss: 0.0006 | Train Accuracy: 1.0000 | Valid Loss:
0.1953 | Valid Accuracy: 0.9688
Epoch: 19 | Train Loss: 0.0005 | Train Accuracy: 1.0000 | Valid Loss:
0.1935 | Valid Accuracy: 0.9688
Epoch: 20 | Train Loss: 0.0005 | Train Accuracy: 1.0000 | Valid Loss:
0.1923 | Valid Accuracy: 0.9688
Epoch: 21 | Train Loss: 0.0005 | Train Accuracy: 1.0000 | Valid Loss:
0.1917 | Valid Accuracy: 0.9688
Epoch: 22 | Train Loss: 0.0004 | Train Accuracy: 1.0000 | Valid Loss:
0.1918 | Valid Accuracy: 0.9688
Epoch: 23 | Train Loss: 0.0004 | Train Accuracy: 1.0000 | Valid Loss:
0.1933 | Valid Accuracy: 0.9688
Epoch: 24 | Train Loss: 0.0004 | Train Accuracy: 1.0000 | Valid Loss:
0.1974 | Valid Accuracy: 0.9688
Epoch: 25 | Train Loss: 0.0004 | Train Accuracy: 1.0000 | Valid Loss:
0.1929 | Valid Accuracy: 0.9688
Epoch: 26 | Train Loss: 0.0004 | Train Accuracy: 1.0000 | Valid Loss:
0.1980 | Valid Accuracy: 0.9688
Epoch: 27 | Train Loss: 0.0003 | Train Accuracy: 1.0000 | Valid Loss:
0.1952 | Valid Accuracy: 0.9688
Epoch: 28 | Train Loss: 0.0003 | Train Accuracy: 1.0000 | Valid Loss:
0.1914 | Valid Accuracy: 0.9688
Epoch: 29 | Train Loss: 0.0003 | Train Accuracy: 1.0000 | Valid Loss:
0.1978 | Valid Accuracy: 0.9688
Epoch: 30 | Train Loss: 0.0003 | Train Accuracy: 1.0000 | Valid Loss:
0.1952 | Valid Accuracy: 0.9688
Epoch: 31 | Train Loss: 0.0003 | Train Accuracy: 1.0000 | Valid Loss:
0.1938 | Valid Accuracy: 0.9688
Epoch: 32 | Train Loss: 0.0003 | Train Accuracy: 1.0000 | Valid Loss:
0.1973 | Valid Accuracy: 0.9688
Epoch: 33 | Train Loss: 0.0003 | Train Accuracy: 1.0000 | Valid Loss:
0.1966 | Valid Accuracy: 0.9688
Epoch: 34 | Train Loss: 0.0002 | Train Accuracy: 1.0000 | Valid Loss:
0.1930 | Valid Accuracy: 0.9688
Epoch: 35 | Train Loss: 0.0002 | Train Accuracy: 1.0000 | Valid Loss:
0.2029 | Valid Accuracy: 0.9594
Epoch: 36 | Train Loss: 0.0002 | Train Accuracy: 1.0000 | Valid Loss:
0.2762 | Valid Accuracy: 0.9594
Epoch: 37 | Train Loss: 0.0002 | Train Accuracy: 1.0000 | Valid Loss:
0.1979 | Valid Accuracy: 0.9688
Epoch: 38 | Train Loss: 0.0002 | Train Accuracy: 1.0000 | Valid Loss:
0.1931 | Valid Accuracy: 0.9688
Epoch: 39 | Train Loss: 0.0002 | Train Accuracy: 1.0000 | Valid Loss:
0.1927 | Valid Accuracy: 0.9688
Epoch: 40 | Train Loss: 0.0002 | Train Accuracy: 1.0000 | Valid Loss:
0.1927 | Valid Accuracy: 0.9688
Epoch: 41 | Train Loss: 0.0002 | Train Accuracy: 1.0000 | Valid Loss:
0.1927 | Valid Accuracy: 0.9688
Epoch: 42 | Train Loss: 0.0002 | Train Accuracy: 1.0000 | Valid Loss:
0.1941 | Valid Accuracy: 0.9688
Epoch: 43 | Train Loss: 0.0002 | Train Accuracy: 1.0000 | Valid Loss:
0.1931 | Valid Accuracy: 0.9688
Epoch: 44 | Train Loss: 0.0002 | Train Accuracy: 1.0000 | Valid Loss:
0.1952 | Valid Accuracy: 0.9688
Epoch: 45 | Train Loss: 0.0002 | Train Accuracy: 1.0000 | Valid Loss:
0.1945 | Valid Accuracy: 0.9688
Epoch: 46 | Train Loss: 0.0002 | Train Accuracy: 1.0000 | Valid Loss:
0.1923 | Valid Accuracy: 0.9688
Epoch: 47 | Train Loss: 0.0002 | Train Accuracy: 1.0000 | Valid Loss:
0.1972 | Valid Accuracy: 0.9688
Epoch: 48 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1945 | Valid Accuracy: 0.9688
Epoch: 49 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1976 | Valid Accuracy: 0.9688
Epoch: 50 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1948 | Valid Accuracy: 0.9688
Epoch: 51 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.2853 | Valid Accuracy: 0.9594
Epoch: 52 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.2078 | Valid Accuracy: 0.9594
Epoch: 53 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1943 | Valid Accuracy: 0.9688
Epoch: 54 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1956 | Valid Accuracy: 0.9688
Epoch: 55 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1950 | Valid Accuracy: 0.9688
Epoch: 56 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1961 | Valid Accuracy: 0.9688
Epoch: 57 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1937 | Valid Accuracy: 0.9688
Epoch: 58 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1939 | Valid Accuracy: 0.9688
Epoch: 59 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1952 | Valid Accuracy: 0.9688
Epoch: 60 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1943 | Valid Accuracy: 0.9688
Epoch: 61 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1953 | Valid Accuracy: 0.9688
Epoch: 62 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1939 | Valid Accuracy: 0.9688
Epoch: 63 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1995 | Valid Accuracy: 0.9688
Epoch: 64 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.2824 | Valid Accuracy: 0.9594
Epoch: 65 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1946 | Valid Accuracy: 0.9688
Epoch: 66 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1960 | Valid Accuracy: 0.9688
Epoch: 67 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1956 | Valid Accuracy: 0.9688
Epoch: 68 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1964 | Valid Accuracy: 0.9688
Epoch: 69 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1964 | Valid Accuracy: 0.9688
Epoch: 70 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1967 | Valid Accuracy: 0.9688
Epoch: 71 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1995 | Valid Accuracy: 0.9688
Epoch: 72 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1952 | Valid Accuracy: 0.9688
Epoch: 73 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1994 | Valid Accuracy: 0.9688
Epoch: 74 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.2009 | Valid Accuracy: 0.9688
Epoch: 75 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1963 | Valid Accuracy: 0.9688
Epoch: 76 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1966 | Valid Accuracy: 0.9688
Epoch: 77 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1999 | Valid Accuracy: 0.9688
Epoch: 78 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1966 | Valid Accuracy: 0.9688
Epoch: 79 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1958 | Valid Accuracy: 0.9688
Epoch: 80 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.2002 | Valid Accuracy: 0.9688
Epoch: 81 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.2000 | Valid Accuracy: 0.9688
Epoch: 82 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1968 | Valid Accuracy: 0.9688
Epoch: 83 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1967 | Valid Accuracy: 0.9688
Epoch: 84 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1956 | Valid Accuracy: 0.9688
Epoch: 85 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1977 | Valid Accuracy: 0.9688
Epoch: 86 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.2003 | Valid Accuracy: 0.9688
Epoch: 87 | Train Loss: 0.0001 | Train Accuracy: 1.0000 | Valid Loss:
0.1975 | Valid Accuracy: 0.9688
Epoch: 88 | Train Loss: 0.0000 | Train Accuracy: 1.0000 | Valid Loss:
0.1967 | Valid Accuracy: 0.9688
Epoch: 89 | Train Loss: 0.0000 | Train Accuracy: 1.0000 | Valid Loss:
0.1970 | Valid Accuracy: 0.9688
Epoch: 90 | Train Loss: 0.0000 | Train Accuracy: 1.0000 | Valid Loss:
0.1970 | Valid Accuracy: 0.9688
Epoch: 91 | Train Loss: 0.0000 | Train Accuracy: 1.0000 | Valid Loss:
0.2018 | Valid Accuracy: 0.9688
Epoch: 92 | Train Loss: 0.0000 | Train Accuracy: 1.0000 | Valid Loss:
0.2041 | Valid Accuracy: 0.9594
Epoch: 93 | Train Loss: 0.0000 | Train Accuracy: 1.0000 | Valid Loss:
0.1970 | Valid Accuracy: 0.9688
Epoch: 94 | Train Loss: 0.0000 | Train Accuracy: 1.0000 | Valid Loss:
0.1963 | Valid Accuracy: 0.9688
Epoch: 95 | Train Loss: 0.0000 | Train Accuracy: 1.0000 | Valid Loss:
0.2018 | Valid Accuracy: 0.9688
Epoch: 96 | Train Loss: 0.0000 | Train Accuracy: 1.0000 | Valid Loss:
0.1979 | Valid Accuracy: 0.9688
Epoch: 97 | Train Loss: 0.0000 | Train Accuracy: 1.0000 | Valid Loss:
0.2907 | Valid Accuracy: 0.9594
Epoch: 98 | Train Loss: 0.0000 | Train Accuracy: 1.0000 | Valid Loss:
0.2051 | Valid Accuracy: 0.9594
Epoch: 99 | Train Loss: 0.0000 | Train Accuracy: 1.0000 | Valid Loss:
0.2004 | Valid Accuracy: 0.9688
Epoch: 100 | Train Loss: 0.0000 | Train Accuracy: 1.0000 | Valid Loss:
0.2021 | Valid Accuracy: 0.9688

{"model_id":"3fbdaf5bc856475697b142497520467b","version_major":2,"vers
ion_minor":0}

Accuracy Test = 0.9516


from sklearn.metrics import accuracy_score, precision_score,
recall_score, f1_score, classification_report, confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns

# Map ground truth labels to numerical values


true_labels = df_test["label"].map(label_map).values
predicted_labels = y_pred_test.numpy()

# Calculate overall accuracy


accuracy = accuracy_score(true_labels, predicted_labels)
print(f"Test Accuracy: {accuracy:.4f}")
# Calculate precision, recall, and f1-score with different averaging
methods
precision_macro = precision_score(true_labels, predicted_labels,
average='macro')
recall_macro = recall_score(true_labels, predicted_labels,
average='macro')
f1_macro = f1_score(true_labels, predicted_labels, average='macro')

precision_micro = precision_score(true_labels, predicted_labels,


average='micro')
recall_micro = recall_score(true_labels, predicted_labels,
average='micro')
f1_micro = f1_score(true_labels, predicted_labels, average='micro')

precision_weighted = precision_score(true_labels, predicted_labels,


average='weighted')
recall_weighted = recall_score(true_labels, predicted_labels,
average='weighted')
f1_weighted = f1_score(true_labels, predicted_labels,
average='weighted')

print("Metric Scores (Macro Average):")


print(f"Precision: {precision_macro:.4f}")
print(f"Recall: {recall_macro:.4f}")
print(f"F1 Score: {f1_macro:.4f}")

print("\nMetric Scores (Micro Average):")


print(f"Precision: {precision_micro:.4f}")
print(f"Recall: {recall_micro:.4f}")
print(f"F1 Score: {f1_micro:.4f}")

print("\nMetric Scores (Weighted Average):")


print(f"Precision: {precision_weighted:.4f}")
print(f"Recall: {recall_weighted:.4f}")
print(f"F1 Score: {f1_weighted:.4f}")

# Detailed classification report


print("\nClassification Report:")
print(classification_report(true_labels, predicted_labels,
target_names=classes))

# Compute and visualize the confusion matrix


cm = confusion_matrix(true_labels, predicted_labels)
plt.figure(figsize=(10, 4.5))
sns.heatmap(cm, cmap='Oranges', annot=True, annot_kws={"fontsize": 9,
"fontweight": "bold"},
linewidths=1.2, fmt='d', linecolor="white", square=True,
xticklabels=classes, yticklabels=classes, cbar=False)
plt.title("Confusion Matrix Test", fontsize=15, fontweight="bold",
color="darkblue")
plt.xlabel("Predicted Classes", fontsize=12, fontweight="bold",
color="black")
plt.ylabel("True Classes", fontsize=12, fontweight="bold",
color="black")
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()

Test Accuracy: 0.9516


Metric Scores (Macro Average):
Precision: 0.9280
Recall: 0.9604
F1 Score: 0.9403

Metric Scores (Micro Average):


Precision: 0.9516
Recall: 0.9516
F1 Score: 0.9516

Metric Scores (Weighted Average):


Precision: 0.9562
Recall: 0.9516
F1 Score: 0.9518

Classification Report:
precision recall f1-score
support

Banana Black Sigatoka Disease 0.89 0.80 0.84


10
Banana Bract Mosaic Virus Disease 1.00 1.00 1.00
8
Banana Healthy Leaf 1.00 1.00 1.00
13
Banana Insect Pest Disease 1.00 0.92 0.96
13
Banana Moko Disease 1.00 1.00 1.00
9
Banana Panama Disease 0.86 1.00 0.92
6
Banana Yellow Sigatoka Disease 0.75 1.00 0.86
3

accuracy 0.95
62
macro avg 0.93 0.96 0.94
62
weighted avg 0.96 0.95 0.95
62

# 1. ResNet50V2 Implementation
# Import necessary libraries
import torch
from torch import nn
import torchvision.models as models
from collections import OrderedDict

# Create ResNet50 model


resnet_model =
models.resnet50(weights=models.ResNet50_Weights.DEFAULT)

# Freeze base layers


for param in resnet_model.parameters():
param.requires_grad = False

# Modify the final layer for our classification task


in_features = resnet_model.fc.in_features
resnet_model.fc = nn.Linear(in_features, len(classes))
resnet_model = resnet_model.to(device)
# Define optimizer for ResNet50
resnet_optimizer = optim.Adam(resnet_model.parameters(), lr=0.001)

# 2. Custom CNN Implementation


class CustomCNN(nn.Module):
def __init__(self, num_classes):
super(CustomCNN, self).__init__()

# Feature extractor - convolutional layers


self.features = nn.Sequential(
# First block
nn.Conv2d(3, 32, kernel_size=3, padding=1),
nn.BatchNorm2d(32),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),

# Second block
nn.Conv2d(32, 64, kernel_size=3, padding=1),
nn.BatchNorm2d(64),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),

# Third block
nn.Conv2d(64, 128, kernel_size=3, padding=1),
nn.BatchNorm2d(128),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),

# Fourth block
nn.Conv2d(128, 256, kernel_size=3, padding=1),
nn.BatchNorm2d(256),
nn.ReLU(inplace=True),
nn.MaxPool2d(kernel_size=2, stride=2),
)

# Classifier - fully connected layers


self.classifier = nn.Sequential(
nn.Flatten(),
nn.Linear(256 * 14 * 14, 512), # For 224x224 input images
nn.ReLU(inplace=True),
nn.Dropout(0.5),
nn.Linear(512, num_classes)
)

def forward(self, x):


x = self.features(x)
x = self.classifier(x)
return x
# Create Custom CNN model
cnn_model = CustomCNN(len(classes))
cnn_model = cnn_model.to(device)

# Define optimizer for Custom CNN


cnn_optimizer = optim.Adam(cnn_model.parameters(), lr=0.001)

# 3. Train ResNet50V2 model


print("=" * 50)
print("Training ResNet50V2 model")
print("=" * 50)

RESNET_RESULTS = train(resnet_model, train_dataloader,


valid_dataloader, loss_fn, resnet_optimizer, EPOCHS)

# 4. Train Custom CNN model


print("=" * 50)
print("Training Custom CNN model")
print("=" * 50)

CNN_RESULTS = train(cnn_model, train_dataloader, valid_dataloader,


loss_fn, cnn_optimizer, EPOCHS)

# 5. Evaluate ResNet50V2 on test set


def evaluate_model(model, test_dataloader, model_name):
model.eval()
y_pred_test = []
with torch.inference_mode():
for X, _ in tqdm(test_dataloader):
X = X.to(device)
y_pred_logit = model(X)
y_pred_prob = torch.softmax(y_pred_logit, dim=1)
y_pred_class = torch.argmax(y_pred_prob, dim=1)
y_pred_test.append(y_pred_class.detach().cpu())
y_pred_test = torch.cat(y_pred_test)

accuracy = accuracy_score(df_test["label"].map(label_map),
y_pred_test.numpy())
print(f'{model_name} Test Accuracy = {round(accuracy, 4)}')

conf_matrix = confusion_matrix(df_test["label"].map(label_map),
y_pred_test.numpy())
fig, ax = plt.subplots(figsize=(10, 4.5))
sns.heatmap(conf_matrix, cmap='Blues', annot=True,
annot_kws={"fontsize": 9, "fontweight": "bold"},
linewidths=1.2, fmt=' ', linecolor="white",
square=True,
xticklabels=classes, yticklabels=classes, cbar=False,
ax=ax)
ax.set_title(f"{model_name} Confusion Matrix", fontsize=15,
fontweight="bold", color="darkblue")
ax.tick_params('x', rotation=90)
plt.tight_layout()
plt.show()

return accuracy, y_pred_test

# Evaluate ResNet50V2
resnet_accuracy, resnet_preds = evaluate_model(resnet_model,
test_dataloader, "ResNet50V2")

# Evaluate Custom CNN


cnn_accuracy, cnn_preds = evaluate_model(cnn_model, test_dataloader,
"Custom CNN")

# 6. Compare all models' performance


vit_accuracy = accuracy_score(df_test["label"].map(label_map),
y_pred_test.numpy())

# Plot comparison
model_names = ['ViT-B/16', 'ResNet50V2', 'Custom CNN']
accuracies = [vit_accuracy, resnet_accuracy, cnn_accuracy]

plt.figure(figsize=(10, 6))
bars = plt.bar(model_names, accuracies, color=['orange', 'skyblue',
'lightgreen'])

# Add accuracy values on top of bars


for bar, acc in zip(bars, accuracies):
plt.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.01,
f'{acc:.4f}', ha='center', fontweight='bold')

plt.title('Model Performance Comparison', fontsize=15,


fontweight='bold')
plt.ylabel('Test Accuracy', fontsize=12)
plt.ylim(0, max(accuracies) + 0.1)
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.tight_layout()
plt.show()

# 7. Plot training curves for all models


plt.figure(figsize=(15, 10))

# Training Loss
plt.subplot(2, 2, 1)
plt.plot(MODEL_RESULTS["train_loss"], 'o-', color='orange',
label='ViT')
plt.plot(RESNET_RESULTS["train_loss"], 'o-', color='skyblue',
label='ResNet50V2')
plt.plot(CNN_RESULTS["train_loss"], 'o-', color='lightgreen',
label='Custom CNN')
plt.title("Training Loss", fontsize=12, fontweight="bold")
plt.xlabel("Epochs", fontsize=10)
plt.ylabel("Loss", fontsize=10)
plt.legend()
plt.grid(True, alpha=0.3)

# Validation Loss
plt.subplot(2, 2, 2)
plt.plot(MODEL_RESULTS["valid_loss"], 'o-', color='orange',
label='ViT')
plt.plot(RESNET_RESULTS["valid_loss"], 'o-', color='skyblue',
label='ResNet50V2')
plt.plot(CNN_RESULTS["valid_loss"], 'o-', color='lightgreen',
label='Custom CNN')
plt.title("Validation Loss", fontsize=12, fontweight="bold")
plt.xlabel("Epochs", fontsize=10)
plt.ylabel("Loss", fontsize=10)
plt.legend()
plt.grid(True, alpha=0.3)

# Training Accuracy
plt.subplot(2, 2, 3)
plt.plot(MODEL_RESULTS["train_accuracy"], 'o-', color='orange',
label='ViT')
plt.plot(RESNET_RESULTS["train_accuracy"], 'o-', color='skyblue',
label='ResNet50V2')
plt.plot(CNN_RESULTS["train_accuracy"], 'o-', color='lightgreen',
label='Custom CNN')
plt.title("Training Accuracy", fontsize=12, fontweight="bold")
plt.xlabel("Epochs", fontsize=10)
plt.ylabel("Accuracy", fontsize=10)
plt.legend()
plt.grid(True, alpha=0.3)

# Validation Accuracy
plt.subplot(2, 2, 4)
plt.plot(MODEL_RESULTS["valid_accuracy"], 'o-', color='orange',
label='ViT')
plt.plot(RESNET_RESULTS["valid_accuracy"], 'o-', color='skyblue',
label='ResNet50V2')
plt.plot(CNN_RESULTS["valid_accuracy"], 'o-', color='lightgreen',
label='Custom CNN')
plt.title("Validation Accuracy", fontsize=12, fontweight="bold")
plt.xlabel("Epochs", fontsize=10)
plt.ylabel("Accuracy", fontsize=10)
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

Downloading: "https://download.pytorch.org/models/resnet50-
11ad3fa6.pth" to /root/.cache/torch/hub/checkpoints/resnet50-
11ad3fa6.pth
100%|██████████| 97.8M/97.8M [00:00<00:00, 178MB/s]

==================================================
Training ResNet50V2 model
==================================================

{"model_id":"949cdceee7e340a38b38db2cf219f103","version_major":2,"vers
ion_minor":0}

Epoch: 1 | Train Loss: 1.5718 | Train Accuracy: 0.4806 | Valid Loss:


1.1950 | Valid Accuracy: 0.8031
Epoch: 2 | Train Loss: 1.0278 | Train Accuracy: 0.7861 | Valid Loss:
0.8868 | Valid Accuracy: 0.8500
Epoch: 3 | Train Loss: 0.8326 | Train Accuracy: 0.7826 | Valid Loss:
0.7333 | Valid Accuracy: 0.8750
Epoch: 4 | Train Loss: 0.7134 | Train Accuracy: 0.8403 | Valid Loss:
0.6577 | Valid Accuracy: 0.8656
Epoch: 5 | Train Loss: 0.5928 | Train Accuracy: 0.8889 | Valid Loss:
0.5573 | Valid Accuracy: 0.9219
Epoch: 6 | Train Loss: 0.5217 | Train Accuracy: 0.8833 | Valid Loss:
0.5437 | Valid Accuracy: 0.9531
Epoch: 7 | Train Loss: 0.4264 | Train Accuracy: 0.9340 | Valid Loss:
0.4592 | Valid Accuracy: 0.9219
Epoch: 8 | Train Loss: 0.3972 | Train Accuracy: 0.9167 | Valid Loss:
0.4672 | Valid Accuracy: 0.9531
Epoch: 9 | Train Loss: 0.3662 | Train Accuracy: 0.9271 | Valid Loss:
0.4590 | Valid Accuracy: 0.9437
Epoch: 10 | Train Loss: 0.3815 | Train Accuracy: 0.9132 | Valid Loss:
0.3892 | Valid Accuracy: 0.9437
Epoch: 11 | Train Loss: 0.3403 | Train Accuracy: 0.9271 | Valid Loss:
0.3802 | Valid Accuracy: 0.9531
Epoch: 12 | Train Loss: 0.3014 | Train Accuracy: 0.9493 | Valid Loss:
0.3681 | Valid Accuracy: 0.9281
Epoch: 13 | Train Loss: 0.2895 | Train Accuracy: 0.9375 | Valid Loss:
0.3634 | Valid Accuracy: 0.9375
Epoch: 14 | Train Loss: 0.3143 | Train Accuracy: 0.9306 | Valid Loss:
0.3535 | Valid Accuracy: 0.9531
Epoch: 15 | Train Loss: 0.2626 | Train Accuracy: 0.9549 | Valid Loss:
0.3280 | Valid Accuracy: 0.9437
Epoch: 16 | Train Loss: 0.2318 | Train Accuracy: 0.9792 | Valid Loss:
0.3155 | Valid Accuracy: 0.9531
Epoch: 17 | Train Loss: 0.2504 | Train Accuracy: 0.9458 | Valid Loss:
0.3347 | Valid Accuracy: 0.9531
Epoch: 18 | Train Loss: 0.2265 | Train Accuracy: 0.9458 | Valid Loss:
0.3109 | Valid Accuracy: 0.9531
Epoch: 19 | Train Loss: 0.2462 | Train Accuracy: 0.9493 | Valid Loss:
0.3066 | Valid Accuracy: 0.9437
Epoch: 20 | Train Loss: 0.1704 | Train Accuracy: 0.9861 | Valid Loss:
0.2662 | Valid Accuracy: 0.9531
Epoch: 21 | Train Loss: 0.1819 | Train Accuracy: 0.9792 | Valid Loss:
0.2883 | Valid Accuracy: 0.9531
Epoch: 22 | Train Loss: 0.1624 | Train Accuracy: 0.9861 | Valid Loss:
0.3047 | Valid Accuracy: 0.9437
Epoch: 23 | Train Loss: 0.1594 | Train Accuracy: 0.9792 | Valid Loss:
0.2776 | Valid Accuracy: 0.9531
Epoch: 24 | Train Loss: 0.2132 | Train Accuracy: 0.9549 | Valid Loss:
0.2530 | Valid Accuracy: 0.9531
Epoch: 25 | Train Loss: 0.1813 | Train Accuracy: 0.9583 | Valid Loss:
0.2687 | Valid Accuracy: 0.9531
Epoch: 26 | Train Loss: 0.1360 | Train Accuracy: 0.9722 | Valid Loss:
0.2605 | Valid Accuracy: 0.9531
Epoch: 27 | Train Loss: 0.1602 | Train Accuracy: 0.9667 | Valid Loss:
0.3095 | Valid Accuracy: 0.9437
Epoch: 28 | Train Loss: 0.1728 | Train Accuracy: 0.9611 | Valid Loss:
0.2683 | Valid Accuracy: 0.9531
Epoch: 29 | Train Loss: 0.1384 | Train Accuracy: 0.9722 | Valid Loss:
0.2870 | Valid Accuracy: 0.9531
Epoch: 30 | Train Loss: 0.1569 | Train Accuracy: 0.9701 | Valid Loss:
0.3169 | Valid Accuracy: 0.9437
Epoch: 31 | Train Loss: 0.1381 | Train Accuracy: 0.9826 | Valid Loss:
0.2970 | Valid Accuracy: 0.9281
Epoch: 32 | Train Loss: 0.1178 | Train Accuracy: 0.9806 | Valid Loss:
0.2536 | Valid Accuracy: 0.9375
Epoch: 33 | Train Loss: 0.0942 | Train Accuracy: 0.9944 | Valid Loss:
0.2679 | Valid Accuracy: 0.9531
Epoch: 34 | Train Loss: 0.1322 | Train Accuracy: 0.9792 | Valid Loss:
0.2343 | Valid Accuracy: 0.9531
Epoch: 35 | Train Loss: 0.1185 | Train Accuracy: 0.9840 | Valid Loss:
0.2511 | Valid Accuracy: 0.9375
Epoch: 36 | Train Loss: 0.1085 | Train Accuracy: 0.9757 | Valid Loss:
0.2240 | Valid Accuracy: 0.9531
Epoch: 37 | Train Loss: 0.1171 | Train Accuracy: 0.9826 | Valid Loss:
0.2646 | Valid Accuracy: 0.9375
Epoch: 38 | Train Loss: 0.1108 | Train Accuracy: 0.9826 | Valid Loss:
0.2709 | Valid Accuracy: 0.9125
Epoch: 39 | Train Loss: 0.1329 | Train Accuracy: 0.9771 | Valid Loss:
0.2342 | Valid Accuracy: 0.9531
Epoch: 40 | Train Loss: 0.1219 | Train Accuracy: 0.9757 | Valid Loss:
0.2407 | Valid Accuracy: 0.9375
Epoch: 41 | Train Loss: 0.1265 | Train Accuracy: 0.9736 | Valid Loss:
0.2801 | Valid Accuracy: 0.9125
Epoch: 42 | Train Loss: 0.1051 | Train Accuracy: 0.9826 | Valid Loss:
0.2559 | Valid Accuracy: 0.9437
Epoch: 43 | Train Loss: 0.1114 | Train Accuracy: 0.9806 | Valid Loss:
0.2364 | Valid Accuracy: 0.9281
Epoch: 44 | Train Loss: 0.0810 | Train Accuracy: 0.9931 | Valid Loss:
0.2367 | Valid Accuracy: 0.9531
Epoch: 45 | Train Loss: 0.0828 | Train Accuracy: 0.9896 | Valid Loss:
0.2457 | Valid Accuracy: 0.9531
Epoch: 46 | Train Loss: 0.1044 | Train Accuracy: 0.9875 | Valid Loss:
0.2555 | Valid Accuracy: 0.9531
Epoch: 47 | Train Loss: 0.1182 | Train Accuracy: 0.9792 | Valid Loss:
0.2231 | Valid Accuracy: 0.9375
Epoch: 48 | Train Loss: 0.0822 | Train Accuracy: 0.9840 | Valid Loss:
0.2732 | Valid Accuracy: 0.9437
Epoch: 49 | Train Loss: 0.0920 | Train Accuracy: 0.9896 | Valid Loss:
0.2922 | Valid Accuracy: 0.9125
Epoch: 50 | Train Loss: 0.0732 | Train Accuracy: 0.9965 | Valid Loss:
0.2633 | Valid Accuracy: 0.9344
Epoch: 51 | Train Loss: 0.0722 | Train Accuracy: 0.9965 | Valid Loss:
0.2211 | Valid Accuracy: 0.9375
Epoch: 52 | Train Loss: 0.0633 | Train Accuracy: 0.9931 | Valid Loss:
0.2390 | Valid Accuracy: 0.9375
Epoch: 53 | Train Loss: 0.0745 | Train Accuracy: 0.9931 | Valid Loss:
0.2262 | Valid Accuracy: 0.9531
Epoch: 54 | Train Loss: 0.0714 | Train Accuracy: 0.9931 | Valid Loss:
0.2503 | Valid Accuracy: 0.9531
Epoch: 55 | Train Loss: 0.0868 | Train Accuracy: 0.9896 | Valid Loss:
0.3058 | Valid Accuracy: 0.9281
Epoch: 56 | Train Loss: 0.1033 | Train Accuracy: 0.9757 | Valid Loss:
0.2441 | Valid Accuracy: 0.9375
Epoch: 57 | Train Loss: 0.0821 | Train Accuracy: 0.9826 | Valid Loss:
0.2072 | Valid Accuracy: 0.9531
Epoch: 58 | Train Loss: 0.0767 | Train Accuracy: 0.9826 | Valid Loss:
0.2189 | Valid Accuracy: 0.9531
Epoch: 59 | Train Loss: 0.0558 | Train Accuracy: 0.9931 | Valid Loss:
0.2821 | Valid Accuracy: 0.9281
Epoch: 60 | Train Loss: 0.0694 | Train Accuracy: 0.9965 | Valid Loss:
0.2130 | Valid Accuracy: 0.9375
Epoch: 61 | Train Loss: 0.0805 | Train Accuracy: 0.9806 | Valid Loss:
0.2759 | Valid Accuracy: 0.9375
Epoch: 62 | Train Loss: 0.0850 | Train Accuracy: 0.9826 | Valid Loss:
0.3042 | Valid Accuracy: 0.9437
Epoch: 63 | Train Loss: 0.0546 | Train Accuracy: 1.0000 | Valid Loss:
0.2507 | Valid Accuracy: 0.9531
Epoch: 64 | Train Loss: 0.0414 | Train Accuracy: 1.0000 | Valid Loss:
0.2595 | Valid Accuracy: 0.9375
Epoch: 65 | Train Loss: 0.0705 | Train Accuracy: 0.9931 | Valid Loss:
0.2315 | Valid Accuracy: 0.9375
Epoch: 66 | Train Loss: 0.0711 | Train Accuracy: 0.9896 | Valid Loss:
0.3221 | Valid Accuracy: 0.9344
Epoch: 67 | Train Loss: 0.0669 | Train Accuracy: 0.9931 | Valid Loss:
0.2135 | Valid Accuracy: 0.9375
Epoch: 68 | Train Loss: 0.0870 | Train Accuracy: 0.9792 | Valid Loss:
0.2585 | Valid Accuracy: 0.9375
Epoch: 69 | Train Loss: 0.0450 | Train Accuracy: 0.9965 | Valid Loss:
0.2396 | Valid Accuracy: 0.9375
Epoch: 70 | Train Loss: 0.0497 | Train Accuracy: 0.9931 | Valid Loss:
0.2108 | Valid Accuracy: 0.9531
Epoch: 71 | Train Loss: 0.0748 | Train Accuracy: 0.9896 | Valid Loss:
0.2353 | Valid Accuracy: 0.9375
Epoch: 72 | Train Loss: 0.0646 | Train Accuracy: 0.9861 | Valid Loss:
0.2475 | Valid Accuracy: 0.9688
Epoch: 73 | Train Loss: 0.0425 | Train Accuracy: 1.0000 | Valid Loss:
0.2581 | Valid Accuracy: 0.9531
Epoch: 74 | Train Loss: 0.0504 | Train Accuracy: 0.9931 | Valid Loss:
0.2430 | Valid Accuracy: 0.9375
Epoch: 75 | Train Loss: 0.0734 | Train Accuracy: 0.9792 | Valid Loss:
0.2053 | Valid Accuracy: 0.9688
Epoch: 76 | Train Loss: 0.0389 | Train Accuracy: 1.0000 | Valid Loss:
0.2503 | Valid Accuracy: 0.9531
Epoch: 77 | Train Loss: 0.0583 | Train Accuracy: 0.9889 | Valid Loss:
0.2012 | Valid Accuracy: 0.9375
Epoch: 78 | Train Loss: 0.0677 | Train Accuracy: 0.9826 | Valid Loss:
0.2732 | Valid Accuracy: 0.9375
Epoch: 79 | Train Loss: 0.0647 | Train Accuracy: 0.9896 | Valid Loss:
0.2295 | Valid Accuracy: 0.9688
Epoch: 80 | Train Loss: 0.0393 | Train Accuracy: 0.9965 | Valid Loss:
0.1992 | Valid Accuracy: 0.9688
Epoch: 81 | Train Loss: 0.0606 | Train Accuracy: 1.0000 | Valid Loss:
0.2411 | Valid Accuracy: 0.9375
Epoch: 82 | Train Loss: 0.0382 | Train Accuracy: 1.0000 | Valid Loss:
0.2319 | Valid Accuracy: 0.9531
Epoch: 83 | Train Loss: 0.0360 | Train Accuracy: 1.0000 | Valid Loss:
0.2814 | Valid Accuracy: 0.9531
Epoch: 84 | Train Loss: 0.0499 | Train Accuracy: 0.9931 | Valid Loss:
0.2365 | Valid Accuracy: 0.9437
Epoch: 85 | Train Loss: 0.0376 | Train Accuracy: 1.0000 | Valid Loss:
0.2301 | Valid Accuracy: 0.9437
Epoch: 86 | Train Loss: 0.0383 | Train Accuracy: 0.9931 | Valid Loss:
0.2504 | Valid Accuracy: 0.9437
Epoch: 87 | Train Loss: 0.0448 | Train Accuracy: 1.0000 | Valid Loss:
0.2461 | Valid Accuracy: 0.9375
Epoch: 88 | Train Loss: 0.0654 | Train Accuracy: 0.9875 | Valid Loss:
0.2232 | Valid Accuracy: 0.9375
Epoch: 89 | Train Loss: 0.0530 | Train Accuracy: 0.9965 | Valid Loss:
0.3191 | Valid Accuracy: 0.9437
Epoch: 90 | Train Loss: 0.0386 | Train Accuracy: 0.9965 | Valid Loss:
0.2151 | Valid Accuracy: 0.9531
Epoch: 91 | Train Loss: 0.0536 | Train Accuracy: 0.9840 | Valid Loss:
0.2392 | Valid Accuracy: 0.9375
Epoch: 92 | Train Loss: 0.0546 | Train Accuracy: 0.9931 | Valid Loss:
0.2773 | Valid Accuracy: 0.9281
Epoch: 93 | Train Loss: 0.0317 | Train Accuracy: 0.9965 | Valid Loss:
0.2407 | Valid Accuracy: 0.9375
Epoch: 94 | Train Loss: 0.0402 | Train Accuracy: 0.9965 | Valid Loss:
0.2347 | Valid Accuracy: 0.9688
Epoch: 95 | Train Loss: 0.0534 | Train Accuracy: 0.9896 | Valid Loss:
0.2394 | Valid Accuracy: 0.9531
Epoch: 96 | Train Loss: 0.0510 | Train Accuracy: 0.9875 | Valid Loss:
0.2431 | Valid Accuracy: 0.9437
Epoch: 97 | Train Loss: 0.0493 | Train Accuracy: 0.9896 | Valid Loss:
0.2556 | Valid Accuracy: 0.9281
Epoch: 98 | Train Loss: 0.0414 | Train Accuracy: 0.9931 | Valid Loss:
0.2134 | Valid Accuracy: 0.9437
Epoch: 99 | Train Loss: 0.0410 | Train Accuracy: 0.9931 | Valid Loss:
0.2423 | Valid Accuracy: 0.9531
Epoch: 100 | Train Loss: 0.0663 | Train Accuracy: 0.9826 | Valid Loss:
0.2396 | Valid Accuracy: 0.9531
==================================================
Training Custom CNN model
==================================================

{"model_id":"afb7427359e84896b6b6ead4b9b8de68","version_major":2,"vers
ion_minor":0}

Epoch: 1 | Train Loss: 18.4033 | Train Accuracy: 0.3090 | Valid Loss:


3.1055 | Valid Accuracy: 0.5094
Epoch: 2 | Train Loss: 5.6784 | Train Accuracy: 0.4049 | Valid Loss:
1.5644 | Valid Accuracy: 0.5719
Epoch: 3 | Train Loss: 2.1706 | Train Accuracy: 0.4639 | Valid Loss:
0.9089 | Valid Accuracy: 0.6250
Epoch: 4 | Train Loss: 1.4060 | Train Accuracy: 0.4812 | Valid Loss:
1.2037 | Valid Accuracy: 0.4719
Epoch: 5 | Train Loss: 1.3996 | Train Accuracy: 0.4396 | Valid Loss:
0.9099 | Valid Accuracy: 0.6562
Epoch: 6 | Train Loss: 1.3009 | Train Accuracy: 0.4958 | Valid Loss:
0.8278 | Valid Accuracy: 0.6781
Epoch: 7 | Train Loss: 1.2410 | Train Accuracy: 0.4917 | Valid Loss:
0.9385 | Valid Accuracy: 0.5750
Epoch: 8 | Train Loss: 1.3735 | Train Accuracy: 0.4486 | Valid Loss:
0.9194 | Valid Accuracy: 0.6156
Epoch: 9 | Train Loss: 1.2863 | Train Accuracy: 0.4778 | Valid Loss:
0.8327 | Valid Accuracy: 0.6531
Epoch: 10 | Train Loss: 1.1629 | Train Accuracy: 0.5410 | Valid Loss:
1.0235 | Valid Accuracy: 0.5437
Epoch: 11 | Train Loss: 1.1892 | Train Accuracy: 0.5236 | Valid Loss:
0.8788 | Valid Accuracy: 0.6625
Epoch: 12 | Train Loss: 1.0551 | Train Accuracy: 0.5604 | Valid Loss:
0.7719 | Valid Accuracy: 0.6375
Epoch: 13 | Train Loss: 1.2097 | Train Accuracy: 0.5688 | Valid Loss:
1.0449 | Valid Accuracy: 0.6469
Epoch: 14 | Train Loss: 1.1190 | Train Accuracy: 0.5292 | Valid Loss:
0.8246 | Valid Accuracy: 0.6625
Epoch: 15 | Train Loss: 1.0254 | Train Accuracy: 0.6035 | Valid Loss:
0.8358 | Valid Accuracy: 0.6562
Epoch: 16 | Train Loss: 1.2347 | Train Accuracy: 0.5604 | Valid Loss:
0.8857 | Valid Accuracy: 0.6156
Epoch: 17 | Train Loss: 1.1875 | Train Accuracy: 0.6069 | Valid Loss:
1.0164 | Valid Accuracy: 0.5656
Epoch: 18 | Train Loss: 1.0494 | Train Accuracy: 0.5701 | Valid Loss:
0.8972 | Valid Accuracy: 0.6438
Epoch: 19 | Train Loss: 0.9590 | Train Accuracy: 0.6292 | Valid Loss:
0.8744 | Valid Accuracy: 0.7094
Epoch: 20 | Train Loss: 1.0713 | Train Accuracy: 0.5681 | Valid Loss:
0.8256 | Valid Accuracy: 0.5437
Epoch: 21 | Train Loss: 1.0110 | Train Accuracy: 0.6278 | Valid Loss:
0.9490 | Valid Accuracy: 0.7469
Epoch: 22 | Train Loss: 1.0295 | Train Accuracy: 0.5958 | Valid Loss:
1.0519 | Valid Accuracy: 0.6281
Epoch: 23 | Train Loss: 0.9566 | Train Accuracy: 0.6187 | Valid Loss:
0.7727 | Valid Accuracy: 0.7094
Epoch: 24 | Train Loss: 0.9212 | Train Accuracy: 0.6556 | Valid Loss:
0.7588 | Valid Accuracy: 0.7875
Epoch: 25 | Train Loss: 0.9498 | Train Accuracy: 0.6465 | Valid Loss:
1.0597 | Valid Accuracy: 0.7406
Epoch: 26 | Train Loss: 1.0937 | Train Accuracy: 0.5653 | Valid Loss:
0.8103 | Valid Accuracy: 0.6000
Epoch: 27 | Train Loss: 0.9567 | Train Accuracy: 0.6500 | Valid Loss:
0.8138 | Valid Accuracy: 0.7500
Epoch: 28 | Train Loss: 0.9659 | Train Accuracy: 0.6326 | Valid Loss:
0.9784 | Valid Accuracy: 0.7094
Epoch: 29 | Train Loss: 0.9660 | Train Accuracy: 0.6299 | Valid Loss:
0.8719 | Valid Accuracy: 0.6625
Epoch: 30 | Train Loss: 0.8980 | Train Accuracy: 0.6486 | Valid Loss:
1.2152 | Valid Accuracy: 0.5531
Epoch: 31 | Train Loss: 0.9433 | Train Accuracy: 0.6201 | Valid Loss:
0.8151 | Valid Accuracy: 0.7250
Epoch: 32 | Train Loss: 0.9149 | Train Accuracy: 0.6639 | Valid Loss:
0.8699 | Valid Accuracy: 0.7188
Epoch: 33 | Train Loss: 0.9024 | Train Accuracy: 0.6778 | Valid Loss:
1.0495 | Valid Accuracy: 0.6531
Epoch: 34 | Train Loss: 0.9078 | Train Accuracy: 0.6750 | Valid Loss:
0.7348 | Valid Accuracy: 0.7406
Epoch: 35 | Train Loss: 0.8663 | Train Accuracy: 0.6750 | Valid Loss:
0.9129 | Valid Accuracy: 0.6656
Epoch: 36 | Train Loss: 0.7986 | Train Accuracy: 0.6847 | Valid Loss:
0.8336 | Valid Accuracy: 0.7344
Epoch: 37 | Train Loss: 0.7425 | Train Accuracy: 0.7444 | Valid Loss:
1.0626 | Valid Accuracy: 0.7344
Epoch: 38 | Train Loss: 0.7371 | Train Accuracy: 0.7563 | Valid Loss:
1.1364 | Valid Accuracy: 0.7000
Epoch: 39 | Train Loss: 0.6272 | Train Accuracy: 0.7563 | Valid Loss:
1.1371 | Valid Accuracy: 0.7625
Epoch: 40 | Train Loss: 0.7429 | Train Accuracy: 0.7604 | Valid Loss:
1.2168 | Valid Accuracy: 0.6406
Epoch: 41 | Train Loss: 0.7696 | Train Accuracy: 0.7229 | Valid Loss:
1.0839 | Valid Accuracy: 0.6562
Epoch: 42 | Train Loss: 0.8602 | Train Accuracy: 0.6792 | Valid Loss:
0.8539 | Valid Accuracy: 0.7156
Epoch: 43 | Train Loss: 0.6384 | Train Accuracy: 0.7549 | Valid Loss:
0.7839 | Valid Accuracy: 0.7312
Epoch: 44 | Train Loss: 0.6205 | Train Accuracy: 0.7861 | Valid Loss:
0.7532 | Valid Accuracy: 0.8344
Epoch: 45 | Train Loss: 0.6115 | Train Accuracy: 0.7854 | Valid Loss:
0.7032 | Valid Accuracy: 0.8031
Epoch: 46 | Train Loss: 0.6008 | Train Accuracy: 0.7931 | Valid Loss:
0.7309 | Valid Accuracy: 0.7406
Epoch: 47 | Train Loss: 0.4866 | Train Accuracy: 0.8153 | Valid Loss:
0.6615 | Valid Accuracy: 0.7625
Epoch: 48 | Train Loss: 0.5318 | Train Accuracy: 0.8160 | Valid Loss:
0.9431 | Valid Accuracy: 0.7781
Epoch: 49 | Train Loss: 0.6761 | Train Accuracy: 0.7507 | Valid Loss:
0.9559 | Valid Accuracy: 0.7875
Epoch: 50 | Train Loss: 0.4549 | Train Accuracy: 0.8361 | Valid Loss:
0.8313 | Valid Accuracy: 0.7875
Epoch: 51 | Train Loss: 0.6808 | Train Accuracy: 0.7847 | Valid Loss:
0.7034 | Valid Accuracy: 0.7969
Epoch: 52 | Train Loss: 0.5575 | Train Accuracy: 0.8035 | Valid Loss:
0.7933 | Valid Accuracy: 0.8281
Epoch: 53 | Train Loss: 0.5371 | Train Accuracy: 0.8160 | Valid Loss:
0.9302 | Valid Accuracy: 0.7344
Epoch: 54 | Train Loss: 0.4785 | Train Accuracy: 0.8382 | Valid Loss:
1.2874 | Valid Accuracy: 0.6813
Epoch: 55 | Train Loss: 0.4938 | Train Accuracy: 0.8208 | Valid Loss:
0.5556 | Valid Accuracy: 0.8594
Epoch: 56 | Train Loss: 0.5929 | Train Accuracy: 0.8000 | Valid Loss:
0.8931 | Valid Accuracy: 0.7500
Epoch: 57 | Train Loss: 0.4961 | Train Accuracy: 0.8347 | Valid Loss:
0.8337 | Valid Accuracy: 0.7719
Epoch: 58 | Train Loss: 0.5183 | Train Accuracy: 0.8000 | Valid Loss:
1.0412 | Valid Accuracy: 0.7875
Epoch: 59 | Train Loss: 0.4300 | Train Accuracy: 0.8729 | Valid Loss:
0.8241 | Valid Accuracy: 0.7562
Epoch: 60 | Train Loss: 0.4895 | Train Accuracy: 0.8764 | Valid Loss:
0.8840 | Valid Accuracy: 0.7469
Epoch: 61 | Train Loss: 0.2679 | Train Accuracy: 0.9306 | Valid Loss:
0.9990 | Valid Accuracy: 0.7469
Epoch: 62 | Train Loss: 0.3059 | Train Accuracy: 0.8889 | Valid Loss:
1.7261 | Valid Accuracy: 0.6438
Epoch: 63 | Train Loss: 0.4582 | Train Accuracy: 0.8799 | Valid Loss:
0.6878 | Valid Accuracy: 0.7781
Epoch: 64 | Train Loss: 0.4261 | Train Accuracy: 0.8472 | Valid Loss:
0.6295 | Valid Accuracy: 0.7719
Epoch: 65 | Train Loss: 0.4150 | Train Accuracy: 0.8833 | Valid Loss:
0.7357 | Valid Accuracy: 0.8031
Epoch: 66 | Train Loss: 0.4510 | Train Accuracy: 0.8576 | Valid Loss:
0.6470 | Valid Accuracy: 0.8281
Epoch: 67 | Train Loss: 0.4317 | Train Accuracy: 0.8729 | Valid Loss:
0.5838 | Valid Accuracy: 0.8438
Epoch: 68 | Train Loss: 0.3381 | Train Accuracy: 0.8854 | Valid Loss:
0.8505 | Valid Accuracy: 0.7937
Epoch: 69 | Train Loss: 0.3429 | Train Accuracy: 0.8674 | Valid Loss:
0.7819 | Valid Accuracy: 0.8344
Epoch: 70 | Train Loss: 0.2105 | Train Accuracy: 0.9285 | Valid Loss:
0.9042 | Valid Accuracy: 0.8031
Epoch: 71 | Train Loss: 0.3359 | Train Accuracy: 0.9201 | Valid Loss:
1.2436 | Valid Accuracy: 0.7031
Epoch: 72 | Train Loss: 0.2521 | Train Accuracy: 0.9062 | Valid Loss:
1.0007 | Valid Accuracy: 0.7625
Epoch: 73 | Train Loss: 0.3432 | Train Accuracy: 0.8958 | Valid Loss:
1.1621 | Valid Accuracy: 0.7625
Epoch: 74 | Train Loss: 0.2437 | Train Accuracy: 0.9201 | Valid Loss:
1.0118 | Valid Accuracy: 0.7781
Epoch: 75 | Train Loss: 0.2876 | Train Accuracy: 0.9306 | Valid Loss:
1.6021 | Valid Accuracy: 0.7375
Epoch: 76 | Train Loss: 0.2014 | Train Accuracy: 0.9201 | Valid Loss:
1.1883 | Valid Accuracy: 0.8094
Epoch: 77 | Train Loss: 0.1693 | Train Accuracy: 0.9306 | Valid Loss:
0.9617 | Valid Accuracy: 0.8281
Epoch: 78 | Train Loss: 0.3452 | Train Accuracy: 0.8958 | Valid Loss:
1.0942 | Valid Accuracy: 0.7812
Epoch: 79 | Train Loss: 0.4686 | Train Accuracy: 0.8708 | Valid Loss:
1.1179 | Valid Accuracy: 0.7656
Epoch: 80 | Train Loss: 0.3303 | Train Accuracy: 0.9097 | Valid Loss:
0.6799 | Valid Accuracy: 0.8187
Epoch: 81 | Train Loss: 0.1714 | Train Accuracy: 0.9410 | Valid Loss:
0.9971 | Valid Accuracy: 0.7562
Epoch: 82 | Train Loss: 0.2425 | Train Accuracy: 0.9236 | Valid Loss:
0.8817 | Valid Accuracy: 0.7812
Epoch: 83 | Train Loss: 0.3929 | Train Accuracy: 0.8889 | Valid Loss:
0.8224 | Valid Accuracy: 0.8281
Epoch: 84 | Train Loss: 0.3475 | Train Accuracy: 0.9028 | Valid Loss:
0.9001 | Valid Accuracy: 0.7937
Epoch: 85 | Train Loss: 0.4059 | Train Accuracy: 0.9007 | Valid Loss:
0.9966 | Valid Accuracy: 0.8344
Epoch: 86 | Train Loss: 0.3762 | Train Accuracy: 0.8681 | Valid Loss:
1.2866 | Valid Accuracy: 0.6937
Epoch: 87 | Train Loss: 0.1977 | Train Accuracy: 0.9340 | Valid Loss:
1.3225 | Valid Accuracy: 0.7562
Epoch: 88 | Train Loss: 0.3232 | Train Accuracy: 0.9236 | Valid Loss:
1.1568 | Valid Accuracy: 0.8031
Epoch: 89 | Train Loss: 0.2614 | Train Accuracy: 0.9146 | Valid Loss:
0.7791 | Valid Accuracy: 0.8031
Epoch: 90 | Train Loss: 0.2596 | Train Accuracy: 0.9250 | Valid Loss:
1.3653 | Valid Accuracy: 0.7312
Epoch: 91 | Train Loss: 0.2549 | Train Accuracy: 0.9306 | Valid Loss:
0.7809 | Valid Accuracy: 0.8438
Epoch: 92 | Train Loss: 0.1772 | Train Accuracy: 0.9562 | Valid Loss:
1.0504 | Valid Accuracy: 0.8656
Epoch: 93 | Train Loss: 0.1642 | Train Accuracy: 0.9549 | Valid Loss:
1.0253 | Valid Accuracy: 0.8187
Epoch: 94 | Train Loss: 0.2157 | Train Accuracy: 0.9340 | Valid Loss:
1.4641 | Valid Accuracy: 0.8094
Epoch: 95 | Train Loss: 0.2038 | Train Accuracy: 0.9424 | Valid Loss:
0.9025 | Valid Accuracy: 0.8438
Epoch: 96 | Train Loss: 0.1876 | Train Accuracy: 0.9479 | Valid Loss:
0.7463 | Valid Accuracy: 0.8344
Epoch: 97 | Train Loss: 0.1228 | Train Accuracy: 0.9410 | Valid Loss:
0.8377 | Valid Accuracy: 0.7875
Epoch: 98 | Train Loss: 0.1539 | Train Accuracy: 0.9597 | Valid Loss:
0.9082 | Valid Accuracy: 0.8500
Epoch: 99 | Train Loss: 0.0907 | Train Accuracy: 0.9688 | Valid Loss:
1.4059 | Valid Accuracy: 0.7531
Epoch: 100 | Train Loss: 0.1717 | Train Accuracy: 0.9597 | Valid Loss:
1.0781 | Valid Accuracy: 0.7688

{"model_id":"d1e86ab2cc074314b9cf63fce9314e88","version_major":2,"vers
ion_minor":0}

ResNet50V2 Test Accuracy = 0.9032


{"model_id":"caa2e57f58bb4cc2bfedf6effcb7930b","version_major":2,"vers
ion_minor":0}

Custom CNN Test Accuracy = 0.629


from sklearn.metrics import accuracy_score, precision_score,
recall_score, f1_score, classification_report, confusion_matrix
import matplotlib.pyplot as plt
import seaborn as sns

# Convert ground truth labels and model predictions to numpy arrays


true_labels = df_test["label"].map(label_map).values

# ----------------------------- ResNet50V2 Evaluation


-----------------------------
resnet_pred = resnet_preds.numpy()

print("ResNet50V2 Evaluation Metrics:")


accuracy_resnet = accuracy_score(true_labels, resnet_pred)
precision_resnet = precision_score(true_labels, resnet_pred,
average="macro")
recall_resnet = recall_score(true_labels, resnet_pred,
average="macro")
f1_resnet = f1_score(true_labels, resnet_pred, average="macro")

print(f"Accuracy: {accuracy_resnet:.4f}")
print(f"Precision: {precision_resnet:.4f}")
print(f"Recall: {recall_resnet:.4f}")
print(f"F1 Score: {f1_resnet:.4f}")
print("\nClassification Report:")
print(classification_report(true_labels, resnet_pred,
target_names=classes))

cm_resnet = confusion_matrix(true_labels, resnet_pred)


plt.figure(figsize=(10, 4.5))
sns.heatmap(cm_resnet, cmap="Blues", annot=True,
annot_kws={"fontsize":9, "fontweight":"bold"},
linewidths=1.2, fmt="d", linecolor="white", square=True,
xticklabels=classes, yticklabels=classes, cbar=False)
plt.title("ResNet50V2 Confusion Matrix", fontsize=15,
fontweight="bold", color="darkblue")
plt.xlabel("Predicted Classes", fontsize=12, fontweight="bold",
color="black")
plt.ylabel("True Classes", fontsize=12, fontweight="bold",
color="black")
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()

# ----------------------------- Custom CNN Evaluation


-----------------------------
cnn_pred = cnn_preds.numpy()

print("Custom CNN Evaluation Metrics:")


accuracy_cnn = accuracy_score(true_labels, cnn_pred)
precision_cnn = precision_score(true_labels, cnn_pred,
average="macro")
recall_cnn = recall_score(true_labels, cnn_pred, average="macro")
f1_cnn = f1_score(true_labels, cnn_pred, average="macro")

print(f"Accuracy: {accuracy_cnn:.4f}")
print(f"Precision: {precision_cnn:.4f}")
print(f"Recall: {recall_cnn:.4f}")
print(f"F1 Score: {f1_cnn:.4f}")
print("\nClassification Report:")
print(classification_report(true_labels, cnn_pred,
target_names=classes))

cm_cnn = confusion_matrix(true_labels, cnn_pred)


plt.figure(figsize=(10, 4.5))
sns.heatmap(cm_cnn, cmap="Blues", annot=True, annot_kws={"fontsize":9,
"fontweight":"bold"},
linewidths=1.2, fmt="d", linecolor="white", square=True,
xticklabels=classes, yticklabels=classes, cbar=False)
plt.title("Custom CNN Confusion Matrix", fontsize=15,
fontweight="bold", color="darkblue")
plt.xlabel("Predicted Classes", fontsize=12, fontweight="bold",
color="black")
plt.ylabel("True Classes", fontsize=12, fontweight="bold",
color="black")
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()

ResNet50V2 Evaluation Metrics:


Accuracy: 0.9032
Precision: 0.8813
Recall: 0.9144
F1 Score: 0.8923

Classification Report:
precision recall f1-score
support

Banana Black Sigatoka Disease 0.88 0.70 0.78


10
Banana Bract Mosaic Virus Disease 0.89 1.00 0.94
8
Banana Healthy Leaf 1.00 1.00 1.00
13
Banana Insect Pest Disease 0.92 0.92 0.92
13
Banana Moko Disease 0.88 0.78 0.82
9
Banana Panama Disease 0.86 1.00 0.92
6
Banana Yellow Sigatoka Disease 0.75 1.00 0.86
3

accuracy 0.90
62
macro avg 0.88 0.91 0.89
62
weighted avg 0.91 0.90 0.90
62
Custom CNN Evaluation Metrics:
Accuracy: 0.6290
Precision: 0.6514
Recall: 0.6237
F1 Score: 0.6073

Classification Report:
precision recall f1-score
support

Banana Black Sigatoka Disease 0.43 0.30 0.35


10
Banana Bract Mosaic Virus Disease 0.40 0.75 0.52
8
Banana Healthy Leaf 0.76 1.00 0.87
13
Banana Insect Pest Disease 1.00 0.54 0.70
13
Banana Moko Disease 0.80 0.44 0.57
9
Banana Panama Disease 0.50 0.67 0.57
6
Banana Yellow Sigatoka Disease 0.67 0.67 0.67
3
accuracy 0.63
62
macro avg 0.65 0.62 0.61
62
weighted avg 0.69 0.63 0.62
62

You might also like