Система классификации изображений: как достичь macro-F1 > 0.95 на реальных данных?
Вы запускаете на production модель для каталога товаров — и получаете macro-F1 = 0.72 из-за сильного дисбаланса классов. Недавно к нам обратился e-commerce проект с датасетом 15 000 изображений, 30 категорий, где 80% картинок относились к пяти категориям. Мы применили комбинацию Weighted Random Sampler и Focal Loss, что подняло macro-F1 с 0.72 до 0.94 за две недели. Ключевой вызов не в самой модели (стандартные бенчмарки пройдены), а в адаптации под специфический домен: шум в разметке, вариации освещения, неполные данные.
Мы также столкнулись с проектом по медицинской диагностике, где требовалось обнаруживать редкие патологии на снимках МРТ. Там дисбаланс был ещё серьёзнее: 99% здоровых и 1% больных. Используя комбинацию oversampling, аугментации и focal loss, мы достигли sensitivity 0.92 при специфичности 0.98.
Какую архитектуру выбрать?
Для большинства задач выбираем 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 |
Для edge-устройств (Raspberry Pi, Jetson Nano) используем MobileNetV3 или EfficientNet-Lite — они работают за 1–2 ms на CPU.
Почему fine-tuning эффективнее обучения с нуля?
Обучение с нуля требует миллионов размеченных примеров. Fine-tuning предобученной модели даёт отличные результаты уже на сотнях изображений на класс. Этот подход описан в Wikipedia: Transfer Learning.
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 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 Стратегия fine-tuning по шагам:
- Заморозить backbone, 5 эпох train only classifier.
- Разморозить последние 2 блока, 10 эпох с LR в 10 раз ниже.
- Полная разморозка, ещё 10 эпох с cosine schedule.
- Оценка на валидации: если метрики не достигнуты — повторить с другими гиперпараметрами.
Типичная ошибка: неразмороженные batch norm слои
При частичной разморозке важно оставить batch norm слои в режиме train, иначе статистики не обновятся, и точность упадёт на 5–10%.Как бороться с дисбалансом классов?
Реальные датасеты редко сбалансированы. Мы комбинируем несколько приёмов:
- Weighted random sampler — частота семплирования обратно пропорциональна размеру класса.
- Focal Loss — фокусируется на сложных примерах (γ=2).
- Oversampling редких классов с помощью аугментации (albumentations).
- Class-weighted cross-entropy — веса 1/class_frequency.
Такой подход поднимает macro-F1 на 15–20% по сравнению с базовым обучением. Закажите пилотный проект — мы покажем результат на ваших данных за две недели. Это позволяет сэкономить до 30% бюджета по сравнению с наймом штатного ML-инженера.
Разница между многоклассовой и многолейбловой классификацией
Многоклассовая — один класс на изображение: softmax + cross-entropy (пример: тип животного). Многолейбловая — несколько классов одновременно: sigmoid + binary cross-entropy (пример: теги фото). Порог срабатывания для каждого класса подбирается отдельно по F1.
Метрики оценки качества модели
- Top-1/Top-5 Accuracy для сбалансированных выборок.
- Macro-averaged F1 для дисбаланса.
- Cohen's Kappa для медицинских задач.
- AUC-ROC per class для многолейбловой.
Процесс работы над системой классификации
Аналитика → проектирование → реализация → тестирование → деплой. На первом этапе мы изучаем ваш датасет, выявляем проблемные классы, оцениваем качество разметки. Затем выбираем архитектуру и проводим серию A/B-экспериментов с гиперпараметрами. После утверждения модели — экспорт в ONNX, контейнеризация и развёртывание в вашу инфраструктуру. Все этапы документируются, ваши инженеры получают доступ к модели и инструкции по эксплуатации. Свяжитесь с нами, чтобы мы подготовили смету и roadmap под ваш проект.
Сроки и стоимость
| Сложность задачи | Срок |
|---|---|
| 2–10 классов, 1000+ фото/класс | 1–2 недели |
| 50+ классов или сложный домен | 3–5 недель |
| Иерархическая классификация, edge деплой | 5–8 недель |
Стоимость рассчитывается индивидуально. Ориентировочно — от $1 000 до $50 000 в зависимости от объёма данных и требований. Экономия на инфраструктуре за счёт оптимизации модели может достигать 40%. Например, на одном проекте мы сократили затраты на $15 000 в год.
Что входит в работу?
- Анализ данных и подготовка датасета.
- Выбор архитектуры и fine-tuning (с A/B-тестами конфигов).
- Оценка качества по выбранным метрикам (отчёт).
- Деплой в виде REST API или встраивание в вашу инфраструктуру.
- Документация и обучение команды.
- Гарантия — если точность не достигает оговорённой, дорабатываем бесплатно.
За годы работы мы реализовали более 50 проектов по классификации изображений для e-commerce, медицины и промышленности. Наши инженеры имеют сертификаты NVIDIA, AWS и Google Cloud, используют MLOps практики для воспроизводимости экспериментов. Мы гарантируем достижение целевых метрик — если точность ниже оговорённой, дорабатываем бесплатно. Свяжитесь с нами, чтобы обсудить ваш проект и получить предварительную оценку сроков.







