dermaAI / app /backend /model.py
yashvardhanshah
fix WindowsPath on Linux
8de7c59
Raw
History Blame Contribute Delete
3.21 kB
import io
import sys
from pathlib import Path
from typing import List, Tuple
from PIL import Image
import importlib.util as _ilu, os as _os
_s = _ilu.spec_from_file_location(
"disease_info",
_os.path.abspath(_os.path.join(_os.path.dirname(__file__), "..", "data", "disease_info.py"))
)
_m = _ilu.module_from_spec(_s)
_s.loader.exec_module(_m)
DISEASE_INFO = _m.DISEASE_INFO
# ---------------------------------------------------------------------------
# fastai import — handled carefully so the app doesn't crash if GPU is absent
# ---------------------------------------------------------------------------
try:
from fastai.vision.all import load_learner, PILImage
FASTAI_AVAILABLE = True
except ImportError:
FASTAI_AVAILABLE = False
# Path to the .pkl file (project root)
MODEL_PATH = Path(__file__).resolve().parents[2] / "skin_disease_classifier.pkl"
# Target image size the model was trained on
IMAGE_SIZE = 448
_learner = None # module-level singleton
def load_model(model_path: str = "skin_disease_classifier.pkl") -> bool:
"""Load the fastai learner once at startup. Returns True on success."""
global _learner
if not FASTAI_AVAILABLE:
print("ERROR: fastai is not installed.", file=sys.stderr)
return False
if not MODEL_PATH.exists():
print(f"ERROR: Model file not found at {MODEL_PATH}", file=sys.stderr)
return False
try:
import pathlib
import platform
print(f"DEBUG: Platform: {platform.system()}", flush=True)
# Patch WindowsPath to PosixPath for Linux loading
pathlib.WindowsPath = pathlib.PosixPath
_learner = load_learner(MODEL_PATH, cpu=True)
print(f"Model loaded successfully from {MODEL_PATH}", flush=True)
return True
except Exception as exc:
import traceback
print(f"ERROR loading model: {exc}", flush=True)
traceback.print_exc()
return False
def is_model_loaded() -> bool:
return _learner is not None
def predict_image(image_bytes: bytes):
import torch
import torchvision.transforms as T
if _learner is None:
raise RuntimeError("Model is not loaded.")
# Build tensor directly — no fastai DataLoader, no threading issues
img = Image.open(io.BytesIO(image_bytes)).convert("RGB")
img = img.resize((IMAGE_SIZE, IMAGE_SIZE))
tfms = T.Compose([
T.ToTensor(),
T.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]),
])
tensor = tfms(img).unsqueeze(0) # shape: (1, 3, 448, 448)
_learner.model.eval()
with torch.no_grad():
logits = _learner.model(tensor)
probs = torch.softmax(logits, dim=1)[0]
vocab = _learner.dls.vocab
label_prob_pairs = list(zip(vocab, probs.tolist()))
label_prob_pairs.sort(key=lambda x: x[1], reverse=True)
top3 = label_prob_pairs[:3]
results = []
for lbl, prob in top3:
info = DISEASE_INFO.get(lbl, {})
friendly = info.get("friendly_name", lbl)
results.append({
"medical_name": lbl,
"friendly_name": friendly,
"confidence": round(float(prob), 4)
})
return results