Отметим: когда EdTech-стартап просит оценить вовлеченность студентов по веб-камере, а ритейлер хочет анализировать удовлетворенность клиентов в колл-центре — мы предлагаем не прототип, а production-ready систему facial emotion recognition под ключ. Согласно определению, распознавание выражений лица — это технология, позволяющая идентифицировать эмоции человека по изображению лица. Наш опыт: 5+ лет в Computer Vision, 30+ проектов с детекцией лиц, сертификаты NVIDIA NGC Partner. Внедрение такой системы снижает затраты на ручной анализ до 70% и позволяет выявить скрытые паттерны поведения.
Как работает система facial emotion recognition
Система включает два этапа: детекция лица и классификация эмоций. Мы используем InsightFace для детекции (32 мс на T4) и EfficientNet-B0 с ONNX Runtime для классификации (4 мс). Temporal smoothing скользящим окном 30 кадров стабилизирует вывод.
Проблемы, которые решаем — facial emotion recognition
Низкая точность на реальных данных
Публичные модели (EfficientNet-B0 на FER) дают 73.1% — это предел из-за субъективности разметки. Люди не соглашаются в 30-40% случаев. Мы дообучаем модель на вашем датасете: собираем 10-50 тысяч кадров, размечаем в 3 этапа (два разметчика + арбитр). Результат: 84-88% accuracy на целевой выборке.
Задержки в реальном времени
Детекция лица + классификация должны укладываться в 100 мс и менее. Мы используем InsightFace для детекции (32 мс на T4) и EfficientNet-B0 с ONNX Runtime (4 мс). Temporal smoothing скользящим окном 30 кадров стабилизирует вывод.
Почему точность публичных моделей недостаточна?
Датасеты вроде FER собирались в uncontrolled условиях, но метки субъективны. AffectNet содержит 1M фото, но 40% разметки признаны шумными. Чтобы преодолеть этот барьер, мы добавляем аугментацию (повороты, освещение, occlusion) и ансамбль моделей. Важно понимать: accuracy 75% — это потолок для набора FER, потому что даже люди соглашаются только в 60-70% случаев. Для продакшена требуется дообучение под домен.
Как мы повышаем точность до 85%+?
Используем Vision Transformer (ViT-B/16) с fine-tuning на вашем датасете. Сравнение: EfficientNet-B0 — 73.1%, ViT-B/16 — 74.8% на FER, но на доменных данных разрыв достигает 5-7%. Дополнительно применяем label smoothing и Focal Loss для работы с несбалансированными классами. EfficientNet-B0 с Focal Loss лучше vanilla ResNet-18 на 3.1% — разрыв на корпоративных данных достигает 5-8%.
Архитектура модели
Пайплайн: детекция лица → выравнивание → классификация эмоций.
import torch import torch.nn as nn import timm import cv2 import numpy as np from insightface.app import FaceAnalysis class EmotionRecognizer: def __init__(self, model_path: str): # Детекция и выравнивание лица self.detector = FaceAnalysis(allowed_modules=['detection']) self.detector.prepare(ctx_id=0, det_size=(640, 640)) # Классификатор эмоций backbone = timm.create_model('efficientnet_b0', pretrained=False) backbone.classifier = nn.Sequential( nn.Dropout(0.3), nn.Linear(backbone.num_features, 7) ) backbone.load_state_dict(torch.load(model_path)) backbone.eval() self.model = backbone self.emotions = ['angry', 'disgust', 'fear', 'happy', 'neutral', 'sad', 'surprise'] self.transform = get_inference_transform() @torch.no_grad() def predict(self, image: np.ndarray) -> list[dict]: faces = self.detector.get(image) results = [] for face in faces: x1, y1, x2, y2 = face.bbox.astype(int) face_crop = image[y1:y2, x1:x2] face_crop = cv2.resize(face_crop, (48, 48)) tensor = self.transform(face_crop).unsqueeze(0) logits = self.model(tensor) probs = torch.softmax(logits, dim=1).squeeze() emotion_scores = { self.emotions[i]: float(probs[i]) for i in range(7) } dominant = max(emotion_scores, key=emotion_scores.get) results.append({ 'bbox': [x1, y1, x2, y2], 'emotion': dominant, 'confidence': emotion_scores[dominant], 'all_scores': emotion_scores }) return results Датасеты и качество моделей
| Датасет | Размер | Условия | Классы |
|---|---|---|---|
| FER | 35k фото | Дикая природа | 7 |
| AffectNet | 1M фото | Дикая природа | 8 (+ contempt) |
| RAF-DB | 30k фото | Реальные | 7 + compound |
| CK+ | 593 видео | Лабораторные | 7 |
| SFEW | 1766 кадров | Кинофильмы | 7 |
Точность на FER:
- EfficientNet-B0 fine-tuned: 73.1%
- Vision Transformer (ViT-B/16): 74.8%
- EfficientFace: 73.3%
Главная сложность: метки в публичных датасетах субъективны, люди не соглашаются в 30–40% случаев. Accuracy 75% — это предел для набора FER из-за человеческого несогласия. Поэтому качественная разметка под задачу критична.
Дополнительная информация о качестве разметки
Для получения надёжных меток мы привлекаем минимум двух разметчиков. Если их оценки расходятся, подключается арбитр. Это повышает согласованность до 85%.Временная аналитика на видео
Покадровая классификация нестабильна — эмоция «мигает» между кадрами. Решения:
- Temporal smoothing: скользящее среднее по 10–30 кадрам.
- RNN/LSTM поверх frame-level классификатора: учитывает временную динамику.
- Aggregation по интервалу: средняя эмоция за N-секундный интервал для аналитики.
from collections import deque class TemporalEmotionTracker: def __init__(self, window_size: int = 30): self.window = deque(maxlen=window_size) def update(self, emotion_scores: dict) -> dict: self.window.append(emotion_scores) # Усредняем по окну averaged = {} for emotion in emotion_scores: averaged[emotion] = sum( frame[emotion] for frame in self.window ) / len(self.window) return averaged Ограничения и этические аспекты
Важно понимать ограничения технологии:
- Культурные различия в выражении эмоций (мимика варьируется между культурами).
- Нейтральное лицо ≠ нейтральное состояние человека.
- Актёрская мимика отличается от искренней.
Технология не должна использоваться для скрытого мониторинга сотрудников без их ведома. В production всегда требуется юридическое согласие.
Процесс работы
- Аналитика требований и сбор датасета.
- Проектирование архитектуры: выбор backbone, детектора, постобработки.
- Реализация: обучение модели, пайплайн инференса.
- Тестирование на ваших данных (A/B тест).
- Деплой: Docker-контейнер с Triton Inference Server или ONNX Runtime.
Что входит в результат
- Документация пайплайна (Model Card, описание архитектуры).
- Обучение вашей команды работе с моделью.
- Поддержка 3 месяца после внедрения.
- Код с тестами и воспроизводимым обучением.
Сравнение: наш подход vs классический ResNet
Мы используем EfficientNet-B0 с Focal Loss. Прирост точности на FER — 3.1% против Vanilla ResNet-18 (70.0%). На корпоративных данных разрыв достигает 5-8%. Задержка инференса на CPU — 12 мс, на GPU — 3 мс.
| Задача | Срок |
|---|---|
| SDK для мобильного/веб приложения | 2–3 недели |
| Аналитика вовлечённости на видео | 3–5 недель |
| Кастомная модель на корпоративном датасете | 5–8 недель |
Гарантируем: модель сдаётся с метриками не ниже оговорённых, код покрыт тестами, пайплайн воспроизводим. Свяжитесь с нами, чтобы обсудить внедрение распознавания эмоций в ваш продукт. Получите консультацию по архитектуре и оценке сроков.







