CerviScan AI β EfficientNet-B0 Cervical Cytology Classifier
5-class Pap smear cell classifier (EfficientNet-B0, timm backbone + custom head, ~4.3M parameters) trained on the SIPaKMeD dataset for AI-assisted cervical cancer screening in resource-limited settings.
Classes
Dyskeratotic Β· Koilocytotic Β· Metaplastic Β· Parabasal Β· Superficial-Intermediate
Results
80/20 stratified split Β· 810 validation images Β· seed 42
| Cell type | Category | Precision | Recall | F1 | Support |
|---|---|---|---|---|---|
| Dyskeratotic | Abnormal | 0.9878 | 0.9939 | 0.9908 | 163 |
| Koilocytotic | HPV-related | 0.9752 | 0.9515 | 0.9632 | 165 |
| Metaplastic | Abnormal | 0.9750 | 0.9811 | 0.9781 | 159 |
| Parabasal | Normal | 1.0000 | 1.0000 | 1.0000 | 157 |
| Superficial-Intermediate | Normal | 0.9821 | 0.9940 | 0.9880 | 166 |
Overall accuracy: 98.40% Β· macro F1: 0.9840
Binary triage view (Normal vs Abnormal)
The deployment decision is binary β flag for human review or clear:
| Metric | Value |
|---|---|
| Triage accuracy | 99.51% (806/810) |
| Abnormal sensitivity | 99.38% (484/487) |
| Normal specificity | 99.69% (322/323) |
| Missed abnormal cells | 3 of 487 (0.62%) |
Of the 13 total 5-class errors, 10 are harmless abnormal-subtype swaps (still routed to human review) and 1 is a false alarm β only 3 abnormal cells escaped as normal. Koilocytotic β Metaplastic is the dominant confusion pair, consistent with published SIPaKMeD benchmarks.
Files
| File | Size | Purpose |
|---|---|---|
cervical_b0_fp16.onnx |
8.32 MB | Browser inference (onnxruntime-web) β verified 98.40% on the full validation set |
cervical_b0.onnx |
16.53 MB | fp32 fallback β verified, parity 1.3e-07 vs PyTorch |
cervical_model.pth |
16.83 MB | Self-describing checkpoint (weights + class order + normalization stats + architecture) |
Usage
import numpy as np
import onnxruntime as ort
from PIL import Image
MEAN = np.array([0.485, 0.456, 0.406], dtype=np.float32)
STD = np.array([0.229, 0.224, 0.225], dtype=np.float32)
CLASSES = ["Dyskeratotic", "Koilocytotic", "Metaplastic", "Parabasal",
"Superficial-Intermediate"]
img = Image.open("cell.png").convert("RGB").resize((224, 224))
x = (np.asarray(img, dtype=np.float32) / 255.0 - MEAN) / STD
x = x.transpose(2, 0, 1)[None] # HWC -> CHW, add batch dim
sess = ort.InferenceSession("cervical_b0_fp16.onnx",
providers=["CPUExecutionProvider"])
logits = sess.run(None, {sess.get_inputs()[0].name: x})[0]
probs = np.exp(logits) / np.exp(logits).sum()
print(CLASSES[int(probs.argmax())], f"{probs.max():.1%}")
Training details
- Architecture: timm efficientnet_b0 (num_classes=0) + head:Dropout(0.4) β Linear(1280β256) β ReLU β Dropout(0.2) β Linear(256β5)
- Data: SIPaKMeD, 4,049 isolated cell images, 80/20 stratified split
- Augmentation: random horizontal flip, random rotation (Β±30Β°), color jitter (0.2)
- Optimization: AdamW (lr 1e-4, weight decay 1e-4), cosine annealing,batch size 32, early stopping (patience 7) on validation accuracy
Limitations & disclaimer
Trained and validated on isolated cells from a single public dataset (SIPaKMeD); performance on whole slides, different scanners, stains, or clinical populations is untested. Research prototype β not a medical device. Class order and normalization statistics are embedded in the checkpoint for verification.
Dataset citation
SIPaKMeD β Pap smear cell images: https://www.kaggle.com/datasets/akshaykrishnan/sipakmed5
Training notebook: https://www.kaggle.com/ethioel/cervicalcancerdetector