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

Когда бизнесу нужно понять эмоции клиентов или сотрудников по лицу, мы разрабатываем систему facial emotion recognition, которая анализирует мимику в реальном времени. Наша команда реализует проект под ключ — от сбора данных и обучения модели до внедрения и последующей поддержки, обеспечивая надёжное решение, которое масштабируется вместе с вашими задачами.
Часто задаваемые вопросы

Отметим: когда 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 недель

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

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

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

  • Разработка сайта компании B2B ADVANCE
    Разработка сайта компании B2B ADVANCE
    1542
  • Разработка веб-приложения для компании FEEDME
    Разработка веб-приложения для компании FEEDME
    1393
  • Разработка веб-сайта для компании БЕЛФИНГРУПП
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1081
  • Разработка интернет магазина для компании FURNORO
    Разработка интернет магазина для компании FURNORO
    1368
  • Разработка логотипа компании B2B Advance
    Разработка логотипа компании B2B Advance
    815
  • Разработка веб-приложения для компании Enviok
    Разработка веб-приложения для компании Enviok
    1139