Розробка системи визначення емоцій за обличчям (Facial Emotion Recognition)

Проектуємо та впроваджуємо системи штучного інтелекту: від прототипу до production-ready рішення. Наша команда поєднує експертизу в машинному навчанні, дата-інжинірингу та MLOps, щоб AI працював не в лабораторії, а в реальному бізнесі.
Показано 1 з 1Усі 1566 послуг
Розробка системи визначення емоцій за обличчям (Facial Emotion Recognition)
Середній
від 1 тижня до 3 місяців
Часті запитання

Напрямки AI-розробки

Етапи розробки AI-рішення

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1284
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1196
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    901
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1119
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    586
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    853

Розробка систем розпізнавання емоцій за обличчям

Розпізнавання емоцій за мімікою - це завдання класифікації виразу обличчя на базові емоційні стани. Класична модель Екмана виділяє 7 універсальних емоцій: радість, грусть, гнів, страх, здивування, огида, нейтральність. Застосування: аналіз залучення при онлайн-навчанні, моніторинг задоволення клієнтів у call-центрі, дослідження UX, контроль стану водія.

Архітектура моделі

Конвеєр: виявлення обличчя → вирівнювання → класифікація емоцій.

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-2013 35k фото Дикі 7
AffectNet 1M фото Дикі 8 (+ презирство)
RAF-DB 30k фото Реальні 7 + складні
CK+ 593 відео Лабораторні 7
SFEW 1766 кадрів Кіно 7

Точність на FER-2013:

  • EfficientNet-B0 fine-tuned: 73.1%
  • Vision Transformer (ViT-B/16): 74.8%
  • EfficientFace: 73.3%

Головна складність: мітки в публічних наборах даних суб'єктивні, люди не згідні в 30–40% випадків. 75% точність - це практична межа для FER-2013 через людське невідповідність.

Часова аналітика на відео

Покадрова класифікація нестабільна — емоція "мигтить" між кадрами. Рішення:

  • Часова згладжування: ковзне середнє за 10–30 кадрів
  • RNN/LSTM поверх frame-level класифікатора: враховує часову динаміку
  • Агрегація за інтервалом: середня емоція за 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-системи завжди потребують юридичної згоди.

Завдання Графік
SDK для мобільного/веб додатка 2–3 тижні
Аналітика залучення на відео 3–5 тижнів
Кастомна модель на корпоративному наборі даних 5–8 тижнів