Pressure Sore Classifier β YOLO 2-Stage Weights
Six YOLO classification weights for a 2-stage cascade pipeline that detects and stages pressure sores from clinical photographs. Stage 1 determines whether a pressure sore is present; Stage 2 classifies its severity (Stage IβIV).
Full project code, training notebooks, and web application:
π github.com/MrCzaro/PS_Classifier
For the 3-level hierarchical cascade variant (8 models, binary decisions at every level):
π MrCzaro/Pressure_sore_cascade_classifier_YOLO
Medical Context
Pressure sores are staged IβIV based on tissue damage depth:
| Stage | Definition | Key Visual Feature |
|---|---|---|
| I | Non-blanchable erythema, intact skin | Redness, no open wound |
| II | Partial-thickness skin loss, exposed dermis | Shallow open ulcer or blister |
| III | Full-thickness skin loss, fat visible | Deep crater, no exposed bone/tendon |
| IV | Full-thickness tissue loss, muscle/bone exposed | Exposed deep structures, eschar/slough |
Pipeline
Image
β
βΌ
[Stage 1] Binary Detection β PS vs No-PS
3-model ensemble: YOLO11s + YOLOv8x + YOLO26x
β NO β "No pressure sore detected"
β YES β
[Stage 2] Multiclass Staging β Stage I / II / III / IV
3-model ensemble: YOLOv8n + YOLO26m + YOLOv8x
Both stages use averaged softmax probabilities across three architecturally distinct YOLO families (v8, YOLO11, YOLO26) for robustness.
Files
| File | Stage | Task | Accuracy | AUC-ROC |
|---|---|---|---|---|
Binary_YOLOv8x.pt |
S1 | PS vs No-PS | 1.0000 | 0.9998 |
Binary_YOLOv11s.pt |
S1 | PS vs No-PS | 1.0000 | 1.0000 |
Binary_YOLOv26x.pt |
S1 | PS vs No-PS | 1.0000 | 1.0000 |
Multiclass_YOLOv8n.pt |
S2 | Stage IβIV | 0.8571 | 0.9486 (macro OvR) |
Multiclass_YOLOv8x.pt |
S2 | Stage IβIV | 0.8571 | 0.9306 (macro OvR) |
Multiclass_YOLOv26m.pt |
S2 | Stage IβIV | 0.8571 | 0.9247 (macro OvR) |
Performance
Stage 1 β Binary Detection (3-Model Ensemble)
| Model | Accuracy | Macro F1 | AUC-ROC |
|---|---|---|---|
| YOLO11s | 1.0000 | 1.0000 | 0.9998 |
| YOLOv8x | 1.0000 | 1.0000 | 1.0000 |
| YOLO26x | 1.0000 | 1.0000 | 1.0000 |
| Ensemble | 1.0000 | 1.0000 | β |
Stage 2 β Multiclass Staging (3-Model Ensemble)
| Model | Accuracy | Macro F1 | Macro AUC-ROC (OvR) |
|---|---|---|---|
| YOLOv8n | 0.8571 | 0.8500 | 0.9486 |
| YOLO26m | 0.8571 | 0.8542 | 0.9306 |
| YOLOv8x | 0.8571 | 0.8501 | 0.9247 |
| Ensemble | 0.8571 | 0.8514 | β |
Per-Class AUC-ROC (Stage 2)
| Stage | YOLOv8n | YOLO26m | YOLOv8x |
|---|---|---|---|
| Stage I | 0.9913 | 0.9712 | 0.9934 |
| Stage II | 0.9455 | 0.9261 | 0.9268 |
| Stage III | 0.8852 | 0.8866 | 0.8450 |
| Stage IV | 0.9723 | 0.9386 | 0.9337 |
The 3-model staging ensemble achieves 0.8514 Macro F1 β a significant improvement over the flat Torchvision staging baseline (0.74 Macro F1) used in Backend 1 of the same project.
Model Selection Rationale
Stage 1 β all three models achieve perfect or near-perfect accuracy and AUC; the three were chosen from different YOLO families (v8, YOLO11, YOLO26) to maximise ensemble diversity.
Stage 2 β selected by Macro AUC-ROC as primary criterion (threshold-independent, treats all 4 classes equally) with Macro F1 as tiebreaker:
| Pick | Model | Reason |
|---|---|---|
| 1 | YOLOv8n | Best AUC+F1 balance, strongest Stage IV AUC (0.9723) |
| 2 | YOLO26m | Best Macro F1 overall, best Stage III AUC among YOLO26 models, architecture diversity |
| 3 | YOLOv8x | Third AUC, strong Stage I AUC (0.9934), large v8 model |
Installation & Usage
1. Install dependencies
pip install ultralytics huggingface_hub
2. Download weights
Option A β clone the full repo
git lfs install
git clone https://huggingface.co/MrCzaro/Pressure_sore_classifier_YOLO
Option B β download individual files
from huggingface_hub import hf_hub_download
path = hf_hub_download(
repo_id="MrCzaro/Pressure_sore_classifier_YOLO",
filename="Binary_YOLOv8x.pt"
)
3. Wire weights into the application
git clone https://github.com/MrCzaro/PS_Classifier
cd PS_Classifier
pip install -r requirements.txt
Update path constants in ps_classifier_yolo.py:
BINARY_MODEL_PATHS = [
"models/yolo/Binary_YOLOv8x.pt",
"models/yolo/Binary_YOLOv11s.pt",
"models/yolo/Binary_YOLOv26x.pt"
]
STAGE_MODEL_PATHS = [
"models/yolo/Multiclass_YOLOv8n.pt",
"models/yolo/Multiclass_YOLOv8x.pt",
"models/yolo/Multiclass_YOLOv26m.pt"
]
Then run and select YOLO from the backend dropdown:
python main.py
# Open http://localhost:5001
4. Standalone inference script
from huggingface_hub import hf_hub_download
from ultralytics import YOLO
import numpy as np
from PIL import Image
REPO = "MrCzaro/Pressure_sore_classifier_YOLO"
BINARY_MODEL_PATHS = [
"models/yolo/Binary_YOLOv8x.pt",
"models/yolo/Binary_YOLOv11s.pt",
"models/yolo/Binary_YOLOv26x.pt"
]
STAGE_MODEL_PATHS = [
"models/yolo/Multiclass_YOLOv8n.pt",
"models/yolo/Multiclass_YOLOv8x.pt",
"models/yolo/Multiclass_YOLOv26m.pt"
]
def ensemble_predict(model_paths, img):
all_probs, names = [], None
for p in model_paths:
model = YOLO(p)
result = model(img, verbose=False)[0]
all_probs.append(result.probs.data.cpu().numpy())
if names is None:
names = result.names
avg = np.mean(all_probs, axis=0)
idx = int(np.argmax(avg))
return idx, names[idx], float(avg[idx])
img = Image.open("your_image.jpg").convert("RGB")
# Stage 1 β binary detection
_, label, conf = ensemble_predict(BINARY_MODEL_PATHS, img)
if "not" in label.lower():
print(f"No pressure sore detected ({conf:.2f})")
else:
# Stage 2 β multiclass staging
_, stage, stage_conf = ensemble_predict(STAGE_MODEL_PATHS, img)
print(f"Pressure sore detected ({conf:.2f})")
print(f"Stage: {stage} ({stage_conf:.2f})")
β οΈ Medical Disclaimer
This model is provided for research and educational purposes only.
- β NOT a medical device
- β NOT certified for clinical diagnosis
- β NOT a substitute for professional medical judgment
- β NOT validated in clinical trials
Always consult licensed healthcare professionals for medical diagnosis and treatment.
Contact
Author: MrCzaro
GitHub: @MrCzaro
Project: PS_Classifier
Email: cezary.tubacki@gmail.com
License: MIT
- Downloads last month
- 206