Facial Emotion Recognition: разработка системы определения эмоций

Отметим: когда EdTech-стартап просит оценить вовлеченность студентов по веб-камере, а ритейлер хочет анализировать удовлетворенность клиентов в колл-центре — мы предлагаем не прототип, а production-ready систему facial emotion recognition под ключ. Согласно определению, <cite>[распознавание выражени

Направления AI-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1414
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1285
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    982
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1241
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    697
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    983

Отметим: когда 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 всегда требуется юридическое согласие.

Процесс работы

  1. Аналитика требований и сбор датасета.
  2. Проектирование архитектуры: выбор backbone, детектора, постобработки.
  3. Реализация: обучение модели, пайплайн инференса.
  4. Тестирование на ваших данных (A/B тест).
  5. Деплой: 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 недель

Гарантируем: модель сдаётся с метриками не ниже оговорённых, код покрыт тестами, пайплайн воспроизводим. Свяжитесь с нами, чтобы обсудить внедрение распознавания эмоций в ваш продукт. Получите консультацию по архитектуре и оценке сроков.