apsora commited on
Commit
9875b71
·
verified ·
1 Parent(s): 41f02b6

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +96 -0
app.py ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # !pip install -q autogluon.tabular gradio huggingface_hub pandas
3
+
4
+ from huggingface_hub import hf_hub_download
5
+ from autogluon.tabular import TabularPredictor
6
+ import pathlib, shutil, zipfile
7
+ import pandas as pd
8
+ import gradio as gr
9
+
10
+ # ---------------- Settings ----------------
11
+ MODEL_REPO_ID = "Iris314/classical-automl-model"
12
+ ZIP_FILENAME = "lego_predictor_dir.zip"
13
+
14
+ # UI → model feature name mapping
15
+ COLUMN_ALIAS = {
16
+ "Length": "Max Length (cm)",
17
+ "Height": "Max Height (cm)",
18
+ "Width": "Width (cm)",
19
+ "Studs": "Studs",
20
+ }
21
+ FEATURE_COLS_UI = ["Length", "Height", "Width", "Studs"]
22
+
23
+ # ---------------- Load predictor ----------------
24
+ CACHE_DIR = pathlib.Path("hf_cache"); EXTRACT_DIR = CACHE_DIR / "predictor"
25
+ CACHE_DIR.mkdir(exist_ok=True, parents=True)
26
+
27
+ def load_predictor():
28
+ local_zip = hf_hub_download(
29
+ repo_id=MODEL_REPO_ID,
30
+ filename=ZIP_FILENAME,
31
+ repo_type="model"
32
+ )
33
+ if EXTRACT_DIR.exists(): shutil.rmtree(EXTRACT_DIR)
34
+ EXTRACT_DIR.mkdir(parents=True)
35
+ with zipfile.ZipFile(local_zip, "r") as zf:
36
+ zf.extractall(EXTRACT_DIR)
37
+ kids = list(EXTRACT_DIR.iterdir())
38
+ path = kids[0] if len(kids) == 1 and kids[0].is_dir() else EXTRACT_DIR
39
+ return TabularPredictor.load(str(path), require_py_version_match=False)
40
+
41
+ PREDICTOR = load_predictor()
42
+
43
+ # ---------------- Helpers ----------------
44
+ def _cast_and_rename(row_dict):
45
+ row = dict(row_dict)
46
+ row["Length"] = float(row["Length"])
47
+ row["Height"] = float(row["Height"])
48
+ row["Width"] = float(row["Width"])
49
+ row["Studs"] = int(round(float(row["Studs"]))) # gr.Number returns float
50
+ X_ui = pd.DataFrame([row], columns=FEATURE_COLS_UI)
51
+ X_model = X_ui.rename(columns=COLUMN_ALIAS)
52
+ return X_model
53
+
54
+ def classify_brick(length, height, width, studs):
55
+ try:
56
+ X = _cast_and_rename({
57
+ "Length": length, "Height": height, "Width": width, "Studs": studs
58
+ })
59
+
60
+ pred = PREDICTOR.predict(X)
61
+ pred_val = pred.iloc[0] if hasattr(pred, "iloc") else pred
62
+
63
+ # Try probabilities; fall back to label
64
+ try:
65
+ proba = PREDICTOR.predict_proba(X)
66
+ s = proba.iloc[0] if hasattr(proba, "iloc") else proba
67
+ s = s.sort_values(ascending=False)
68
+ s.index = [str(k) for k in s.index] # ensure JSON-serializable keys
69
+ return {k: float(v) for k, v in s.items()}
70
+ except Exception:
71
+ return {"prediction": str(pred_val)}
72
+ except Exception as e:
73
+ import traceback
74
+ return {"error": f"{type(e).__name__}: {e}", "traceback": traceback.format_exc()}
75
+
76
+ # ---------------- Quick test (uses correct names) ----------------
77
+ # test_X = _cast_and_rename({"Length": 4, "Height": 1.2, "Width": 2, "Studs": 4})
78
+ # print("Prediction:", PREDICTOR.predict(test_X))
79
+ # print("Probabilities:\n", PREDICTOR.predict_proba(test_X))
80
+
81
+ # ---------------- Gradio (Interface version) ----------------
82
+ demo = gr.Interface(
83
+ fn=classify_brick,
84
+ inputs=[
85
+ gr.Slider(1, 10, step=0.1, value=4, label="Length"),
86
+ gr.Slider(0.2, 5, step=0.1, value=1.2, label="Height"),
87
+ gr.Slider(1, 10, step=0.1, value=2, label="Width"),
88
+ gr.Number(value=4, precision=0, label="Studs"),
89
+ ],
90
+ outputs=gr.Label(num_top_classes=3, label="Predicted Class / Probabilities"),
91
+ examples=[[4, 1.2, 2, 4], [2, 0.6, 2, 2], [3, 2.0, 2, 2]],
92
+ title="🧱 LEGO Brick Classifier",
93
+ description="Predicts whether a LEGO piece is Standard, Flat, or Sloped."
94
+ )
95
+
96
+ demo.launch()