import os # For filesystem operations import shutil # For directory cleanup import zipfile # For extracting model archives import pathlib # For path manipulations import pandas # For tabular data handling import gradio # For interactive UI import huggingface_hub # For downloading model assets import autogluon.tabular # For loading and running AutoGluon predictors # Settings MODEL_REPO_ID = "its-zion-18/flowers-tabular-autolguon-predictor" ZIP_FILENAME = "autogluon_predictor_dir.zip" CACHE_DIR = pathlib.Path("hf_assets") EXTRACT_DIR = CACHE_DIR / "predictor_native" # Feature column names and target column names FEATURE_COLS = [ "flower_diameter_cm", "petal_length_cm", "petal_width_cm", "petal_count", "stem_height_cm" ] TARGET_COL = "color" # Encoding for outcome questions OUTCOME_LABELS = { 0: "Pink", 1: "Red", 2: "Orange", 3: "White", 4: "Yellow", 5: "Purple", } # Download & load the native predictor def _prepare_predictor_dir() -> str: CACHE_DIR.mkdir(parents=True, exist_ok=True) local_zip = huggingface_hub.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 = autogluon.tabular.TabularPredictor.load(PREDICTOR_DIR, require_py_version_match=False) # A mapping utility to make it easier to encode the variables def _human_label(c): try: ci = int(c) if ci in OUTCOME_LABELS: return OUTCOME_LABELS[ci] except Exception: pass if c in OUTCOME_LABELS: return OUTCOME_LABELS[c] return str(c) # This functions takes all of our features,e ncodes this accordingly, and performs a predictions def do_predict(diameter, length, width, number, height): row = { FEATURE_COLS[0]: float(diameter), FEATURE_COLS[1]: float(length), FEATURE_COLS[2]: float(width), FEATURE_COLS[3]: int(number), FEATURE_COLS[4]: float(height), } X = pandas.DataFrame([row], columns=FEATURE_COLS) pred_series = PREDICTOR.predict(X) raw_pred = pred_series.iloc[0] try: proba = PREDICTOR.predict_proba(X) if isinstance(proba, pandas.Series): proba = proba.to_frame().T except Exception: proba = None pred_label = _human_label(raw_pred) proba_dict = None if proba is not None: row0 = proba.iloc[0] tmp = {} for cls, val in row0.items(): key = _human_label(cls) tmp[key] = float(val) + float(tmp.get(key, 0.0)) proba_dict = dict(sorted(tmp.items(), key=lambda kv: kv[1], reverse=True)) df_out = pandas.DataFrame([{ "Predicted outcome": pred_label, "Confidence (%)": round((proba_dict.get(pred_label, 1.0) if proba_dict else 1.0) * 100, 2), }]) md = f"**Prediction:** {pred_label}" if proba_dict: md += f" \n**Confidence:** {round(proba_dict.get(pred_label, 0.0) * 100, 2)}%" return proba_dict # Representative examples EXAMPLES = [ [3.4, 1.3, 1, 7, 68.7], [5.7, 3.2, 0.9, 5, 21.2], [6.9, 3.8, 0.6, 17, 64.2], [5.6, 1, 1.5, 7, 73.4, ], [7.7, 1.5, 1.8, 13, 73.8], ] # Gradio UI with gradio.Blocks() as demo: # Provide an introduction gradio.Markdown("# What Color is the Flower?") gradio.Markdown(""" This is a simple app that uses the model at its-zion-18/flowers-tabular-autolguon-predictor to predict the color of a flower based off its characteristics, utilizing data found at scottymcgee/flowers. To use the interface, make selections using the interface elements shown below. """) with gradio.Row(): diameter = gradio.Slider(3, 10, step=0.1, value=5.0, label=FEATURE_COLS[0]) length = gradio.Slider(1, 5, step=0.1, value=3.0, label=FEATURE_COLS[1]) width = gradio.Slider(0.5, 2, step=0.1, value=1.0, label=FEATURE_COLS[2]) with gradio.Row(): number = gradio.Slider(5, 30, step=1, value=15, label=FEATURE_COLS[3]) height = gradio.Slider(10, 80, step=0.1, value=50.0, label=FEATURE_COLS[4]) proba_pretty = gradio.Label(num_top_classes=5, label="Class probabilities") inputs = [diameter, length, width, number, height] for comp in inputs: comp.change(fn=do_predict, inputs=inputs, outputs=[proba_pretty]) gradio.Examples( examples=EXAMPLES, inputs=inputs, label="Representative examples", examples_per_page=5, cache_examples=False, ) if __name__ == "__main__": demo.launch()