Spaces:
Sleeping
Sleeping
| """ | |
| Test the full inference pipeline (quality -> features -> predict) on real dataset images. | |
| This simulates exactly what happens when a user uploads a photo. | |
| """ | |
| import sys, io | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).parents[1])) | |
| import numpy as np | |
| from PIL import Image | |
| from app.services.prediction import ScreeningPredictor | |
| from app.services.image_quality import ImageQualityService | |
| from app.ml.archive_model import _build_subject_catalog, ANEMIA_HB_THRESHOLD | |
| from sklearn.metrics import accuracy_score, f1_score, recall_score, precision_score, roc_auc_score, mean_absolute_error | |
| predictor = ScreeningPredictor() | |
| quality_svc = ImageQualityService() | |
| print("Model:", predictor.archive_model.get("version") if predictor.archive_model else "NONE") | |
| print() | |
| subjects = _build_subject_catalog(Path(__file__).parents[2] / "archive" / "dataset anemia") | |
| # Test on original JPG images (what users actually upload) | |
| results = [] | |
| blocked = 0 | |
| for s in subjects[:40]: # first 40 for speed | |
| country = s["subject_id"].split("-")[0] | |
| num = s["subject_number"] | |
| jpg_path = Path(__file__).parents[2] / "archive" / "dataset anemia" / country / num | |
| jpgs = list(jpg_path.glob("*.jpg")) | |
| if not jpgs: | |
| continue | |
| with open(jpgs[0], "rb") as f: | |
| img_bytes = f.read() | |
| try: | |
| quality, rgb = quality_svc.evaluate(img_bytes) | |
| if not quality.passed: | |
| blocked += 1 | |
| continue | |
| pred = predictor.predict(rgb, quality, symptom_score=0.0) | |
| results.append({ | |
| "hb_true": s["hb"], | |
| "hb_pred": pred.predicted_hemoglobin, | |
| "risk": pred.anemia_risk, | |
| "label_true": int(s["hb"] < ANEMIA_HB_THRESHOLD), | |
| "label_pred": int(pred.anemia_risk >= 0.65) if pred.anemia_risk else 0, | |
| "screening_label": pred.screening_label, | |
| }) | |
| except Exception as e: | |
| print(f" Error on {s['subject_id']}: {e}") | |
| print(f"Processed: {len(results)}, Blocked by quality: {blocked}") | |
| print() | |
| if not results: | |
| print("No results — all blocked by quality gate!") | |
| else: | |
| labels_true = [r["label_true"] for r in results] | |
| labels_pred = [r["label_pred"] for r in results] | |
| risks = [r["risk"] for r in results if r["risk"] is not None] | |
| hb_true = [r["hb_true"] for r in results if r["hb_pred"] is not None] | |
| hb_pred = [r["hb_pred"] for r in results if r["hb_pred"] is not None] | |
| print(f"Accuracy: {accuracy_score(labels_true, labels_pred):.3f}") | |
| print(f"Recall: {recall_score(labels_true, labels_pred, zero_division=0):.3f}") | |
| print(f"Precision: {precision_score(labels_true, labels_pred, zero_division=0):.3f}") | |
| print(f"F1: {f1_score(labels_true, labels_pred, zero_division=0):.3f}") | |
| if len(set(labels_true)) > 1 and risks: | |
| print(f"AUC: {roc_auc_score(labels_true[:len(risks)], risks):.3f}") | |
| if hb_pred: | |
| print(f"Hb MAE: {mean_absolute_error(hb_true, hb_pred):.3f} g/dL") | |
| print(f"Hb bias: {float(np.mean(np.array(hb_pred) - np.array(hb_true))):.3f} g/dL") | |
| print("\nSample predictions:") | |
| for r in results[:10]: | |
| tag = "OK" if r["label_true"] == r["label_pred"] else "WRONG" | |
| print(f" True={r['hb_true']:.1f} Pred={r['hb_pred']} Risk={r['risk']} {r['screening_label']} [{tag}]") | |