Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import pandas as pd | |
| import numpy as np | |
| from PIL import Image | |
| import os | |
| import time | |
| import cloudpickle | |
| import traceback | |
| # ========================= | |
| # Configuration | |
| # ========================= | |
| IMAGE_SIZE = (64, 64) | |
| LEADERBOARD_PATH = "leaderboard.csv" | |
| LABEL_FILE = "labels.csv" | |
| TEST_DIR = "test_images" | |
| # ========================= | |
| # Helpers | |
| # ========================= | |
| def image_to_features(image: Image.Image) -> np.ndarray: | |
| image = image.resize(IMAGE_SIZE) | |
| return np.array(image.convert("L")).flatten() | |
| def load_test_data(): | |
| if not os.path.exists(LABEL_FILE) or not os.path.exists(TEST_DIR): | |
| raise FileNotFoundError("Missing labels.csv or test_images/ folder.") | |
| df = pd.read_csv(LABEL_FILE) | |
| X_test, y_test = [], [] | |
| for _, row in df.iterrows(): | |
| img_path = os.path.join(TEST_DIR, row["filename"]) | |
| try: | |
| img = Image.open(img_path) | |
| X_test.append(image_to_features(img)) | |
| y_test.append(row["label"]) | |
| except Exception as e: | |
| print(f"β Error loading {img_path}: {e}") | |
| return np.array(X_test), np.array(y_test) | |
| def load_leaderboard(): | |
| if os.path.exists(LEADERBOARD_PATH): | |
| df = pd.read_csv(LEADERBOARD_PATH) | |
| return df.sort_values(by=["Accuracy", "Avg Time (ms)"], ascending=[False, True]).reset_index(drop=True) | |
| else: | |
| df = pd.DataFrame(columns=["Name", "Accuracy", "Avg Time (ms)"]) | |
| df.to_csv(LEADERBOARD_PATH, index=False) | |
| return df | |
| # ========================= | |
| # Evaluation Logic | |
| # ========================= | |
| def evaluate_model(file, name): | |
| try: | |
| with open(file.name, "rb") as f: | |
| model = cloudpickle.load(f) | |
| X_test, y_test = load_test_data() | |
| start = time.time() | |
| y_pred = model.predict(X_test) | |
| elapsed = (time.time() - start) * 1000 | |
| if len(y_pred) != len(y_test): | |
| return "β Model output length does not match test set.", load_leaderboard() | |
| accuracy = round(100.0 * (y_pred == y_test).mean(), 5) | |
| avg_time = round(elapsed / len(X_test), 5) | |
| leaderboard = load_leaderboard() | |
| # Remove existing entries for the same name | |
| leaderboard = leaderboard[leaderboard["Name"] != name] | |
| # Add new result | |
| new_entry = pd.DataFrame([{ | |
| "Name": name, | |
| "Accuracy": accuracy, | |
| "Avg Time (ms)": avg_time | |
| }]) | |
| leaderboard = pd.concat([leaderboard, new_entry], ignore_index=True) | |
| # Keep only the best score per name | |
| leaderboard = leaderboard.sort_values(by=["Accuracy", "Avg Time (ms)"], ascending=[False, True]) | |
| leaderboard = leaderboard.drop_duplicates(subset=["Name"], keep="first").reset_index(drop=True) | |
| leaderboard.to_csv(LEADERBOARD_PATH, index=False) | |
| return "", leaderboard | |
| except Exception as e: | |
| return f"β Error:\n{traceback.format_exc()}", load_leaderboard() | |
| # ========================= | |
| # UI | |
| # ========================= | |
| with gr.Blocks(title="Olive Fly Classifier Leaderboard") as demo: | |
| gr.Markdown("## Olive Fly Classifier Leaderboard") | |
| gr.Markdown( | |
| "Upload your `.cloudpkl` model trained on Olive Fly images. " | |
| "We'll evaluate it and update the leaderboard." | |
| ) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| file_input = gr.File(label="Upload your model") | |
| name_input = gr.Text(label="Your name or team") | |
| submit_btn = gr.Button("Submit model") | |
| error_box = gr.Textbox(label="Output log", visible=True) | |
| leaderboard_table = gr.Dataframe( | |
| label="Leaderboard", | |
| interactive=False, | |
| wrap=True | |
| ) | |
| submit_btn.click( | |
| fn=evaluate_model, | |
| inputs=[file_input, name_input], | |
| outputs=[error_box, leaderboard_table] | |
| ) | |
| # Refresh leaderboard on app launch | |
| demo.load(fn=load_leaderboard, inputs=[], outputs=[leaderboard_table]) | |
| demo.launch() | |