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
```

![image](https://cdn-uploads.huggingface.co/production/uploads/6950f0ce20339b949d1af441/Dl6OrYownRJDjw2FlToDA.png)

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


![image](https://cdn-uploads.huggingface.co/production/uploads/6950f0ce20339b949d1af441/Mq8PCENsXNtrFkUSg2PLg.png)

`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

![image](https://cdn-uploads.huggingface.co/production/uploads/6950f0ce20339b949d1af441/MwBIQBbDp7udNodaGhavq.png)

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.

![image](https://cdn-uploads.huggingface.co/production/uploads/6950f0ce20339b949d1af441/WofAdFNrmXDcEW6vh4_Sa.png)


---

## 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**

![image](https://cdn-uploads.huggingface.co/production/uploads/6950f0ce20339b949d1af441/CFnPN22w3PnGXP0J3GhJI.png)

**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**

![image](https://cdn-uploads.huggingface.co/production/uploads/6950f0ce20339b949d1af441/DvalDPNAy3FVq0JobUxhX.png)

**V2 Sample Detections**

![image](https://cdn-uploads.huggingface.co/production/uploads/6950f0ce20339b949d1af441/e-GuF-xTftjaPTbLQxbAd.png)

---

## 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