MrCzaro commited on
Commit
41a3481
Β·
verified Β·
1 Parent(s): 434f652

Update README.md

Browse files
Files changed (1) hide show
  1. README.md +258 -3
README.md CHANGED
@@ -1,3 +1,258 @@
1
- ---
2
- license: mit
3
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ license: mit
3
+ language:
4
+ - en
5
+ tags:
6
+ - medical-imaging
7
+ - pressure-sore
8
+ - pressure-ulcer
9
+ - wound-classification
10
+ - yolo
11
+ - ultralytics
12
+ - two-stage
13
+ - binary-classification
14
+ - multiclass-classification
15
+ - computer-vision
16
+ metrics:
17
+ - accuracy
18
+ - f1
19
+ - roc-auc
20
+ pipeline_tag: image-classification
21
+ ---
22
+
23
+ # Pressure Sore Classifier β€” YOLO 2-Stage Weights
24
+
25
+ [![Python](https://img.shields.io/badge/Python-3.11+-blue.svg)](https://www.python.org/downloads/)
26
+ [![Ultralytics](https://img.shields.io/badge/Ultralytics-YOLO-orange.svg)](https://ultralytics.com/)
27
+ [![License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/license/mit)
28
+
29
+ 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).
30
+
31
+ Full project code, training notebooks, and web application:
32
+ πŸ‘‰ **[github.com/MrCzaro/PS_Classifier](https://github.com/MrCzaro/PS_Classifier)**
33
+
34
+ For the 3-level hierarchical cascade variant (8 models, binary decisions at every level):
35
+ πŸ‘‰ **[MrCzaro/Pressure_sore_cascade_classifier_YOLO](https://huggingface.co/MrCzaro/Pressure_sore_cascade_classifier_YOLO)**
36
+
37
+ ---
38
+
39
+ ## Medical Context
40
+
41
+ Pressure sores are staged I–IV based on tissue damage depth:
42
+
43
+ | Stage | Definition | Key Visual Feature |
44
+ |-------|-----------|-------------------|
45
+ | **I** | Non-blanchable erythema, intact skin | Redness, no open wound |
46
+ | **II** | Partial-thickness skin loss, exposed dermis | Shallow open ulcer or blister |
47
+ | **III** | Full-thickness skin loss, fat visible | Deep crater, no exposed bone/tendon |
48
+ | **IV** | Full-thickness tissue loss, muscle/bone exposed | Exposed deep structures, eschar/slough |
49
+
50
+ ---
51
+
52
+ ## Pipeline
53
+
54
+ ```
55
+ Image
56
+ β”‚
57
+ β–Ό
58
+ [Stage 1] Binary Detection β€” PS vs No-PS
59
+ 3-model ensemble: YOLO11s + YOLOv8x + YOLO26x
60
+ β”‚ NO β†’ "No pressure sore detected"
61
+ β”‚ YES ↓
62
+ [Stage 2] Multiclass Staging β€” Stage I / II / III / IV
63
+ 3-model ensemble: YOLOv8n + YOLO26m + YOLOv8x
64
+ ```
65
+
66
+ Both stages use **averaged softmax probabilities** across three architecturally distinct YOLO families (v8, YOLO11, YOLO26) for robustness.
67
+
68
+ ---
69
+
70
+ ## Files
71
+
72
+ | File | Stage | Task | Accuracy | AUC-ROC |
73
+ |------|-------|------|----------|---------|
74
+ | `Binary_YOLOv8x.pt` | S1 | PS vs No-PS | 1.0000 | 0.9998 |
75
+ | `Binary_YOLOv11s.pt` | S1 | PS vs No-PS | 1.0000 | 1.0000 |
76
+ | `Binary_YOLOv26x.pt` | S1 | PS vs No-PS | 1.0000 | 1.0000 |
77
+ | `Multiclass_YOLOv8n.pt` | S2 | Stage I–IV | 0.8571 | 0.9486 (macro OvR) |
78
+ | `Multiclass_YOLOv8x.pt` | S2 | Stage I–IV | 0.8571 | 0.9306 (macro OvR) |
79
+ | `Multiclass_YOLOv26m.pt` | S2 | Stage I–IV | 0.8571 | 0.9247 (macro OvR) |
80
+
81
+ ---
82
+
83
+
84
+
85
+ ## Performance
86
+
87
+ ### Stage 1 β€” Binary Detection (3-Model Ensemble)
88
+
89
+ | Model | Accuracy | Macro F1 | AUC-ROC |
90
+ |-------|----------|----------|---------|
91
+ | YOLO11s | 1.0000 | 1.0000 | 0.9998 |
92
+ | YOLOv8x | 1.0000 | 1.0000 | 1.0000 |
93
+ | YOLO26x | 1.0000 | 1.0000 | 1.0000 |
94
+ | **Ensemble** | **1.0000** | **1.0000** | **β€”** |
95
+
96
+ ### Stage 2 β€” Multiclass Staging (3-Model Ensemble)
97
+
98
+ | Model | Accuracy | Macro F1 | Macro AUC-ROC (OvR) |
99
+ |-------|----------|----------|---------------------|
100
+ | YOLOv8n | 0.8571 | 0.8500 | 0.9486 |
101
+ | YOLO26m | 0.8571 | 0.8542 | 0.9306 |
102
+ | YOLOv8x | 0.8571 | 0.8501 | 0.9247 |
103
+ | **Ensemble** | **0.8571** | **0.8514** | **β€”** |
104
+
105
+ ### Per-Class AUC-ROC (Stage 2)
106
+
107
+ | Stage | YOLOv8n | YOLO26m | YOLOv8x |
108
+ |-------|---------|---------|---------|
109
+ | Stage I | 0.9913 | 0.9712 | 0.9934 |
110
+ | Stage II | 0.9455 | 0.9261 | 0.9268 |
111
+ | Stage III | 0.8852 | 0.8866 | 0.8450 |
112
+ | Stage IV | 0.9723 | 0.9386 | 0.9337 |
113
+
114
+ 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.
115
+
116
+ ### Model Selection Rationale
117
+
118
+ **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.
119
+
120
+ **Stage 2** β€” selected by Macro AUC-ROC as primary criterion (threshold-independent, treats all 4 classes equally) with Macro F1 as tiebreaker:
121
+
122
+ | Pick | Model | Reason |
123
+ |------|-------|--------|
124
+ | 1 | YOLOv8n | Best AUC+F1 balance, strongest Stage IV AUC (0.9723) |
125
+ | 2 | YOLO26m | Best Macro F1 overall, best Stage III AUC among YOLO26 models, architecture diversity |
126
+ | 3 | YOLOv8x | Third AUC, strong Stage I AUC (0.9934), large v8 model |
127
+
128
+ ---
129
+
130
+ ## Installation & Usage
131
+
132
+ ### 1. Install dependencies
133
+
134
+ ```bash
135
+ pip install ultralytics huggingface_hub
136
+ ```
137
+
138
+ ### 2. Download weights
139
+
140
+ **Option A β€” clone the full repo**
141
+
142
+ ```bash
143
+ git lfs install
144
+ git clone https://huggingface.co/MrCzaro/Pressure_sore_classifier_YOLO
145
+ ```
146
+
147
+ **Option B β€” download individual files**
148
+
149
+ ```python
150
+ from huggingface_hub import hf_hub_download
151
+
152
+ path = hf_hub_download(
153
+ repo_id="MrCzaro/Pressure_sore_classifier_YOLO",
154
+ filename="Binary_YOLOv8x.pt"
155
+ )
156
+ ```
157
+
158
+ ### 3. Wire weights into the application
159
+
160
+ ```bash
161
+ git clone https://github.com/MrCzaro/PS_Classifier
162
+ cd PS_Classifier
163
+ pip install -r requirements.txt
164
+ ```
165
+
166
+ Update path constants in `ps_classifier_yolo.py`:
167
+
168
+ ```python
169
+ BINARY_MODEL_PATHS = [
170
+ "models/yolo/Binary_YOLOv8x.pt",
171
+ "models/yolo/Binary_YOLOv11s.pt",
172
+ "models/yolo/Binary_YOLOv26x.pt"
173
+ ]
174
+ STAGE_MODEL_PATHS = [
175
+ "models/yolo/Multiclass_YOLOv8n.pt",
176
+ "models/yolo/Multiclass_YOLOv8x.pt",
177
+ "models/yolo/Multiclass_YOLOv26m.pt"
178
+ ]
179
+ ```
180
+
181
+ Then run and select **YOLO** from the backend dropdown:
182
+
183
+ ```bash
184
+ python main.py
185
+ # Open http://localhost:5001
186
+ ```
187
+
188
+ ### 4. Standalone inference script
189
+
190
+ ```python
191
+ from huggingface_hub import hf_hub_download
192
+ from ultralytics import YOLO
193
+ import numpy as np
194
+ from PIL import Image
195
+
196
+ REPO = "MrCzaro/Pressure_sore_classifier_YOLO"
197
+
198
+ BINARY_MODEL_PATHS = [
199
+ "models/yolo/Binary_YOLOv8x.pt",
200
+ "models/yolo/Binary_YOLOv11s.pt",
201
+ "models/yolo/Binary_YOLOv26x.pt"
202
+ ]
203
+ STAGE_MODEL_PATHS = [
204
+ "models/yolo/Multiclass_YOLOv8n.pt",
205
+ "models/yolo/Multiclass_YOLOv8x.pt",
206
+ "models/yolo/Multiclass_YOLOv26m.pt"
207
+ ]
208
+
209
+ def ensemble_predict(model_paths, img):
210
+ all_probs, names = [], None
211
+ for p in model_paths:
212
+ model = YOLO(p)
213
+ result = model(img, verbose=False)[0]
214
+ all_probs.append(result.probs.data.cpu().numpy())
215
+ if names is None:
216
+ names = result.names
217
+ avg = np.mean(all_probs, axis=0)
218
+ idx = int(np.argmax(avg))
219
+ return idx, names[idx], float(avg[idx])
220
+
221
+ img = Image.open("your_image.jpg").convert("RGB")
222
+
223
+ # Stage 1 β€” binary detection
224
+ _, label, conf = ensemble_predict(BINARY_MODEL_PATHS, img)
225
+
226
+ if "not" in label.lower():
227
+ print(f"No pressure sore detected ({conf:.2f})")
228
+ else:
229
+ # Stage 2 β€” multiclass staging
230
+ _, stage, stage_conf = ensemble_predict(STAGE_MODEL_PATHS, img)
231
+ print(f"Pressure sore detected ({conf:.2f})")
232
+ print(f"Stage: {stage} ({stage_conf:.2f})")
233
+ ```
234
+
235
+ ---
236
+
237
+
238
+
239
+ ## ⚠️ Medical Disclaimer
240
+
241
+ This model is provided **for research and educational purposes only**.
242
+
243
+ - ❌ NOT a medical device
244
+ - ❌ NOT certified for clinical diagnosis
245
+ - ❌ NOT a substitute for professional medical judgment
246
+ - ❌ NOT validated in clinical trials
247
+
248
+ Always consult licensed healthcare professionals for medical diagnosis and treatment.
249
+
250
+ ---
251
+
252
+ ## Contact
253
+
254
+ **Author**: MrCzaro
255
+ **GitHub**: [@MrCzaro](https://github.com/MrCzaro)
256
+ **Project**: [PS_Classifier](https://github.com/MrCzaro/PS_Classifier)
257
+ **Email**: cezary.tubacki@gmail.com
258
+ **License**: MIT