Spaces:
Sleeping
Sleeping
Upload folder using huggingface_hub
Browse files- README.md +5 -11
- app.py +73 -0
- requirements.txt +5 -0
README.md
CHANGED
|
@@ -1,12 +1,6 @@
|
|
| 1 |
-
|
| 2 |
-
title: Cheese Texture App
|
| 3 |
-
emoji: 📊
|
| 4 |
-
colorFrom: purple
|
| 5 |
-
colorTo: gray
|
| 6 |
-
sdk: gradio
|
| 7 |
-
sdk_version: 5.47.2
|
| 8 |
-
app_file: app.py
|
| 9 |
-
pinned: false
|
| 10 |
-
---
|
| 11 |
|
| 12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Cheese Texture Gradio App
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
+
This Space loads **rlogh/cheese-texture-autogluon-classifier** (AutoGluon Tabular) and offers a simple UI.
|
| 4 |
+
|
| 5 |
+
**Inputs:** fat, protein, price, origin (dropdown or custom), holed (yes/no)
|
| 6 |
+
**Output:** predicted texture (soft / semi-soft / semi-hard / hard) and class probabilities.
|
app.py
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
import gradio as gr, pandas as pd
|
| 3 |
+
from huggingface_hub import list_repo_files, hf_hub_download
|
| 4 |
+
import zipfile, cloudpickle, shutil
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
import autogluon.tabular as ag
|
| 7 |
+
|
| 8 |
+
MODEL_REPO_ID = "rlogh/cheese-texture-autogluon-classifier"
|
| 9 |
+
ZIP_CANDIDATES = ['cheese_texture_predictor_dir.zip', 'autogluon_predictor_dir.zip', 'predictor_dir.zip']
|
| 10 |
+
PKL_CANDIDATES = ['cheese_texture_predictor.pkl', 'autogluon_predictor.pkl', 'predictor.pkl']
|
| 11 |
+
CACHE_DIR = Path("hf_assets"); CACHE_DIR.mkdir(parents=True, exist_ok=True)
|
| 12 |
+
EXTRACT_DIR = CACHE_DIR / "predictor_native"
|
| 13 |
+
|
| 14 |
+
def _pick_first(files, cands):
|
| 15 |
+
for n in cands:
|
| 16 |
+
if n in files: return n
|
| 17 |
+
return None
|
| 18 |
+
|
| 19 |
+
def load_predictor(repo_id):
|
| 20 |
+
files = list_repo_files(repo_id, repo_type="model")
|
| 21 |
+
zn = _pick_first(files, ZIP_CANDIDATES)
|
| 22 |
+
pn = _pick_first(files, PKL_CANDIDATES)
|
| 23 |
+
if zn:
|
| 24 |
+
zp = hf_hub_download(repo_id, filename=zn, repo_type="model", local_dir=str(CACHE_DIR), local_dir_use_symlinks=False)
|
| 25 |
+
if EXTRACT_DIR.exists(): shutil.rmtree(EXTRACT_DIR)
|
| 26 |
+
EXTRACT_DIR.mkdir(parents=True, exist_ok=True)
|
| 27 |
+
with zipfile.ZipFile(zp, "r") as zf: zf.extractall(str(EXTRACT_DIR))
|
| 28 |
+
kids = list(EXTRACT_DIR.iterdir())
|
| 29 |
+
root = kids[0] if (len(kids)==1 and kids[0].is_dir()) else EXTRACT_DIR
|
| 30 |
+
return ag.TabularPredictor.load(str(root), require_py_version_match=False)
|
| 31 |
+
elif pn:
|
| 32 |
+
pp = hf_hub_download(repo_id, filename=pn, repo_type="model", local_dir=str(CACHE_DIR), local_dir_use_symlinks=False)
|
| 33 |
+
with open(pp, "rb") as f: return cloudpickle.load(f)
|
| 34 |
+
raise FileNotFoundError("No predictor artifact found.")
|
| 35 |
+
|
| 36 |
+
PREDICTOR = load_predictor(MODEL_REPO_ID)
|
| 37 |
+
FEATURES = ["fat","origin","holed","price","protein"]
|
| 38 |
+
HOLED_MAP = {"Yes (has holes)":1,"No (solid)":0}
|
| 39 |
+
COMMON_ORIGINS = ["Italy","France","USA","Switzerland","Netherlands","Spain","Greece","Mexico","Denmark","Norway","India","Cyprus"]
|
| 40 |
+
|
| 41 |
+
def predict(fat, origin_pick, origin_free, holed_label, price, protein, k):
|
| 42 |
+
origin = origin_free.strip() if origin_free and origin_free.strip() else origin_pick
|
| 43 |
+
row = {"fat":float(fat), "origin":origin, "holed":HOLED_MAP[holed_label], "price":float(price), "protein":float(protein)}
|
| 44 |
+
X = pd.DataFrame([row], columns=FEATURES)
|
| 45 |
+
pred = PREDICTOR.predict(X).iloc[0]
|
| 46 |
+
try:
|
| 47 |
+
proba = PREDICTOR.predict_proba(X)
|
| 48 |
+
if hasattr(proba, "to_frame"): proba = proba.to_frame().T if proba.ndim==1 else proba
|
| 49 |
+
row0 = proba.iloc[0].to_dict()
|
| 50 |
+
probs = {str(k): float(v) for k,v in row0.items()}
|
| 51 |
+
probs = dict(sorted(probs.items(), key=lambda kv: kv[1], reverse=True)[:int(k)])
|
| 52 |
+
except Exception:
|
| 53 |
+
probs = {}
|
| 54 |
+
return f"**Prediction:** {pred}", probs
|
| 55 |
+
|
| 56 |
+
with gr.Blocks() as demo:
|
| 57 |
+
gr.Markdown("# Cheese Texture Classifier")
|
| 58 |
+
fat = gr.Slider(0, 60, value=25.0, step=0.1, label="Fat (g/100g)")
|
| 59 |
+
protein = gr.Slider(0, 40, value=22.0, step=0.1, label="Protein (g/100g)")
|
| 60 |
+
price = gr.Slider(0, 10, value=2.50, step=0.01, label="Price")
|
| 61 |
+
holed = gr.Radio(list(HOLED_MAP.keys()), value="No (solid)", label="Has holes?")
|
| 62 |
+
origin_pick = gr.Dropdown(COMMON_ORIGINS, value="Italy", label="Origin (common)")
|
| 63 |
+
origin_free = gr.Textbox(value="", placeholder="Or type a custom origin", label="Custom origin (optional)")
|
| 64 |
+
topk = gr.Slider(1, 4, value=4, step=1, label="Top-K")
|
| 65 |
+
|
| 66 |
+
summary = gr.Markdown()
|
| 67 |
+
probs = gr.Label(num_top_classes=4, label="Class probabilities")
|
| 68 |
+
|
| 69 |
+
gr.Button("Predict").click(predict,
|
| 70 |
+
[fat, origin_pick, origin_free, holed, price, protein, topk],
|
| 71 |
+
[summary, probs])
|
| 72 |
+
|
| 73 |
+
demo.launch()
|
requirements.txt
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
autogluon.tabular
|
| 2 |
+
gradio
|
| 3 |
+
huggingface_hub
|
| 4 |
+
cloudpickle
|
| 5 |
+
pandas
|