COCODEDE04 commited on
Commit
369a04a
·
verified ·
1 Parent(s): f22bef5

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +44 -50
app.py CHANGED
@@ -2,79 +2,73 @@ import json
2
  import numpy as np
3
  import tensorflow as tf
4
  import gradio as gr
5
- from fastapi import FastAPI
6
 
7
- # --- CONFIG ---
8
- MODEL_PATH = "best_model.h5" # or .keras
9
- STATS_PATH = "Means & Std for Excel.json"
10
  CLASSES = ["Top", "Mid-Top", "Mid", "Mid-Low", "Low"]
 
11
 
12
  print("Loading model and stats...")
13
  model = tf.keras.models.load_model(MODEL_PATH, compile=False)
 
14
  with open(STATS_PATH, "r") as f:
15
  stats = json.load(f)
16
 
17
  FEATURES = list(stats.keys())
18
  print("Feature order:", FEATURES)
19
 
20
- def _z(x, m, s):
21
  try:
22
- x = float(x)
23
- except:
24
- x = 0.0
25
- return 0.0 if s == 0 else (x - m) / s
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
- def _predict_core(ratios: dict):
28
- missing = [f for f in FEATURES if f not in ratios]
29
- zs = []
30
- zdict = {}
31
  for f in FEATURES:
32
- mean = stats[f]["mean"]
33
- std = stats[f]["std"]
34
- z = _z(ratios.get(f, 0.0), mean, std)
35
- zs.append(z)
36
- zdict[f] = z
37
- X = np.array([zs], dtype=np.float32)
38
 
39
- raw = model.predict(X, verbose=0)[0]
40
- if len(raw) == len(CLASSES):
41
- probs = np.clip(raw, 0.0, 1.0)
42
- probs /= probs.sum()
43
- elif len(raw) == len(CLASSES) - 1: # CORAL-style
44
- sig = 1 / (1 + np.exp(-raw))
45
- left = np.concatenate([[1.0], sig])
46
- right = np.concatenate([sig, [0.0]])
47
- probs = left - right
48
  else:
49
- raise ValueError("Unexpected output length")
50
 
51
  pred_idx = int(np.argmax(probs))
52
- return {
53
- "input_ok": len(missing) == 0,
54
- "missing": missing,
55
  "probabilities": {CLASSES[i]: float(probs[i]) for i in range(len(CLASSES))},
56
  "predicted_state": CLASSES[pred_idx],
57
  }
 
58
 
59
- def predict_from_json(payload):
60
- if isinstance(payload, list) and len(payload) == 1 and isinstance(payload[0], dict):
61
- payload = payload[0]
62
- if not isinstance(payload, dict):
63
- return {"error": "Expected a JSON object mapping feature->value."}
64
- return _predict_core(payload)
65
-
66
- # ---- GRADIO INTERFACE ----
67
- iface = gr.Interface(
68
  fn=predict_from_json,
69
- inputs=gr.JSON(label="ratios JSON (dict of feature -> value)"),
70
  outputs="json",
71
- title="Static Fingerprint Model API",
72
- description="POST JSON to /run/predict with your 21 ratios."
73
  )
74
 
75
- app = FastAPI()
76
- app = gr.mount_gradio_app(app, iface, path="/")
77
-
78
- @app.get("/health")
79
- def health():
80
- return {"status": "ok"}
 
2
  import numpy as np
3
  import tensorflow as tf
4
  import gradio as gr
 
5
 
6
+ # ==== CONFIG ====
7
+ MODEL_PATH = "best_model.h5"
8
+ STATS_PATH = "means_std.json"
9
  CLASSES = ["Top", "Mid-Top", "Mid", "Mid-Low", "Low"]
10
+ # ================
11
 
12
  print("Loading model and stats...")
13
  model = tf.keras.models.load_model(MODEL_PATH, compile=False)
14
+
15
  with open(STATS_PATH, "r") as f:
16
  stats = json.load(f)
17
 
18
  FEATURES = list(stats.keys())
19
  print("Feature order:", FEATURES)
20
 
21
+ def zscore(val, mean, sd):
22
  try:
23
+ val = float(val)
24
+ except Exception:
25
+ return 0.0
26
+ if sd == 0 or sd is None:
27
+ return 0.0
28
+ return (val - mean) / sd
29
+
30
+ def coral_probs_from_logits(logits_np):
31
+ logits = tf.convert_to_tensor(logits_np, dtype=tf.float32)
32
+ sig = tf.math.sigmoid(logits)
33
+ left = tf.concat([tf.ones_like(sig[:, :1]), sig], axis=1)
34
+ right = tf.concat([sig, tf.zeros_like(sig[:, :1])], axis=1)
35
+ probs = tf.clip_by_value(left - right, 1e-12, 1.0)
36
+ return probs.numpy()
37
+
38
+ def predict_from_json(input_json):
39
+ # Expect a dictionary with feature:value pairs
40
+ if not isinstance(input_json, dict):
41
+ return {"error": "Expected JSON object mapping feature -> value."}
42
 
43
+ # Prepare data
44
+ z_list = []
 
 
45
  for f in FEATURES:
46
+ v = input_json.get(f, 0)
47
+ z = zscore(v, stats[f]["mean"], stats[f]["std"])
48
+ z_list.append(z)
49
+ X = np.array([z_list], dtype=np.float32)
 
 
50
 
51
+ raw = model.predict(X, verbose=0)
52
+ if raw.shape[1] == len(CLASSES) - 1:
53
+ probs = coral_probs_from_logits(raw)[0]
 
 
 
 
 
 
54
  else:
55
+ probs = raw[0]
56
 
57
  pred_idx = int(np.argmax(probs))
58
+ output = {
 
 
59
  "probabilities": {CLASSES[i]: float(probs[i]) for i in range(len(CLASSES))},
60
  "predicted_state": CLASSES[pred_idx],
61
  }
62
+ return output
63
 
64
+ # ==== Gradio UI ====
65
+ demo = gr.Interface(
 
 
 
 
 
 
 
66
  fn=predict_from_json,
67
+ inputs=gr.JSON(label="Feature dictionary (JSON)"),
68
  outputs="json",
69
+ title="Static Fingerprint Predictor",
70
+ description="POST JSON to /run/predict with your feature values."
71
  )
72
 
73
+ if __name__ == "__main__":
74
+ demo.launch()