import gradio as gr from PIL import Image import pathlib import os import shutil import zipfile import huggingface_hub from huggingface_hub import hf_hub_download from autogluon.multimodal import MultiModalPredictor import pandas as pd # Model config MODEL_REPO_ID = "cassieli226/sign-identification-automl" ZIP_FILENAME = "autogluon_predictor_dir.zip" CACHE_DIR = pathlib.Path("hf_assets") EXTRACT_DIR = CACHE_DIR / "predictor_native" # Download & load the native predictor def _prepare_predictor_dir() -> str: CACHE_DIR.mkdir(parents=True, exist_ok=True) local_zip = hf_hub_download( repo_id=MODEL_REPO_ID, filename=ZIP_FILENAME, repo_type="model", local_dir=str(CACHE_DIR), local_dir_use_symlinks=False, ) if EXTRACT_DIR.exists(): shutil.rmtree(EXTRACT_DIR) EXTRACT_DIR.mkdir(parents=True, exist_ok=True) with zipfile.ZipFile(local_zip, "r") as zf: zf.extractall(str(EXTRACT_DIR)) contents = list(EXTRACT_DIR.iterdir()) predictor_root = contents[0] if (len(contents) == 1 and contents[0].is_dir()) else EXTRACT_DIR return str(predictor_root) PREDICTOR_DIR = _prepare_predictor_dir() PREDICTOR = MultiModalPredictor.load(PREDICTOR_DIR) clf = PREDICTOR # MultiModalPredictor def predict_image(image, confidence_threshold=0.5, return_probabilities=False): if image is None: return "Please upload an image", "" try: # Wrap the image in a dict for MultiModalPredictor input_df = pd.DataFrame([{"image": image}]) # Make prediction prediction = clf.predict(input_df)[0] detailed = f"**Predicted Class:** {prediction}" if return_probabilities: try: probs = clf.predict_proba(input_df) prob_dict = probs.iloc[0].to_dict() sorted_probs = sorted(prob_dict.items(), key=lambda x: x[1], reverse=True) detailed += "\n\n**Prediction Probabilities:**\n" for class_name, prob in sorted_probs[:5]: if prob >= confidence_threshold: detailed += f"- {class_name}: {prob:.3f}\n" except Exception as e: detailed += f"\n\nNote: Could not retrieve probabilities ({str(e)})" return prediction, detailed except Exception as e: return f"Error: {str(e)}", f"**Error:** {str(e)}" # --- Gradio UI --- with gr.Blocks(title="Image Classifier", theme=gr.themes.Soft()) as demo: gr.Markdown(""" # 🖼️ AI Image Classifier ## Upload an image to get AI-powered classification results """) with gr.Row(): with gr.Column(): image_input = gr.Image(type="pil", label="Upload Image", height=300) gr.Markdown("### 🔧 Inference Parameters") confidence_threshold = gr.Slider(0.0, 1.0, value=0.1, step=0.05, label="Confidence Threshold") return_probabilities = gr.Checkbox(label="Show Prediction Probabilities", value=True) predict_btn = gr.Button("🎯 Classify Image", variant="primary", size="lg") with gr.Column(): prediction_output = gr.Textbox(label="Prediction Result", interactive=False, lines=1) detailed_output = gr.Markdown(label="Detailed Analysis", value="Results will appear here...") predict_btn.click( fn=predict_image, inputs=[image_input, confidence_threshold, return_probabilities], outputs=[prediction_output, detailed_output] ) gr.Markdown(""" --- *Built with AutoGluon and Gradio* """) if __name__ == "__main__": demo.launch()