Обучение моделей оценки позы: ViTPose, YOLOv8-pose, MediaPipe
Стандартные модели Pose Estimation — MediaPipe или OpenPose — часто дают сбой в нестандартных сценах: специфическая униформа, необычные ракурсы, частичное перекрытие тела. Например, на производстве, где рабочие выполняют наклоны и подъёмы, COCO-модели показывают до 30% ложных пропусков. Наши инженеры решают эту задачу через кастомное дообучение ViTPose и YOLOv8-pose под вашу онтологию скелета. Мыимеем 5+ лет опыта в компьютерном зрении и десятки внедрений на производствах. Предлагаем услугу «под ключ»: от сбора данных до API-развёртывания.
Решаемые проблемы
Низкая точность на рабочих позах. COCO-модели обучались на бытовых сценах. Для охраны труда нужны наклоны, приседания, подъём груза — иначе до 30% ложных пропусков. Нехватка размеченных данных. Подготовка датасета с keypoints — трудоёмкий этап. Используем активное обучение и аугментацию, чтобы сократить затраты на разметку в 2-3 раза. Latency для real-time. На складе 40 камер — требуемый деплой с Triton Server и квантование модели до INT8 даёт экономию на GPU-инференсе до 40%.
Как подобрать архитектуру для pose estimation?
Выбор зависит от трёх параметров: целевая точность (AP), допустимая задержка (p99 latency) и платформа. MediaPipe даёт <5ms на CPU, но AP ~67.4. YOLOv8l-pose — компромисс: 65.5 AP за 9ms на GPU. ViTPose-H — максимум: 79.1 AP, но 48ms на A100. Мы помогаем подобрать оптимум через профилирование на вашем оборудовании.
Почему ViTPose лучше других моделей?
ViTPose — трансформерная архитектура, на 12% точнее CNN-аналогов (ResNet-50). Она использует self-attention для учёта глобального контекста, что критично при перекрытиях. На COCO benchmark ViTPose-H держит рекорд AP. При этом fine-tuning требует всего 10% размеченных данных от обучения с нуля.
Кастомная онтология скелета
COCO определяет 17 keypoints. Для промышленных задач добавляем точки хватки, шлема, шеи — до 21-22 keypoints. Пример онтологии для охраны труда:
# Кастомная онтология для оценки позы рабочего (охрана труда) WORKER_SKELETON = { 'keypoints': [ 'nose', 'left_eye', 'right_eye', 'left_ear', 'right_ear', 'left_shoulder', 'right_shoulder', 'left_elbow', 'right_elbow', 'left_wrist', 'right_wrist', 'left_hip', 'right_hip', 'left_knee', 'right_knee', 'left_ankle', 'right_ankle', # Расширение для промышленности 'left_hand_center', 'right_hand_center', # для детекции хватки 'head_top', # для шлема 'neck' ], 'skeleton': [ [16, 14], [14, 12], [17, 15], [15, 13], [12, 13], [6, 12], [7, 13], [6, 7], [6, 8], [7, 9], [8, 10], [9, 11], [2, 3], [1, 2], [1, 3], [2, 4], [3, 5], [4, 6], [5, 7], [10, 18], [11, 19], [1, 21], [1, 20] # кастомные соединения ] } Как дообучить ViTPose на кастомном датасете?
Процесс fine-tuning ViTPose включает несколько шагов:
- Подготовка датасета — сбор изображений, разметка keypoints в формате COCO. Используем активное обучение для минимизации ручной разметки.
- Настройка конфигурации — изменение количества keypoints в голове модели, подбор гиперпараметров (learning rate, batch size).
- Запуск обучения — на GPU с поддержкой mixed precision. Мониторинг loss и метрик AP.
- Квантование и оптимизация — конвертация в ONNX с INT8 квантованием, деплой через Triton Inference Server.
Пример кода для создания кастомной модели ViTPose:
import torch import torch.nn as nn from mmpose.apis import init_model, inference_topdown from mmpose.models import build_posenet from mmengine.config import Config def build_vitpose_custom( num_keypoints: int = 21, # кастомное количество точек pretrained_checkpoint: str = 'vitpose_base_coco.pth' ) -> nn.Module: cfg = Config.fromfile('configs/body_2d_keypoint/topdown_heatmap/' 'vitpose/td-hm_ViTPose-base_8xb64-210e_coco-256x192.py') # Меняем голову под новое количество keypoints cfg.model.head.num_joints = num_keypoints cfg.model.test_cfg.num_joints = num_keypoints model = build_posenet(cfg.model) # Загружаем pretrained веса, исключая голову state_dict = torch.load(pretrained_checkpoint)['state_dict'] state_dict_filtered = { k: v for k, v in state_dict.items() if 'keypoint_head' not in k # голову инициализируем заново } model.load_state_dict(state_dict_filtered, strict=False) return model Для быстрого старта используйте ViTPose официальный репозиторий.
YOLOv8-pose — быстрая альтернатива
Для real-time приложений (видеонаблюдение, спорт) выполняем кастомизацию YOLOv8-pose:
from ultralytics import YOLO # Fine-tuning YOLOv8-pose на кастомных данных model = YOLO('yolov8m-pose.pt') results = model.train( data='pose_dataset.yaml', # включает keypoint_shape: [17, 3] imgsz=640, batch=16, epochs=100, device='0', kobj=1.0, # вес лосса keypoint объектности kpt_shape=[17, 3] # [num_keypoints, visibility_flag] ) Анализ позы: определение эргономических нарушений
Кейс из практики: система мониторинга охраны труда на складе. YOLOv8l-pose + классификатор поз, 40 камер, 12 часов в сутки. Стоимость работ рассчитывается индивидуально под ваш проект.
import numpy as np from typing import Optional class ErgoRiskAnalyzer: """ Оценка эргономических рисков по позе рабочего. Метрика: RULA (Rapid Upper Limb Assessment) — стандарт ISO 11228. """ def calculate_trunk_angle( self, left_shoulder: np.ndarray, # [x, y] right_shoulder: np.ndarray, left_hip: np.ndarray, right_hip: np.ndarray ) -> float: """Угол наклона торса от вертикали в градусах""" shoulder_mid = (left_shoulder + right_shoulder) / 2 hip_mid = (left_hip + right_hip) / 2 trunk_vec = shoulder_mid - hip_mid vertical_vec = np.array([0, -1]) # вверх в системе координат изображения cos_angle = np.dot(trunk_vec, vertical_vec) / ( np.linalg.norm(trunk_vec) * np.linalg.norm(vertical_vec) + 1e-6 ) return float(np.degrees(np.arccos(np.clip(cos_angle, -1, 1)))) def assess_lifting_risk( self, keypoints: dict, # {'left_shoulder': [x,y], 'right_shoulder': [x,y], ...} confidence_threshold: float = 0.5 ) -> dict: """ RULA-подобная оценка риска подъёма груза. Риски: прямая спина OK, наклон 20-60° — предупреждение, >60° — критично. """ required_kpts = ['left_shoulder', 'right_shoulder', 'left_hip', 'right_hip'] if not all( keypoints.get(k) is not None and keypoints[k][2] > confidence_threshold for k in required_kpts ): return {'risk': 'unknown', 'reason': 'low_confidence_keypoints'} trunk_angle = self.calculate_trunk_angle( keypoints['left_shoulder'][:2], keypoints['right_shoulder'][:2], keypoints['left_hip'][:2], keypoints['right_hip'][:2] ) if trunk_angle > 60: risk_level = 'critical' elif trunk_angle > 20: risk_level = 'warning' else: risk_level = 'ok' return { 'risk': risk_level, 'trunk_angle_deg': round(trunk_angle, 1), 'rula_trunk_score': 4 if trunk_angle > 60 else (3 if trunk_angle > 20 else 1) } На пилотном проекте (склад, 120 рабочих): система выявила 34 случая систематического подъёма с нарушением в течение смены. После коррекции рабочих мест — снижение жалоб на боли в спине на 41% за 3 месяца.
Сравнение методов
| Модель | AP COCO | Latency | Устройство | Применение |
|---|---|---|---|---|
| MediaPipe Pose | 67.4 | <5ms | CPU/телефон | Мобайл, IoT |
| YOLOv8n-pose | 49.0 | 3ms | GPU | Real-time видео |
| YOLOv8l-pose | 65.5 | 9ms | GPU | Точность+скорость |
| ViTPose-B | 75.8 | 18ms | GPU | Высокая точность |
| ViTPose-H | 79.1 | 48ms | GPU | Максимум |
Что входит в работу
- Анализ требований: выбор архитектуры под latency/точность/платформу
- Сбор и разметка датасета (аугментация, активное обучение)
- Fine-tuning модели (ViTPose/YOLOv8-pose) с подбором гиперпараметров
- Квантование (INT8) и оптимизация инференса (ONNX Runtime, TensorRT)
- Деплой через REST/gRPC (Triton, SageMaker) + мониторинг
- Документация, обучение команды, гарантия 3 месяца
Сроки
| Задача | Срок |
|---|---|
| Fine-tuning стандартного скелета | 2–4 недели |
| Кастомная онтология + обучение | 4–8 недель |
| Полная система с аналитикой поз | 8–14 недель |
Получите консультацию по выбору архитектуры для вашей задачи. Наши инженеры помогут подобрать модель под ваши latency и точность. Свяжитесь с нами для оценки вашего проекта — мы проанализируем требования и предложим оптимальное решение.







