Розробка системи класифікації зображень
Класифікація зображень — присвоєння одного або кількох класів кожному зображенню. Практичні застосування: сортування медичних знімків за патологіями, маркування каталогів e-commerce за категоріями, фільтрування контенту користувачів, класифікація дефектів виробництва. Завдання вирішено на рівні вище людського для стандартних бенчмарків ще з 2015 року, але правильна адаптація під конкретний домен вимагає методичного підходу.
Вибір архітектури
Для більшості завдань оптимальний вибір — EfficientNet-B4 або ConvNeXt-Tiny: хороший баланс точності та швидкості інференсу.
| Архітектура | Top-1 ImageNet | Параметри | Latency (T4 GPU) |
|---|---|---|---|
| EfficientNet-B0 | 77.1% | 5.3M | 3.5 ms |
| EfficientNet-B4 | 82.9% | 19M | 9.2 ms |
| ConvNeXt-Tiny | 82.1% | 28M | 7.8 ms |
| ViT-B/16 | 81.8% | 86M | 12.1 ms |
| EfficientNet-B7 | 84.4% | 66M | 28 ms |
Для периферійних пристроїв (Raspberry Pi, Jetson Nano): MobileNetV3, EfficientNet-Lite, YOLO11-cls.
Трансфер-навчання та fine-tuning
Навчання з нуля вимагає мільйонів прикладів. Fine-tuning попередньо навченої моделі дає хороші результати зі сотнями зображень на клас.
import timm
import torch.nn as nn
def build_classifier(num_classes: int,
pretrained_model: str = 'efficientnet_b4'):
model = timm.create_model(
pretrained_model,
pretrained=True,
num_classes=0 # видаляємо оригінальну голову класифікатора
)
embedding_dim = model.num_features # 1792 для B4
# Замораживаємо backbone на ранніх епохах
for param in model.parameters():
param.requires_grad = False
# Користувацька голова класифікації
classifier = nn.Sequential(
nn.Linear(embedding_dim, 512),
nn.GELU(),
nn.Dropout(0.3),
nn.Linear(512, num_classes)
)
model.classifier = classifier
return model
Стратегія навчання: 5 епох із замороженим backbone → розморозити останні 2 блоки → 10 епох з LR у 10 разів меншою → повна розморозка → ще 10 епох із cosine розкладом.
Робота з дисбалансом класів
Реальні датасети рідко збалансовані. Стратегії:
- Взважений випадковий семплер: частота семплювання обернено пропорційна розміру класу
-
Focal Loss:
FL(p) = -(1-p)^γ · log(p), фокусує навчання на складних прикладах (γ=2 — стандартне значення) - Надвибірка рідкісних класів: albumentations аугментація тільки для недопредставлених класів
-
Взважена перехресна ентропія класу: ваги пропорційні
1 / class_frequency
Багатокласова vs багатомітковна класифікація
Багатокласова (один клас на зображення): softmax + cross-entropy. Приклад: тип тварини.
Багатомітковна (кілька класів одночасно): sigmoid + binary cross-entropy. Приклад: теги на фото (природа + гори + захід сонця). Поріг активації вибирається окремо за F1 для кожного класу.
Метрики оцінювання
- Top-1 / Top-5 Accuracy — для збалансованих датасетів
- Macro-averaged F1 — для дисбалансу
- Cohen's Kappa — для медичних завдань
- AUC-ROC per class — для багатомітковної класифікації
Продуктивність і розгортання
Для API-сервісу: ONNX експорт + ONNX Runtime → latency 5–15 ms на CPU (batch=1). Для GPU: TorchServe з динамічним батчингом. Для мобільних: Core ML (iOS), TFLite (Android).
| Складність завдання | Хронологія |
|---|---|
| 2–10 класів, 1000+ фото/клас | 1–2 тижні |
| 50+ класів або складний домен | 3–5 тижнів |
| Ієрархічна класифікація, периферійний розгорт | 5–8 тижнів |







