Класифікація зображень присвоює мітки зображенням - це кіт чи собака, дефект чи ні, пухлина чи здорова тканина. Deep learning революціонізував цю сферу, а transfer learning робить її доступною без масивних датасетів. Продакшн-системи мають обробляти реальну варіативність зображень, ефективно масштабуватись та gracefully обробляти помилки.
Де це використовується
Класифікація зображень забезпечує візуальне розпізнавання в різних галузях:
- Виробництво: Виявлення дефектів, контроль якості
- Медицина: Медичні зображення, патологія, радіологія
- Рітейл: Розпізнавання товарів, візуальний пошук
- Сільське господарство: Виявлення хвороб рослин, оцінка врожаю
- Безпека: Модерація контенту, виявлення загроз
- Автомобільна: Розпізнавання дорожніх знаків, розуміння сцени
Продукти: Google Photos, Pinterest Lens, медичні діагностичні інструменти, промислові інспекційні системи.
Типові дані
| Аспект | Типові значення |
|---|---|
| Тренувальні зображення | 1K-10M |
| Розмір зображення | 224x224 - 512x512 |
| Класи | 2-1000+ |
| Class imbalance | Часто 10:1 - 100:1 |
| Якість міток | Варіативна, часто шумна |
Джерела даних: - Розмічені датасети зображень - Web-scraped зображення - Production дані з мітками - Синтетичні дані та аугментація - Pre-labeled датасети (ImageNet, COCO)
Що ви робите на практиці
- Визначте класи - Які категорії потрібно розрізняти?
- Зберіть та розмітьте дані - Якісні мітки критичні
- Preprocessing зображень - Resize, normalize, обробка форматів
- Застосуйте аугментацію - Збільшіть ефективний розмір датасету
- Оберіть архітектуру - Transfer learning vs кастомна
- Натренуйте модель - Fine-tune або з нуля
- Ретельно оцініть - Per-class метрики, error analysis
- Оптимізуйте для деплою - Quantization, pruning, ONNX
- Деплойте з моніторингом - Latency, розподіл confidence
- Обробіть edge cases - Out-of-distribution, adversarial
Спочатку бейзлайн
Почніть з pre-trained моделі та простого fine-tuning:
import torch
import torchvision.models as models
from torchvision import transforms
# Завантажити pre-trained ResNet
model = models.resnet50(weights='IMAGENET1K_V2')
# Замінити фінальний шар для ваших класів
num_classes = 10
model.fc = torch.nn.Linear(model.fc.in_features, num_classes)
# Заморозити ранні шари для швидшого тренування
for param in model.parameters():
param.requires_grad = False
for param in model.fc.parameters():
param.requires_grad = True
# Стандартний preprocessing
preprocess = transforms.Compose([
transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225]
)
])
Чому transfer learning бейзлайн: - Працює добре з обмеженими даними (сотні зображень) - Швидко тренувати (хвилини-години) - State-of-the-art фічі з ImageNet - Легко ітерувати та покращувати
Вибір архітектури
| Архітектура | Розмір | Точність | Швидкість | Use Case |
|---|---|---|---|---|
| MobileNetV3 | 5-20MB | Добра | Дуже швидка | Mobile, edge |
| EfficientNet-B0 | 20MB | Дуже добра | Швидка | Збалансований |
| ResNet-50 | 98MB | Добра | Середня | Загального призначення |
| ConvNeXt | 350MB | Відмінна | Повільна | Максимальна точність |
| ViT | 300MB+ | Відмінна | Повільна | Великі датасети |
Критерії вибору: - Ціль деплою (сервер, mobile, edge) - Вимоги до latency - Розмір датасету - Вимоги до точності
Приклад з EfficientNet:
from torchvision.models import efficientnet_b0, EfficientNet_B0_Weights
# Завантажити з останніми вагами
weights = EfficientNet_B0_Weights.IMAGENET1K_V1
model = efficientnet_b0(weights=weights)
# Модифікувати classifier
model.classifier[1] = torch.nn.Linear(1280, num_classes)
Data Augmentation
Аугментація критична для генералізації:
from torchvision import transforms
import albumentations as A
# Базова аугментація
train_transform = transforms.Compose([
transforms.RandomResizedCrop(224, scale=(0.8, 1.0)),
transforms.RandomHorizontalFlip(),
transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2),
transforms.RandomRotation(15),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])
# Просунута аугментація з Albumentations
train_transform_albu = A.Compose([
A.RandomResizedCrop(224, 224, scale=(0.8, 1.0)),
A.HorizontalFlip(p=0.5),
A.ShiftScaleRotate(shift_limit=0.1, scale_limit=0.1, rotate_limit=15),
A.OneOf([
A.GaussNoise(var_limit=(10, 50)),
A.GaussianBlur(blur_limit=3),
A.MotionBlur(blur_limit=3),
], p=0.3),
A.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),
A.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
A.pytorch.ToTensorV2()
])
Стратегії аугментації по доменах:
| Домен | Корисні аугментації |
|---|---|
| Природні зображення | Flip, crop, color jitter, rotation |
| Медичні | Rotation, elastic deform, intensity shift |
| Виробництво | Зміни освітлення, перспектива, шум |
| Документи | Легка ротація, blur, контраст |
Training Pipeline
import torch
from torch.utils.data import DataLoader
from tqdm import tqdm
def train_epoch(model, dataloader, criterion, optimizer, device):
model.train()
running_loss = 0.0
correct = 0
total = 0
for images, labels in tqdm(dataloader):
images, labels = images.to(device), labels.to(device)
optimizer.zero_grad()
outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
_, predicted = outputs.max(1)
total += labels.size(0)
correct += predicted.eq(labels).sum().item()
return running_loss / len(dataloader), correct / total
# Training loop зі scheduler
optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4, weight_decay=0.01)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=epochs)
criterion = torch.nn.CrossEntropyLoss(label_smoothing=0.1)
for epoch in range(epochs):
train_loss, train_acc = train_epoch(model, train_loader,
criterion, optimizer, device)
val_loss, val_acc = evaluate(model, val_loader, criterion, device)
scheduler.step()
print(f"Epoch {epoch}: Train {train_acc:.3f}, Val {val_acc:.3f}")
Оцінка та метрики
| Метрика | Що вимірює | Коли використовувати |
|---|---|---|
| Accuracy | Загальна коректність | Збалансовані класи |
| Per-class Accuracy | Продуктивність по класах | Imbalanced дані |
| Confusion Matrix | Патерни помилок | Розуміння failures |
| Top-5 Accuracy | Правильно в топ 5 передбаченнях | Багато класів |
| AUC-ROC | Якість ранжування | Бінарні проблеми |
Комплексна оцінка:
from sklearn.metrics import classification_report, confusion_matrix
import seaborn as sns
def evaluate_model(model, dataloader, class_names, device):
model.eval()
all_preds = []
all_labels = []
all_probs = []
with torch.no_grad():
for images, labels in dataloader:
images = images.to(device)
outputs = model(images)
probs = torch.softmax(outputs, dim=1)
_, preds = outputs.max(1)
all_preds.extend(preds.cpu().numpy())
all_labels.extend(labels.numpy())
all_probs.extend(probs.cpu().numpy())
# Classification report
print(classification_report(all_labels, all_preds,
target_names=class_names))
# Confusion matrix
cm = confusion_matrix(all_labels, all_preds)
plt.figure(figsize=(10, 8))
sns.heatmap(cm, annot=True, fmt='d',
xticklabels=class_names, yticklabels=class_names)
plt.xlabel('Predicted')
plt.ylabel('True')
return all_preds, all_labels, all_probs
Режими відмов та чеклист налагодження
- [ ] Data leakage: Те саме зображення в train і test (різні crops)
- [ ] Label noise: Неправильно розмічені training приклади
- [ ] Class imbalance: Модель ігнорує рідкісні класи
- [ ] Domain shift: Training дані відрізняються від production
- [ ] Overfitting: Ідеальний train, поганий test performance
- [ ] Adversarial vulnerability: Малі збурення обманюють модель
- [ ] Out-of-distribution: Модель впевнена на невідомих класах
Чеклист для продакшну
Перед деплоєм: - [ ] Модель протестована на held-out даних що відповідають production - [ ] Per-class performance прийнятний - [ ] Розмір моделі підходить для deployment target - [ ] Latency відповідає вимогам - [ ] Калібрація confidence перевірена - [ ] Edge cases задокументовані
Після деплою: - [ ] Prediction latency моніториться - [ ] Розподіл confidence відстежується - [ ] Low-confidence predictions флагуються - [ ] Періодична валідація accuracy - [ ] Model versioning на місці
Оптимізація для деплою:
import torch
import onnx
# Export в ONNX
dummy_input = torch.randn(1, 3, 224, 224)
torch.onnx.export(
model, dummy_input, "model.onnx",
input_names=['image'],
output_names=['predictions'],
dynamic_axes={'image': {0: 'batch'}}
)
# Quantization для швидшого inference
model_quantized = torch.quantization.quantize_dynamic(
model, {torch.nn.Linear}, dtype=torch.qint8
)
Обробка Edge Cases
Thresholding по confidence:
def predict_with_threshold(model, image, threshold=0.8):
"""Передбачення з порогом confidence."""
model.eval()
with torch.no_grad():
output = model(image.unsqueeze(0))
probs = torch.softmax(output, dim=1)
max_prob, pred_class = probs.max(1)
if max_prob.item() < threshold:
return None, max_prob.item() # Невпевнений
return pred_class.item(), max_prob.item()
Out-of-distribution detection: - Моніторити entropy передбачень - Відстежувати відстань від training distribution - Використовувати ensemble disagreement - Реалізувати human review pipeline
Інструменти та стек
| Категорія | Інструменти |
|---|---|
| Фреймворки | PyTorch, TensorFlow, Keras |
| Pretrained моделі | torchvision, timm, HuggingFace |
| Аугментація | Albumentations, torchvision, imgaug |
| Розмітка | Label Studio, CVAT, Labelbox |
| Деплоймент | ONNX, TensorRT, TorchServe, Triton |
| Edge | TFLite, CoreML, ONNX Runtime |
Приклад міні-кейсу
Сценарій: Виробнича компанія потребує виявлення дефектів у зображеннях продуктів (подряпина, вм'ятина, зміна кольору, добре).
Підхід: 1. Дані: 10K розмічених зображень (7K добре, 1K кожного типу дефекту) 2. Бейзлайн: ResNet-50 pretrained, fine-tuned - Accuracy: 89% 3. Аугментація: Ротація, яскравість, шум - Accuracy: 93% 4. Class weights: Обробка imbalance - Recall покращився на 15% 5. Деплоймент: ONNX + TensorRT на edge device
Результати: - Загальна accuracy: 94% - Defect recall: 97% (пріоритет над precision) - Latency: 15ms на edge GPU - False positive rate: 3%
Ключові уроки: - Хороше освітлення критичне - тренували з lighting augmentation - Edge cases потребували перегляду розмітки людиною - Confidence threshold зменшив false alarms у production
Пов'язані сторінки
- Індекс: ML Field Guide
- Object Detection
- Бінарна класифікація
- Мультикласова класифікація
Додаткове читання
- PyTorch Image Models (timm)
- Transfer Learning in Computer Vision
- Albumentations Documentation
- Model Deployment with ONNX
Спробуйте наживо
Дослідіть пов'язану модель на практиці: відкрийте Convolutional Neural Network Simulator і змінюйте параметри під час роботи. Усе лишається у вашому браузері.
▶ Відкрити симуляцію Convolutional Neural Network Simulator