hamzabinabdulmajeed's picture
Update app.py
fff8926 verified
Raw
History Blame Contribute Delete
4.79 kB
import os
import time
import torch
import torch.nn as nn
from PIL import Image
import pandas as pd
import gradio as gr
from torchvision import models, transforms
# 1. Dynamic Class Identification from your training CSV
CSV_FILE_PATH = "Training_set.csv"
LABEL_COLUMN_NAME = "label"
if os.path.exists(CSV_FILE_PATH):
metadata_df = pd.read_csv(CSV_FILE_PATH)
CLASS_NAMES = sorted(metadata_df[LABEL_COLUMN_NAME].dropna().unique().tolist())
print(f"Dynamically discovered {len(CLASS_NAMES)} classes from CSV.")
else:
CLASS_NAMES = ['Butterfly_Species_1', 'Butterfly_Species_2', 'Butterfly_Species_3']
print(f"WARNING: '{CSV_FILE_PATH}' not found. Defaulting to placeholders.")
NUM_CLASSES = len(CLASS_NAMES)
# 2. Reconstruct Models to Match Your Training Notebook Exactly
# --- Model A: MobileNetV2 (Aug) ---
mobilenet = models.mobilenet_v2(weights=None)
num_features_mono = mobilenet.classifier[1].in_features
mobilenet.classifier = nn.Sequential(
nn.Dropout(p=0.2),
nn.Linear(num_features_mono, NUM_CLASSES)
)
# --- Model B: Unmodified VGG16 (Stock Head) ---
vgg16_stock = models.vgg16(weights=None)
num_features_stock = vgg16_stock.classifier[6].in_features
vgg16_stock.classifier[6] = nn.Linear(num_features_stock, NUM_CLASSES)
# --- Model C: Modified VGG16 with GAP ---
vgg16_gap = models.vgg16(weights=None)
vgg16_gap.avgpool = nn.AdaptiveAvgPool2d((1, 1)) # Replaced avgpool step
vgg16_gap.classifier = nn.Sequential(
nn.Flatten(),
nn.Dropout(p=0.3),
nn.Linear(512, NUM_CLASSES)
)
# 3. Safe Model Checkpoint Loading Strategy
models_dict = {
"MobileNetV2": mobilenet,
"VGG16 (Stock Head)": vgg16_stock,
"VGG16 (GAP Modified Head)": vgg16_gap
}
files_dict = {
"MobileNetV2": "mobilenetv2_butterfly.pth",
"VGG16 (Stock Head)": "unmodified_vgg16_butterfly.pth",
"VGG16 (GAP Modified Head)": "modified_vgg16_gap_butterfly.pth"
}
for name, model in models_dict.items():
file_path = files_dict[name]
if os.path.exists(file_path):
model.load_state_dict(torch.load(file_path, map_location=torch.device('cpu')))
model.eval()
print(f"Successfully loaded {name} weights structure without mismatch.")
else:
print(f"WARNING: Checkpoint file '{file_path}' missing!")
# 4. Processing Pipelines
img_transforms = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
# 5. High Precision Benchmark Handler
def benchmark_inference(input_image):
if input_image is None:
return None
img_tensor = img_transforms(input_image).unsqueeze(0)
results_data = []
with torch.no_grad():
for name, model in models_dict.items():
# Warm-up loop iteration
_ = model(img_tensor)
# Start tracking precision loop speed
start_time = time.perf_counter()
outputs = model(img_tensor)
probabilities = torch.nn.functional.softmax(outputs[0], dim=0)
best_prob, best_class_idx = torch.max(probabilities, dim=0)
end_time = time.perf_counter()
latency_ms = (end_time - start_time) * 1000
predicted_label = CLASS_NAMES[best_class_idx.item()]
confidence_pct = f"{best_prob.item() * 100:.2f}%"
results_data.append({
"Model Architecture Blueprint": name,
"Predicted Butterfly Label": predicted_label,
"Confidence Score": confidence_pct,
"Inference Latency (Milliseconds)": f"{latency_ms:.2f} ms"
})
return pd.DataFrame(results_data)
# 6. Gradio Render Interface
with gr.Blocks(theme=gr.themes.Soft()) as demo:
gr.Markdown("# 🦋 Scenario 1: Butterfly Classifier & Performance Benchmarking Space")
gr.Markdown("Upload an image of a butterfly to compare deployment metrics, classification targets, and computational speed tracking across your models.")
with gr.Row():
with gr.Column(scale=1):
input_img_slot = gr.Image(type="pil", label="Input Target Field Photo File")
submit_btn = gr.Button("Execute Multi-Model Run", variant="primary")
with gr.Column(scale=2):
output_table_slot = gr.Dataframe(
headers=["Model Architecture Blueprint", "Predicted Butterfly Label", "Confidence Score", "Inference Latency (Milliseconds)"],
datatype=["str", "str", "str", "str"],
label="Benchmark Results Table"
)
submit_btn.click(
fn=benchmark_inference,
inputs=input_img_slot,
outputs=output_table_slot
)
demo.launch()