Домашнее задание из 5-2 звучало так: «откуда берутся ручки (латентные переменные)[прим.]?» Теперь мы найдём ручки, глядя только на данные. По 600 сценам с человечком-палочкой построим кодировщик, который сжимает 1 196 чисел до k, и декодер, который разворачивает k чисел обратно в 1 196. Даже после сжатия до 16 чисел и развёртывания возвращается 99.8% движения. А затем с помощью этих сжатых чисел мы уберём дрожание, восстановим скрытый локоть, сделаем распознавание выброса мусора из 5-1 точнее на малых данных и выполним генерацию из 5-2 без заданных ручек.
Генератор D из 5-2 победил потому, что заранее знал три ручки (скорость · положение · размер). Реальные данные приходят без ручек. Миссия этой части — найти ручки самостоятельно, глядя только на 600 сцен.
Кодировщик сжимает оригинал слева до k чисел (фиолетовые столбики в центре), а декодер разворачивает их обратно в 1 196 (справа). Уменьшайте размер узкого места k и смотрите, до какой степени можно сжать.
| Узкое место k | Степень сжатия | Объяснённая дисперсия | Ошибка восстановления (RMSE) | Ошибка длины костей |
|---|---|---|---|---|
| 1 | в 1 196 раз | 85.72% | 0.1021 | 6.16% |
| 2 | в 598 раз | 95.07% | 0.0598 | 7.65% |
| 3 | в 398.7 раза | 97.84% | 0.0395 | 2.78% |
| 5 | в 239.2 раза | 99.02% | 0.0266 | 1.95% |
| 8 | в 149.5 раза | 99.46% | 0.0195 | 1.86% |
| 16 | в 74.8 раза | 99.80% | 0.0123 | 1.50% |
| 32 | в 37.4 раза | 99.90% | 0.0088 | 1.43% |
В тестовые сцены подмешано дрожание оценки позы (σ = 0.008). Ошибка 0.0088 при k = 32 почти равна величине этого дрожания. Дальше модель запоминает уже не движение, а дрожание.
Собрав 600 сцен, мы по очереди нашли «направления, по которым движение меняется сильнее всего» (метод главных компонент, PCA). Кодировщик вычитает из сцены среднюю сцену и проецирует её на k таких направлений, получая k чисел. Декодер прибавляет к средней сцене k направлений, умноженных на эти числа. Это простейший автокодировщик — только сложение и умножение. Автокодировщик на нейросети с помощью слоёв и функций активации передаёт и криволинейные связи (3-7). 16 направлений на этой странице — это значения, вычисленные в коде 1, без изменений.
Это карта 600 сцен по ручкам 1 и 2. Нажмите на точку, чтобы выбрать сцену, и покрутите четыре ручки ниже. У ручек нет названий. Посмотрите, что меняется, и придумайте им названия сами.
Сцены одного вида собираются на карте рядом. Никто не говорил «это бросок» — мы только сжимали, и всё же так вышло. Значения ручек выражены в единицах стандартного отклонения (σ) обучающих сцен. За пределами ±2σ — область, которой почти не было в обучающих данных, поэтому развёрнутая поза выглядит неестественно.
| Ручка | Где изменения сильнее всего | Прозвище по наблюдениям | Среднее по видам сцен (код 1) |
|---|---|---|---|
| 1 (85.7% движения) | x всех суставов, конец сцены | «Где оказывается в конце» — остаётся перед урной или уходит вправо | положить −15.3 · бросок +8.3 · проход мимо +6.4 · уронить +6.7 |
| 2 (9.4%) | x правого запястья, локтя и лодыжек, начало сцены | «Где начинает и с какой стороны держит правую руку» | проход мимо −4.4 · взмах рукой +4.1 |
| 3 (2.8%) | y правого запястья, локтя и головы | «Поднимает руку или наклоняется» | взмах рукой +2.6 · поднять −2.1 |
| 4 (1.2%) | x правого запястья и лодыжек, середина сцены | «Покачивание рук и ног влево-вправо в середине» | поднять +1.3 · бросок −0.9 |
Ручки из 5-2 (скорость · положение · размер) задал человек, когда создавал сцены. Здесь же ручки — это направления, по которым данные меняются сильнее всего, выбранные по очереди. Поэтому у них нет названий, и в одной ручке смешано несколько смыслов (ручка 1 — это и положение, и «ушёл ли человек»). Зато их можно найти, даже если человек ничего не подсказывает. Это и есть латентное пространство.
При реальной оценке позы точки суставов дрожат, а когда рука закрыта телом, точка теряется. Воронка пропускает только то, что «похоже на человеческое движение», поэтому после сжатия и развёртывания дрожание отфильтровывается, а пропуски правдоподобно заполняются.
При дрожании σ = 0.01 ошибка 0.0100 → 0.0082, при σ = 0.03 — 0.0300 → 0.0090, при σ = 0.05 — 0.0501 → 0.0104. Чем сильнее дрожание, тем больше эффект. Дрожание направлено хаотично и поэтому почти не попадает на 16 направлений воронки.
Если подобрать 16 латентных чисел только по видимым ячейкам методом наименьших квадратов и развернуть их декодером, заполнятся и пустые ячейки. Ошибка положения: «заткнуть средней точкой между плечом и запястьем» — 0.0230, «заполнить декодером» — 0.0108, то есть примерно в 2.1 раза точнее. Так закрывается проблема из 5-1: «когда рука закрыта телом, сустав не находится».
В 5-1 говорилось: «если обучаться прямо на координатах, данных нужно гораздо больше». На этот раз мы сначала сжимаем кодировщиком координаты суставов и банки (1 288 чисел), а затем обучаем простейшую логистическую регрессию на k сжатых числах.
| Обучающие сцены (на вид) | 1 288 чисел как есть + MLP | сжатие до k = 8 + логистическая регрессия | сжатие до k = 16 + логистическая регрессия |
|---|---|---|---|
| 25 (всего 150) | 96.7% | 95.0% | 99.7% |
| 50 (всего 300) | 97.0% | 95.3% | 100.0% |
| 100 (всего 600) | 98.0% | 98.0% | 100.0% |
k = 16 + логистическая регрессия: обучившись всего на 25 сценах каждого вида (150 всего), модель верно определила 299 из 300 тестовых сцен. В 16 числах вместе сжаты и «где банка в конце», и «куда ушёл человек», поэтому классы можно разделить даже одной прямой.
k = 8 недостаточно: мелкие движения вроде конечного положения банки содержатся в направлениях начиная с 9-го, поэтому при сжатии до 8 часть теряется. Сжимать посильнее — не всегда ответ.
Почему не так, как 92.3% в 5-1: в 5-1 «нет объекта» обозначалось координатой −9, а здесь — (0, 0). Одна лишь смена обозначения на входе поднимает MLP до 98%. Все три столбца этой таблицы сравниваются на одинаковом входе.
Кодировщик построен только по сценам, без меток (использованы все 600, но правильные ответы «выброс/норма» он не видел). Полученная так «сводка движения» очищена от шума и состоит из немногих чисел, поэтому классификатор не путается, даже если размеченных сцен мало. Сначала учить представление на неразмеченных данных, а затем доучивать на небольшом числе правильных ответов — это та же базовая схема, по которой сегодня обучают большие модели. Но учтите: эти числа получены на синтетических данных. На реальном видео они ниже.
Эксперт из 5-2 вернулся. Новый генератор E не знает ручек, заданных человеком. Он смотрит, где на латентной карте собираются броски (среднее и стандартное отклонение), вытягивает новые 16 чисел и разворачивает их декодером.
| Генератор | Знает ли ручки заранее | Ошибка длины костей | Дрожание | Макс. скорость запястья | Разнообразие | Новизна |
|---|---|---|---|---|---|---|
| A Одно среднее | — | 1.7% | 0.0045 | 1.36 | 0.000 | 0.033 |
| B Кубик для каждой координаты | — | 44.2% | 0.2659 | 10.00 | 0.149 | 0.109 |
| C Выбрать одну и скопировать | — | 4.7% | 0.0300 | 2.75 | 0.125 | 0.000 |
| D Выбор 3 ручек | Знает (заданы человеком) | 0.0% | 0.0125 | 2.71 | 0.123 | 0.022 |
| E — вытянуть из 16 латентных чисел | Не знает (нашли данные) | 3.7% | 0.0122 | 1.76 | 0.114 | 0.047 |
Что удалось E: не зная ручек, он не ломается, как B (ошибка костей 44.2% → 3.7%, дрожание 0.27 → 0.012). Результаты разнообразны (0.114) и не скопированы (0.047).
Что не удалось E: максимальная скорость запястья — 1.76, бросок потерял силу. Поскольку он вытягивает точки около среднего в латентном пространстве и лишь складывает прямолинейные направления, короткий миг быстрого замаха размывается. И длины костей не так точны, как у настоящих движений (0%).
Линейный декодер лишь складывает направления в заданных пропорциях и не может передать криволинейные связи вроде «рука описывает круг». Поэтому в реальных исследованиях генерации движений используют многослойные нелинейные кодировщики и декодеры [R2] и одновременно обучают латентное пространство принимать форму нормального распределения, чтобы получилось пространство, где «что ни вытянешь — разворачивается правдоподобно» (VAE [R1]). Есть и VAE для движений, учитывающие ось времени [R4].
Кодировщик и декодер улучшили и распознавание, и генерацию. Но кое-что осталось.
Оба кода используют только библиотеки, установленные в Colab по умолчанию. Нажмите «Скачать ноутбук (.ipynb)» и откройте его в Colab через Файл → Загрузить блокнот или скопируйте код и вставьте в ячейку нового ноутбука.
По 600 сценам строятся encode и decode, затем измеряются ошибка восстановления для каждого k, устранение дрожания и восстановление скрытого локтя (fill). Отсюда и взялись 16 направлений на этой странице. Чтобы подставить свои данные, поместите на место S свои данные формы (число сцен, число чисел). Данные датчиков и логов можно сжимать точно так же.
Распознавание выброса мусора из 5-1 сравнивается в вариантах «MLP на данных как есть» и «сжатие + логистическая регрессия» при разном числе обучающих сцен, а генератор E оценивается по оценочному листу Эксперта из 5-2. Таблицы разделов 5 и 6 построены прямо по этому выводу.
Эти промпты нужно вставлять в ИИ-помощники вроде ChatGPT, Qwen или Claude. При нажатии «Копировать» после промпта добавляется выбранный код. Замените текст в 〔 〕 на свою ситуацию.
Ответ ИИ — лишь отправная точка. Предложенные статьи, цифры и библиотечные функции обязательно проверяйте по первоисточникам и официальной документации. Прежде чем использовать реальные данные о движениях людей, убедитесь в наличии согласия на съёмку и проверьте условия использования датасета.
Это тот же словарь, что и у терминов с жёлтым пунктирным подчёркиванием в тексте. Нажмите на название раздела, чтобы перейти туда, где термин встретился впервые.
Аналогия — первый шаг к пониманию, но и семя заблуждения. У аналогий с человеческим восприятием указана сила соответствия. Прямая — есть данные, что это действительно делает то же самое · Частичная — похожи лишь некоторые свойства · Нет — соответствие неизвестно
| Понятие | Бытовая аналогия | Аналогия с восприятием человека | Где аналогия не работает |
|---|---|---|---|
| Кодировщик и декодер | Сложить одежду в чемодан, а в гостинице развернуть | Частично Запомнить длинный танец несколькими словами вроде «левая нога, хлопок, поворот», а потом станцевать его снова | Одежда после складывания остаётся прежней, а воронка выбрасывает мелкие складки (дрожание). Выброшенное не вернётся и после развёртывания |
| Размер узкого места k | Ограничение на число знаков в аннотации | Нет | В аннотации важное выбирает человек, а эта воронка выбирает «то, что сильно меняется». Мелкое, но важное отличие (конечное положение банки) может потеряться |
| Латентное пространство | Нанести рестораны на карту с двумя осями: «цена · острота» | Нет | Оси карты ресторанов задаёт человек, а оси латентного пространства задают данные, и у них нет названий |
| Восстановление перекрытий | Угадывать стёртые буквы по контексту до и после | Частично Человеческое восприятие, которое угадывает скрытую руку по позе всего тела | Догадка верна только в пределах изученных движений. Незнакомую позу воронка ошибочно достраивает в сторону знакомой |
| Выборка из латентного пространства | Ткнуть на карте «где-то возле этого района» и отправиться туда | Нет | Если ткнуть в пустое место карты (где не было обучающих данных), окажешься в странном месте |
E-1 Об авторе · E-2 Научные источники · E-3 Источники рисунков и чисел
Методическая памятка для преподавателей, наставников по обучению на рабочем месте (OJT) и тьюторов. Время указано ориентировочно — подстройте его под своё занятие.
| Для кого | Студенты и работающие специалисты, прошедшие 5-1 и 5-2. Практики, работающие с большими зашумлёнными данными — датчиков, видео, логов |
|---|---|
| Что нужно знать заранее | «Движение — это таблица» и оценка генераторов из 5-2, скалярное произведение векторов (перемножить элементы на одинаковых позициях и сложить) |
| Цели обучения | ① Объяснить смысл кодировщика, декодера и узкого места k с помощью рисунка воронки ② Привести примеры того, как сжатие и развёртывание используются для устранения дрожания, восстановления перекрытий, обучения на малых данных и генерации ③ Объяснить ограничения линейного кодировщика и почему нужен VAE |
| Ориентировочное время | Чтение 35–45 мин · демонстрация анимаций 25 мин · практика в Colab 30 мин (код 1 — 10 мин, код 2 — 1 мин запуск + 19 мин разбор) |
Введение 5 мин (раздел 1, домашнее задание из 5-2) → раздел 2: уменьшаем k в воронке, 12 мин → раздел 3: крутим ручки, 10 мин → раздел 4: дрожание и перекрытие, 8 мин → разделы 5 и 6: чтение таблиц, 10 мин → проверочные вопросы, 5 мин.
Раздел 2, 15 мин → обсуждение «сколько чисел» и «сколько реально независимых чисел» в наших данных (датчики, логи), 15 мин → разделы 4 и 5: примеры удаления шума и обучения на малом числе ответов, 20 мин → подставляем свои данные в код 1, 30 мин → раздел 7: подведение итогов по ограничениям, 10 мин.
Начинающим — только разделы 2 и 4. Учащиеся среднего уровня пусть вручную проследят encode и decode из кода 1, а затем нарисуют Vt[0] и проверят, почему ручка 1 из раздела 3 — это «положение в конце».
| Раздел | Вопрос, на котором стоит остановиться | Совет по управлению |
|---|---|---|
| 2 Воронка | «Сколько нужно чисел, чтобы бросок выглядел как бросок?» | Увеличивайте k = 1 → 3 → 8 и смотрите на результат справа |
| 3 Латентная карта | «Никто не подсказывал — почему же сцены одного вида собрались вместе?» | Выберите одну красную точку (бросок) и поверните ручку 1 на −2σ |
| 4 Дрожание и перекрытие | «Как воронка отличает дрожание от движения?» | Включите одновременно σ = 0.05 и скрытие локтя |
| 5 Выброс мусора | «Почему k = 8 хуже, чем k = 16?» | Сначала прочитайте строку таблицы с 25 сценами |
| 6 Генерация | «Чего E знает меньше, чем D, и что у него получается хуже?» | Нажмите «Создать заново» и посмотрите на ячейку максимальной скорости запястья |
| Заблуждение | Правильное объяснение | Что показать |
|---|---|---|
| При сжатии информация теряется, поэтому качество падает | Если выбрасывается в основном шум, становится даже лучше. Примеры — устранение дрожания и обучение на малых данных | Раздел 4, раздел 5 |
| Чем больше k, тем лучше | При большом k захватывается и дрожание. При малом теряются важные мелкие движения. Выбирайте по задаче | k = 32 в таблице раздела 2, k = 8 в разделе 5 |
| У каждого латентного числа есть понятный человеку смысл | Направления задают данные, и у них нет названий. Прозвища — это толкование, которое человек даёт потом | Таблица раздела 3 |
| Автокодировщик обязательно должен быть нейросетью | Простейший линейный автокодировщик делает то же, что PCA. Нейросеть передаёт и криволинейные связи | Разбор под разделом 2 |
| Любая точка латентного пространства даёт правдоподобное движение | Только рядом с тем местом, где были обучающие данные. Сделать это пространство равномерным — задача VAE | Раздел 3 за пределами ±2σ, раздел 6 |
1 196 ÷ 16 = 74.75, примерно в 74.8 раза. Объяснённая дисперсия в коде 1 — 99.80%.
Кодировщик: z = (x·v₁, x·v₂) = (3, −2). Декодер: 3v₁ − 2v₂ = (3, −2, 0). Третье значение 0.4 не попадает ни на одно из двух направлений и исчезает. Это и есть принцип, по которому «стирается дрожание».
Локоть согнут, поэтому находится снаружи от средней точки. Декодер использует выученную по 600 сценам связь «при такой позе локоть обычно здесь» (16 направлений) и подбирает локоть вместе с другими видимыми суставами. В коде 1 ошибка снизилась с 0.0230 до 0.0108.
Кодировщик выучил только структуру движения (что движется вместе) и превратил 1 288 чисел в сводку из 16. Сводка содержит мало шума и мало чисел, поэтому простой классификатор не путается, даже если размеченных сцен всего 150.
Потому что он вытягивает точки около среднего бросков в латентном пространстве, а декодер лишь линейно складывает направления. Быстрые замахи, слегка различающиеся по времени, не выражаются несколькими прямолинейными направлениями и размываются. Нужен нелинейный декодер или модель, учитывающая ось времени.
В коде 1 замените скрываемый сустав с правого локтя на левое колено (сустав № 9 → № 10) и увеличьте скрываемый отрезок с 21 до 40 кадров. Представьте в виде таблицы, как меняется ошибка заполнения декодером.
Создайте отсутствующее в обучении движение «падение» (сцена, где в функции pose параметр lean увеличен до 1.4) и измерьте, насколько его ошибка восстановления больше, чем у сцен шести видов. Предложите, можно ли по ошибке восстановления сделать сигнал тревоги о «невиданном движении», и укажите пороговое значение.
| Новичкам | Даже одних кнопок k в разделе 2 и трёх рисунков в разделе 4 достаточно, чтобы понять: «сжатие и развёртывание фильтруют» |
|---|---|
| Углублённо | Попросите заменить линейный кодировщик из кода 1 автокодировщиком на Keras (1,196 → 64 → 16 → 64 → 1,196) и сравнить ошибку восстановления и скорость запястья генератора E |
| Следующая часть | 5-4 От слов к движениям — превращаем и слова в точки на той же карте |
Вы дочитали часть «5-3 Кодировщик и декодер» до конца. Команда лаборатории подводит итоги — каждый по одной фразе.