aslan-ng commited on
Commit
92e3a81
·
verified ·
1 Parent(s): 5f8a2a8

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +127 -0
app.py ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os # For filesystem operations
2
+ import shutil # For directory cleanup
3
+ import zipfile # For extracting model archives
4
+ import pathlib # For path manipulations
5
+ import pandas # For tabular data handling
6
+ import gradio # For interactive UI
7
+ import huggingface_hub # For downloading model assets
8
+ import autogluon.tabular # For loading and running AutoGluon predictors
9
+
10
+ # Settings
11
+ MODEL_REPO_ID = "its-zion-18/flowers-tabular-autolguon-predictor"
12
+ ZIP_FILENAME = "autogluon_predictor_dir.zip"
13
+ CACHE_DIR = pathlib.Path("hf_assets")
14
+ EXTRACT_DIR = CACHE_DIR / "predictor_native"
15
+
16
+ FEATURE_COLS = [
17
+ "flower_diameter_cm",
18
+ "petal_length_cm",
19
+ "petal_width_cm",
20
+ "petal_count",
21
+ "stem_height_cm",
22
+ ]
23
+ TARGET_COL = "color"
24
+
25
+ # If your repo id has a typo in "autolguon", fix it here if download fails.
26
+ # Download & load the native predictor
27
+ def _prepare_predictor_dir() -> str:
28
+ CACHE_DIR.mkdir(parents=True, exist_ok=True)
29
+ local_zip = huggingface_hub.hf_hub_download(
30
+ repo_id=MODEL_REPO_ID,
31
+ filename=ZIP_FILENAME,
32
+ repo_type="model",
33
+ local_dir=str(CACHE_DIR),
34
+ local_dir_use_symlinks=False,
35
+ )
36
+ if EXTRACT_DIR.exists():
37
+ shutil.rmtree(EXTRACT_DIR)
38
+ EXTRACT_DIR.mkdir(parents=True, exist_ok=True)
39
+ with zipfile.ZipFile(local_zip, "r") as zf:
40
+ zf.extractall(str(EXTRACT_DIR))
41
+ contents = list(EXTRACT_DIR.iterdir())
42
+ predictor_root = contents[0] if (len(contents) == 1 and contents[0].is_dir()) else EXTRACT_DIR
43
+ return str(predictor_root)
44
+
45
+ PREDICTOR_DIR = _prepare_predictor_dir()
46
+ PREDICTOR = autogluon.tabular.TabularPredictor.load(PREDICTOR_DIR, require_py_version_match=False)
47
+
48
+ def do_predict(flower_diameter_cm, petal_length_cm, petal_width_cm, petal_count, stem_height_cm, top_k):
49
+ row = {
50
+ FEATURE_COLS[0]: float(flower_diameter_cm),
51
+ FEATURE_COLS[1]: float(petal_length_cm),
52
+ FEATURE_COLS[2]: float(petal_width_cm),
53
+ FEATURE_COLS[3]: int(petal_count),
54
+ FEATURE_COLS[4]: float(stem_height_cm),
55
+ }
56
+ X = pandas.DataFrame([row], columns=FEATURE_COLS)
57
+
58
+ # Predicted label (string)
59
+ pred_series = PREDICTOR.predict(X)
60
+ pred_label = str(pred_series.iloc[0])
61
+
62
+ # Probabilities: dict[class] -> float
63
+ proba_dict = None
64
+ try:
65
+ proba = PREDICTOR.predict_proba(X)
66
+ # AutoGluon can return Series for binary; normalize to DataFrame row
67
+ if isinstance(proba, pandas.Series):
68
+ proba = proba.to_frame().T
69
+ row0 = proba.iloc[0].sort_values(ascending=False)
70
+ if isinstance(top_k, (int, float)) and top_k > 0:
71
+ row0 = row0.head(int(top_k))
72
+ proba_dict = {str(cls): float(val) for cls, val in row0.items()}
73
+ except Exception:
74
+ # If proba not available, just put 1.0 on the predicted class
75
+ proba_dict = {pred_label: 1.0}
76
+
77
+ # Return TWO outputs: (predicted color string, dict of numeric probs)
78
+ return proba_dict
79
+
80
+ # ----------------
81
+ # Example records
82
+ # ----------------
83
+ EXAMPLES = [
84
+ [4.5, 5.2, 1.8, 5, 35.0], # diam, petal_len, petal_wid, count, stem_h
85
+ [2.1, 3.3, 0.9, 8, 22.0],
86
+ [6.8, 7.1, 2.5, 6, 55.0],
87
+ [9.0, 4.0, 1.2, 12, 80.0],
88
+ [1.8, 2.6, 0.5, 4, 15.0],
89
+ ]
90
+
91
+ with gradio.Blocks() as demo:
92
+ gradio.Markdown("# 🌼 Flower Color Classifier\nPredict the flower **color** from five measurements.")
93
+ gradio.Markdown(
94
+ "Enter a single flower’s measurements below. "
95
+ "Use **Top-K** to see the most likely colors with their probabilities."
96
+ )
97
+
98
+ with gradio.Row():
99
+ flower_diameter_cm = gradio.Slider(0.0, 20.0, step=0.1, value=4.5, label="flower_diameter_cm")
100
+ petal_length_cm = gradio.Slider(0.0, 15.0, step=0.1, value=5.2, label="petal_length_cm")
101
+ petal_width_cm = gradio.Slider(0.0, 10.0, step=0.1, value=1.8, label="petal_width_cm")
102
+
103
+ with gradio.Row():
104
+ petal_count = gradio.Slider(1, 100, step=1, value=5, label="petal_count")
105
+ stem_height_cm = gradio.Slider(0.0, 200.0, step=0.5, value=35.0, label="stem_height_cm")
106
+ top_k = gradio.Slider(1, 10, step=1, value=3, label="Top-K classes shown")
107
+
108
+ # Separate outputs: Textbox for label, Label for probs (dict must be numeric)
109
+ proba_pretty = gradio.Label(num_top_classes=10, label="Class probabilities")
110
+
111
+ inputs = [flower_diameter_cm, petal_length_cm, petal_width_cm, petal_count, stem_height_cm, top_k]
112
+
113
+ # Trigger on any change
114
+ for comp in inputs:
115
+ comp.change(fn=do_predict, inputs=inputs, outputs=[proba_pretty])
116
+
117
+ # Examples: only pass the first 5 inputs (excluding top_k) to match example rows
118
+ gradio.Examples(
119
+ examples=EXAMPLES,
120
+ inputs=inputs[:-1], # exclude top_k so example length matches
121
+ label="Representative examples",
122
+ examples_per_page=5,
123
+ cache_examples=False,
124
+ )
125
+
126
+ if __name__ == "__main__":
127
+ demo.launch()