Fetal Heart IQA β EfficientNetV2-S Quality Classifier
Theodore's Heart Initiative (THI) β Proof of Concept, Phase 3
EfficientNetV2-S trained to classify fetal cardiac ultrasound crops as GREEN (optimal), YELLOW (adjusting), or RED (searching/poor). Used as Step 2 of the two-step CHD screening pipeline:
YOLO11n (localization) β EfficientNetV2-S IQA (quality) β OpenCV overlay
Model Details
| Architecture | EfficientNetV2-S, ImageNet pretrained backbone |
| Task | 3-class image quality classification |
| Input | 224Γ224 RGB crop of YOLO-detected fetal heart ROI |
| Output | Logits for [green, yellow, red] + view head stub |
| Training data | FOCUS dataset (300 expert 4CV images β 1,500 augmented crops) |
| Training platform | Kaggle T4 Γ2, PyTorch 2.10.0+cu128, DataParallel |
| Epochs | 75 per fold |
| Optimizer | AdamW (lr=3e-4, wd=1e-4) + CosineAnnealingLR |
Training Results (5-Fold Cross-Validation)
| Metric | Value |
|---|---|
| Mean val accuracy | 99.89% Β± 0.21% |
| Test accuracy | 97.62% |
| GREEN test acc | 88.10% |
| YELLOW test acc | 100.00% |
| RED test acc | 100.00% |
| Best fold | Fold 1 |
Files
| File | Description |
|---|---|
best_iqa_fold1.pth |
Best fold (use for inference) |
best_iqa_fold{2-5}.pth |
Remaining folds for ensemble use |
iqa_training_summary.json |
Full training history and per-class metrics |
Usage
import torch
import torch.nn as nn
from torchvision.models import efficientnet_v2_s
from torchvision import transforms
from PIL import Image
LABELS = ["green", "yellow", "red"]
class IQAModel(nn.Module):
def __init__(self, num_quality_classes=3):
super().__init__()
base = efficientnet_v2_s(weights=None)
in_features = base.classifier[1].in_features
base.classifier = nn.Identity()
self.backbone = base
self.quality_head = nn.Sequential(
nn.Dropout(p=0.3), nn.Linear(in_features, 256),
nn.SiLU(), nn.Dropout(p=0.2), nn.Linear(256, num_quality_classes),
)
self.view_head = nn.Sequential(nn.Dropout(p=0.3), nn.Linear(in_features, 1))
def forward(self, x):
f = self.backbone(x)
return self.quality_head(f), self.view_head(f)
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
])
model = IQAModel()
model.load_state_dict(torch.load("best_iqa_fold1.pth", map_location="cpu"))
model.eval()
img = Image.open("your_crop.png").convert("RGB")
with torch.no_grad():
q_logits, _ = model(transform(img).unsqueeze(0))
label = LABELS[q_logits.argmax(1).item()]
print(label) # "green", "yellow", or "red"
Limitations & Scope
- Trained on 4-Chamber View (4CV) only β FOCUS dataset (single-center, 300 originals).
- YELLOW and RED classes are synthetically generated from GREEN images via augmentation (blur, rotation, contrast, occlusion, noise). Real-world YELLOW/RED examples were not available at POC stage.
- Not validated on LVOT, RVOT, or 3VV views.
- Not for clinical use.
Citation
Theodore's Heart Initiative, 2026. Internal POC β fetal CHD screening research.