File size: 12,228 Bytes
a411658 471ebfd a411658 b361d6d a411658 225a60d a411658 225a60d a411658 10f79cd a411658 10f79cd a411658 10f79cd a411658 10f79cd a411658 86a6309 a411658 86a6309 a411658 10f79cd a411658 10f79cd a411658 85e93ee a411658 85e93ee a411658 10f79cd a411658 85e93ee a411658 a59e633 a411658 10f79cd a411658 10f79cd a411658 10f79cd a411658 10f79cd a411658 10f79cd a411658 10f79cd a411658 10f79cd ac34a30 10f79cd ac34a30 16e59ac ac34a30 10f79cd ac34a30 10f79cd 16e59ac ac34a30 10f79cd a411658 10f79cd a411658 10f79cd a411658 10f79cd a411658 5745499 10f79cd a411658 10f79cd a411658 10f79cd a411658 5745499 10f79cd a411658 10f79cd a411658 10f79cd a411658 10f79cd a411658 10f79cd a411658 10f79cd a411658 b361d6d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 | ---
license: apache-2.0
language:
- en
base_model:
- Ultralytics/YOLO26
pipeline_tag: object-detection
library_name: ultralytics
description: "YOLO26m trained to detect Ring, Trophozoite and Schizont stages of P. falciparum in Giemsa-stained blood smears"
tags:
- medical
- biology
- malaria
- plasmodium
- microscopy
- giemsa
- computer-vision
- africa
- kenya
metrics:
- mAP
- precision
- recall
model-index:
- name: plasmodium-yolo26-v1
results:
- task:
type: object-detection
dataset:
name: Plasmodium Giemsa Life Stages V1
type: custom
metrics:
- type: mAP
value: 0.735
name: mAP@0.5 (test)
- type: mAP
value: 0.513
name: mAP@0.5:0.95 (test)
- type: precision
value: 0.666
name: Precision (test)
- type: recall
value: 0.753
name: Recall (test)
- name: plasmodium-yolo26-v2
results:
- task:
type: object-detection
dataset:
name: Plasmodium Giemsa Life Stages V2
type: custom
metrics:
- type: mAP
value: 0.830
name: mAP@0.5 (test)
- type: mAP
value: 0.638
name: mAP@0.5:0.95 (test)
- type: precision
value: 0.747
name: Precision (test)
- type: recall
value: 0.812
name: Recall (test)
---
# Plasmodium Life Stage Detection on Thin Blood Smear using YOLO26m
This model detects and classifies Plasmodium falciparum life stages
in Giemsa-stained Thin blood smear images using a YOLO26m object detection architecture.
The three target classes are Ring, Trophozoite, and Schizont the three intraerythrocytic stages
observable under light microscopy.
The work is motivated by the clinical need for automated malaria
staging in resource-limited settings, where trained microscopists
are not always available and diagnostic turnaround time is critical.
This repository documents the full development journey from V1 to V2,
including the challenges encountered, decisions made, and improvements
achieved at each stage.
## V1 Dataset
The dataset consists of Giemsa-stained blood smear images annotated
with bounding boxes and life stage labels at the individual cell level.
Annotations were sourced from an Excel file mapping image filenames to
cell center coordinates and stage labels.
| Original Label | Mapped Class | Split | Ratio | Annotations | Class | Crop Size |
|-----------------|--------------|-------|-------|-------------------------------|-------------|-----------|
| R, LR-ET | Ring | Train | 70% | Ring oversampling x3 applied | Ring | 80 px |
| LT, MT | Trophozoite | Val | 15% | 122 images, 439 instances | Trophozoite | 110 px |
| Esch, Lsch, Seg | Schizont | Test | 15% | 122 images, 436 instances | Schizont | 150 px |
---
## V1 Model Details
| Property | Value | Property | Value |
|------------------|-----------------------------|-----------------|------------------------------|
| Architecture | YOLO26m | Parameters | 20,351,765 |
| Framework | Ultralytics 8.4.23 | GFLOPs | 67.9 |
| Input Size | 512 x 512 px | Training Device | Tesla P100 16GB |
| Classes | Ring, Schizont, Trophozoite | Epochs | 80 |
| Optimizer | AdamW | Learning Rate | 5e-5 (cosine decay to 0.001) |
source code can be found : https://github.com/codeshujaa/Plasmodium-Life-Stage-Detection/blob/main/README.md
## V1 Training
Training was conducted with strong data augmentation to compensate
for the limited dataset size.
The classification loss weight was increased to 3.0 to address the morphological ambiguity between
transitional stages, particularly between Trophozoite and the
adjacent Ring and Schizont classes.
## V1 Training Curves
The TensorBoard training curves are included in this repository
under `runs/plasmodium/`. To visualise them locally
```bash
tensorboard --logdir runs/plasmodium
```

Key observations from the curves
`Loss/train_box` converged from ~1.2 to 0.81 by epoch 79
`Loss/train_cls` converged from ~12 to 6.95 — the highest
absolute loss, reflecting the classification difficulty
of morphologically similar stages
`Loss/val_box` and `Loss/val_cls` both decreased consistently
without divergence, confirming the model did not overfit

`mAP/mAP50` reached 0.693 at epoch 79 with a smooth
convergence curve
`mAP/mAP50_95` reached 0.494 at epoch 79
Both mAP curves plateau after epoch 60, indicating the model
reached the limit of what the current dataset volume supports.
---
## V1 Evaluation Results
Inference was run at conf=0.15 and iou=0.5 on the held-out test set.
### Detection Performance on Test Set V1
| Class | Precision | Recall | mAP@0.5 | mAP@0.5:0.95 |
|-------------|-----------|--------|---------|--------------|
| All | 0.666 | 0.753 | 0.735 | 0.513 |
| Ring | 0.623 | 0.586 | 0.551 | 0.377 |
| Schizont | 0.733 | 0.937 | 0.917 | 0.646 |
| Trophozoite | 0.641 | 0.737 | 0.737 | 0.516 |
### Classification Performance on Test Set V1
| Class | Precision | Recall | F1 | Support |
|-------------|-----------|--------|------|---------|
| Ring | 0.68 | 0.57 | 0.62 | 115 |
| Schizont | 0.70 | 0.76 | 0.73 | 214 |
| Trophozoite | 0.42 | 0.42 | 0.42 | 105 |
| Accuracy | | | 0.63 | 434 |
| Macro avg | 0.60 | 0.58 | 0.59 | 434 |
| Weighted avg| 0.63 | 0.63 | 0.62 | 434 |
---
## Confusion Matrix V1
The confusion matrix

Key observations
- Schizont is the most reliably detected class, achieving 0.917
mAP@0.5, consistent with its large and morphologically
distinct appearance
- Ring stage shows the highest background confusion —
small cell size and light staining intensity make Ring
cells the hardest to detect at this dataset scale
- Trophozoite is confused in both directions, with some
predictions falling toward Ring and others toward Schizont,
reflecting its intermediate morphological position in the
parasite life cycle
---
## Sample Detections
Sample detection outputs on validation images.

---
## V1 How to Use
```python
!pip install ultralytics
from huggingface_hub import hf_hub_download
from ultralytics import YOLO
# Load V2 model
weights_path = hf_hub_download(
repo_id = "codeshujaaa/kenyanmalarai-detect",
filename = "weights/best.pt"
)
model = YOLO(weights_path)
results = model.predict(
source = "https://en.pimg.jp/023/550/618/1/23550618.jpg",
conf = 0.15,
iou = 0.5,
imgsz = 640,
)
results[0].show()
```
### V2 Data Expansion
Based on V1 findings, a second annotated dataset was sourced from
Roboflow Universe and merged with the original dataset.
The Roboflow dataset contained seven classes. Only Ring, Schizont,
and Trophozoite annotations were retained and remapped to match the
V1 class ID schema before merging.
**Data growth from V1 to V2**
| Class | V1 Instances | V2 Instances | Growth |
|-------|-------------|-------------|--------|
| Ring | 127 | 1356 | 10x |
| Schizont | 214 | 1546 | 7x |
| Trophozoite | 95 | 2283 | 24x |
Training was extended from 80 to 120 epochs and image size was
increased from 512 to 640. Mosaic augmentation was disabled for
the final 10 epochs to allow the model to consolidate detection
on full-size images.
**V2 Model Details**
| Property | Value | Property | Value |
|----------|-------|----------|-------|
| Architecture | YOLO26m | Parameters | 20,351,765 |
| Framework | Ultralytics 8.4.24 | GFLOPs | 67.9 |
| Input Size | 640 x 640 px | Training Device | Tesla T4 x2 |
| Classes | Ring, Schizont, Trophozoite | Epochs | 120 |
| Optimizer | AdamW | Learning Rate | 5e-5 (cosine decay) |
**V2 Training Curves**

**V2 Detection Performance on Test Set**
| Class | Precision | Recall | mAP@0.5 | mAP@0.5:0.95 |
|-------|-----------|--------|---------|--------------|
| All | 0.747 | 0.812 | 0.830 | 0.638 |
| Ring | 0.698 | 0.701 | 0.735 | 0.565 |
| Schizont | 0.775 | 0.930 | 0.933 | 0.750 |
| Trophozoite | 0.770 | 0.804 | 0.822 | 0.601 |
**V2 Classification Performance — Test Set**
| Class | Precision | Recall | F1 | Support |
|-------|-----------|--------|----|---------|
| Ring | 0.71 | 0.72 | 0.72 | 175 |
| Schizont | 0.69 | 0.79 | 0.74 | 232 |
| Trophozoite | 0.80 | 0.70 | 0.74 | 317 |
| Accuracy | | | 0.73 | 724 |
| Macro avg | 0.73 | 0.74 | 0.73 | 724 |
| Weighted avg | 0.74 | 0.73 | 0.74 | 724 |
**V2 Confusion Matrix**

**V2 Sample Detections**

---
## V1 to V2 — Progress
| Metric | V1 | V2 | Improvement |
|--------|----|----|-------------|
| Overall mAP@0.5 | 0.735 | 0.830 | +0.095 |
| Overall mAP@0.5:0.95 | 0.513 | 0.638 | +0.125 |
| Ring mAP@0.5 | 0.551 | 0.735 | +0.184 |
| Trophozoite F1 | 0.42 | 0.74 | +0.32 |
| Overall accuracy | 0.63 | 0.73 | +0.10 |
The most significant gain was Trophozoite F1 improving from 0.42
to 0.74 a direct result of increasing its training instances
from 95 to 2283. This confirmed the V1 hypothesis that data volume
was the primary bottleneck.
---
## Limitations
The primary limitation of V1 model is dataset size. Instance
counts across classes are uneven, with Trophozoite having the
fewest examples (95 instances in the test split). The direct
relationship between instance count and F1 score observed across
all three classes confirms that further performance gains require
additional annotated data rather than architectural changes.
In V2 Ring stage remains the weakest class at mAP@0.5 of 0.735. Ring
cells are the smallest and most morphologically subtle stage.
Further gains require additional annotated Ring stage images.
The model is a research prototype and is not validated for
clinical deployment.
---
---
## V2 How to Use
```python
!pip install ultralytics
from huggingface_hub import hf_hub_download
from ultralytics import YOLO
# Load V2 model
weights_path = hf_hub_download(
repo_id = "codeshujaaa/kenyanmalarai-detect",
filename = "weights/best_v2.pt"
)
model = YOLO(weights_path)
results = model.predict(
source = "https://media.istockphoto.com/id/2169552309/photo/plasmodium-vivax-in-thin-film-under-microscope.jpg?s=612x612&w=0&k=20&c=ZjxGlaMKoPQEvJyRAwlZWgugPZMNIV1EiJeO1oP5Z8A=",
conf = 0.15,
iou = 0.5,
imgsz = 640,
)
results[0].show()
```
---
## Repository Structure
```
kenyanmalarai-detect/
weights/
# V1 model
best.pt
# V2 model
best_v2.pt
runs/
# V1 TensorBoard logs
plasmodium/
# V2 TensorBoard logs
plasmodium_v2/
README.md
```
## Citation
If you use this model or findings from this work in your research,
please cite this repository.
```
@misc{mwangi2025plasmodium,
author = {Denis Mwangi},
title = {Plasmodium Life Stage Detection Using YOLO26m on Giemsa-Stained Blood Smears},
year = {2025},
publisher = {Hugging Face},
howpublished = {\url{https://huggingface.co/kenyanmalarai-detect}}
}
```
## Acknowledgements
Training infrastructure provided by Kaggle |