Назад
78

Восстанавливаем скрытые переменные для моделирования сложных динамических систем

78

Представьте, что вы пытаетесь предсказать поведение сложной системы, такой как погода, финансовый рынок или робот. В идеальном мире у вас был бы доступ ко всей необходимой информации (ко всем скрытым состояниям/переменным) для точного моделирования системы. Однако на практике у нас зачастую нет доступа к полному состоянию (sate), а есть только к частичным наблюдениям (partial observations). Последние могут быть подмножеством состояний или некоторой нелинейной функцией состояний. Это представляет собой проблему для алгоритмов машинного обучения, которые зависят от состояний.

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

Конкретно в робототехнике динамические модели нужны, например, для обучения с подкреплением на основе модели (model-based reinforcement learning (RL)), которая эффективнее в использовании выборки (sample efficient) по сравнению с model-free RL [1]. В model-free RL стратегия (policy) или функция ценности (value function) в неявной форме содержат динамическую модель робота [2].

Постановка задачи

Рис. 1. Пример сложной динамической системы

Предположим, что перед нами стоит задача обучения модели для предсказания поведения робота (как показано на рисунке 1). Скрытое состояние робота \( x_k \) — вектор положений и скоростей шарниров робота. Однако пусть нам доступными данными будут положения некоторых ключевых точек \( y \), измеренных на камеру во время движения робота. По сути нам необходимо аппроксимировать исходную динамику робота \( F \) некоторой функцией \( \hat F \). Но поскольку мы имеем дело с частичными наблюдениями, задача моделирования изрядно усложняется.

Рассмотрим проблему поподробнее и начнем с определения истинной нелинейной дискретной динамики. Она может быть описана следующим разностным уравнением:

\( x_{k+1} = F\big(x_k, u_k, \theta_{r}\big) \)

где \( x_k=x(t_k) \) — вектор состояний системы в момент времени; \( t_k \), \( u_k \) — вектор внешних входов, а \( \theta_r \) — вектор истинных параметров системы. Пусть \( y_k \) будет вектором зашумленных наблюдений системы:

\( y_k = H\big(x_k\big) + \nu_k \)

где \( H(x_k) \) — функция, которая отображает состояния \( x_k \) в наблюдения, а \( \nu_k \) — шум.

На основе этих зашумленных наблюдений мы хотим обучить модель вида \( \hat z_{k+1} = \hat F(\hat z_k, u_k, \theta_a) \), которая смогла бы максимально точно аппроксимировать исходную динамику, где \( \hat F \) — приближение исходного отображения \( F \), а \( \theta_a \) — параметры приближенного отображения. Если мы знаем размерность вектора исходных состояний \( x \) — мы можем выбрать такую же размерность для \( z \). Если мы не знаем размерность вектора или хотим найти более низкоразмерное приближение отображения \( F \) — мы можем выбрать произвольную размерность \( z \). На практике мы хотим наименьшую размерность, при которой модель смогла бы точно предсказывать наблюдения \( y \) для быстрого инференса и, в случае робота, для быстрого управления движением. А еще нам надо аппроксимировать функцию отображений скрытых состояний в наблюдения \( H \) некоторой функцией \( \hat H \).

Для простоты давайте воспользуемся рекуррентными нейронными сетями (RNN) с целью аппроксимации динамики. На рисунке 2 схематически показан принцип работы «ванильной» RNN, где каждый ромб представляет RNN-блок. Тезисно: RNN принимает на вход \( u_k \) и состояние \( \hat z_k \) и выдает следующее состояние \( \hat z_{k+1} \). Говоря математическим языком, динамика RNN распространяется таким образом:

\( \hat z_{k+1} = \tanh(W_{\hat z} \hat z_k + W_u u_k + b) \)

Рис. 2. Принцип работы RNN

Итак, нас интересует обучение моделей, которые могут точно предсказывать поведение сложной динамической системы по частичным наблюдениям. Если говорить точнее, наша модель должна безошибочно предсказывать последующие \(N\) состояний системы, \( \hat z_{k+1} \) , \( \hat z_{k+2} \), \( \dots \), \( \hat z_{k+N+1} \) на основе частичных наблюдений и последовательности внешних входов \( U \). В сущности, решение проблемы сводится к поиску начального состояния \( \hat z_k \), которое будет использоваться RNN для распространения динамики и функции. Функция отобразит скрытые состояния в наблюдения. А теперь давайте рассмотрим несколько методов, которые так или иначе использовались для решения этой проблемы.

Автоэнкодеры

Один из распространенных подходов в машинном обучении для решения таких задач — автоэнкодеры. Здесь наш входной вектор признаков \( h_k \) для энкодера — последовательность пар наблюдений и внешних входов. Для простоты давайте выберем \( h_k = \left(y_k; u_k\right) \). Энкодер — многослойный перцептрон (MLP), который берет векторы \( h_k, h_{k+1}, \dots, h_{k+N+1} \) и возвращает скрытые состояния \( z_k, z_{k+1},\dots, z_{k+N+1} \) (как показано на рисунке 3). Начиная с первого скрытого состояния \( z_k \) и используя последовательность внешних входов \( U = [u_k\ u_{k+1} \dots u_{k+N}] \), RNN распространяет динамику и возвращает последовательность состояний \( \hat{z}_{k+1},\ \hat{z}_{k+2},\ \dots,\ \hat{z}_{k+N} \). Декодер — еще один MLP, который аппроксимирует \( H \), то есть берет состояния \( z_k, \dots, z{k+N+1} \), предсказанные энкодером, и состояния, предсказанные RNN \( \hat z_{k+1}, \dots, \hat z_{k+N+1} \), и отображает их в последовательность пар наблюдение-внешний-вход \( \bar h_k = (y_k, u_k) \), \( \bar h_{k+1} = (\bar{y}{k+1}, u{k+1}), \dots , \bar h_{k+N+1} = (\bar{y}{k+N+1}, u{k+N+1}) \) и \( \hat h_{k+1} = (\hat{y}{k+1}, u{k+1}), \dots , \hat h_{k+N+1} = (\hat{y}{k+N+1}, u{k+N+1}) \) соответственно. Для визуальной привлекательности \( \hat h \) на рисунке 3 не показаны.

Рис. 3. Использование автоэнкодера для восстановления скрытых состояний системы

Функция потерь для всего процесса обучения энкодера, RNN и декодера является комбинацией нескольких функций потерь:

  • функция потерь для пары энкодер-декодер оценивает, насколько хорошо декодер может восстановить \( h_k \), используя скрытое закодированное энкодером состояние \( z_k \)

\( \mathcal{L}_1= \sum_{j=0}^{N+1} ||h_{k+j} — \psi(\phi(h_{k+j})) ||_2^2 \)

  • функция потерь закодированного скрытого состояния измеряет, соответствует ли закодированные скрытые состояния динамике системы

\( \mathcal{L}_2 = \sum_{j=1}^{N+1} ||z_{k+j} — \hat z_{k+j}||_2^2 \)

  • функция потерь предсказания выходных данных измеряет, насколько хорошо динамика приближает истинную динамику и предсказывает наблюдения

\( \mathcal{L}_3 = \sum_{j=1}^N||h_{k+j} — \psi(\hat z_{k+j})|| \)

Общая функция потерь является взвешенной суммой отдельных функций потерь: \( \mathcal{L} = \alpha \mathcal{L}_1 + \beta \mathcal{L}_2 + \gamma \mathcal{L}_3 \). Если вы хотите узнать больше о применении автоэнкодеров для обучения скрытых динамических моделей, то я рекомендую прочитать статью [Discovering Governing Equations from Partial Measurements with Deep Delay Autoencoders]. Она достаточно простая и иллюстративная.

RNN-энкодеры

Еще один подход в машинном обучении — использование RNN в качестве энкодера скрытых состояний. В этом методе мы берем последовательность пар наблюдений и внешних входов \( (y_{k}, u_{k}),\ (y_{k+1}, u_{k+1}),\ \dots, \ (y_{k+M}, u_{k+M}) \) и подаем их на вход RNN в обратном порядке, где конечное состояние RNN — искомое скрытое состояние \( z_k \). Частичные наблюдения бывают зашумлены неидеальными сенсорами, которыми они измеряются. Поэтому мы можем оценивать не детерминированное скрытое начальное состояние, а его распределение, например, нормальное распределение. В такой вероятностной постановке задачи конечное состояние RNN-энкодера представляет собой среднее значение и ковариацию [3] распределения скрытого начального состояния \( z_k \sim \mathcal{N}(\mu_k, \Sigma_k) \). Обычно состояние энкодера RNN \( z_{k+M} \) инициализируется нулевым вектором.

Рис. 4. Использование RNN в качестве энкодера начального скрытого состояния

Если вы знакомы с моделированием последовательностей, то, возможно, узнаете архитектуру RNN-энкодера из области машинного перевода. В таком случае RNN-энкодер предоставляет «контекст» для RNN-декодера, который генерирует перевод на основе этого “контекста”.

Эта схема работает благодаря понятию устойчивости динамических систем. Они «забывают» свое начальное состояние (некоторый рандомный вектор или вектор нулей) и сходятся к стационарной точке. То есть несмотря на то что мы инициализируем состояние RNN-энкодера нулевым или другим вектором, он сойдется к стационарной точке, которой является наше начальное состояние \( z_k \). Обычно теоретики умалчивают о том, через сколько итераций RNN-энкодер сойдется к стационарной точке. Поэтому на практике хорошей идеей станет выбор относительно большой входной последовательности \( M \). Она даст достаточного времени RNN-энкодеру сойтись правильному значению \( z_k \), которое затем распространяется RNN (как показано на рисунке 4). RNN-энкодеры широко использовались для обучения динамических моделей с применением нейронных обыкновенных дифференциальных уравнений, например [Neural Ordinary Differential Equations] и [Latent ODEs for Irregularly-Sampled Time Series].

Делаем начальное скрытое состояние оптимизационной переменной

Специалисты в области идентификации систем (занимаются проблемой моделирования сложных систем, любят доказательства, теоремы и гарантии) разработали собственные инструменты для обучения скрытой динамике. Одним из самых простых методов является использование начального состояния в качестве обучаемой переменной. Это позволяет избавиться от необходимости применения энкодера. Такой подход, показанный на рисунке 5, часто используется для идентификации систем методом «серого ящика», где известна структура системы \( F(x_k, u_k, \theta_r) \) и отображение состояний в наблюдения \( H(x_k) \), но неизвестны параметры \( \theta_r \). Но этот метод может быть использован и для более общих моделей, таких как RNN. Однако сделать начальное состояние переменной оптимизации —это значит увеличить количество оптимизационных переменных, особенно при использовании mini-batch оптимизации. Поэтому имеет смысл обучаться начальному состоянию только при моделировании очень длинных последовательностей и использовании batch оптимизации. Такой метод применялся в различных работах, включая работу моего коллеги из MECO Андраша (Toolbox for identification of nonlinear state-space grey-box models).

Рис. 5. Делаем начальное состояние оптимизационной переменной для избавления от энкодера

KKL-энкодер

Большинство методов для управления роботами, самолетами или химическими заводами основывается на скрытом состоянии. Инженеры по управлению разработали алгоритмы (наблюдатели состояний) для оценки скрытых состояний по частичным наблюдениям. Наблюдатели состояний — динамические системы. Их можно интерпретировать как виртуальные динамические сенсоры. Самыми известными среди них являются фильтр Калмана и его вариации, такие как Extended Kalman Filter и Unscented Kalman Filter . Однако большинство алгоритмов оценки (предсказания) состояний сильно зависит от скрытой динамической модели системы. Если динамическая модель системы задана уравнением \( \hat z_{k+1} = \hat F\big(\hat z_k, u_k, \theta_{r}\big) \), а наблюдения — \( \hat y_k = \hat H\big(\hat z_k\big) + \nu_k \), то динамическая модель наблюдателя выстраивается следующим образом:

\( \tilde z_{k+1} = \hat F(\tilde z_k, u_k, \theta_a) + K(y_k — \hat H(\tilde z_k)) \)

где \( \tilde z_k \) — оценка скрытого состояния \( z_k \), а \( K \)— матрица коэффициентов усиления ошибки предсказания. Если говорить простым языком: мы берем обученную динамическую модель системы и добавляем к ней корректирующий член, пропорциональный разнице между нашим предсказанием наблюдений и реальными наблюдениями. Однако в нашей ситуации (когда скрытая динамическая модель неизвестна) использование классических наблюдателей состояния (как фильтры Калмана) приведет к проблеме курицы и яйца: нам нужно оценить скрытое состояние из частичных наблюдений, чтобы обучить модель динамической системы, но нам нужна скрытая динамическая модель, чтобы оценить скрытое состояние.

Среди немногих алгоритмов оценки состояния, которые несильно зависят от точной динамической модели, можно выделить наблюдатель Казанциса-Кравариса-Люнбергера (KKL). В отличие от классических наблюдателей, копирующих известную скрытую модель и добавляющих дополнительный член, наблюдатель KKL отделяет скрытую динамику \( z_{k+1} = \hat F(z_k, u_k, \theta_a) \) от динамики наблюдателя и предполагает линейную динамику для наблюдателя. Состояние наблюдателя KKL (обозначено как \( \xi \)) распространяется в соответствии со следующим уравнением:

\( \xi_{k+1} = D \xi_k + G \begin{bmatrix}y_k \\ u_k\end{bmatrix} \)

где \( D \) — стабильная матрица состояний с собственными значениями \( -1 < \lambda_i < 1 \). Требование устойчивости к динамической модели наблюдателя (сходимость и независимость от начального скрытого состояния) гарантирует, что независимо от инициализации \( \xi \) после достаточно длительного времени наблюдатель сойдется и «забудет» свое начальное состояние. KKL-наблюдатель может отделить динамику наблюдателя от скрытой динамики самой системы: есть гладкое обратимое отображение \( \mathcal{T} \) от нашего скрытого состояния \( z \) к состоянию наблюдателя \( \xi \) и обратно [4]. К сожалению, не существует готового рецепта для нахождения такого отображения. На практике мы можем рассматривать отображение \( \mathcal{T} \) и его обратное \( \mathcal{T}^* \) как автоэнкодер, который будем обучать вместе с динамической моделью.

По сравнению с простым автоэнкодером, в KKL-энкодере мы используем состояние KKL наблюдателя \( \xi \) вместо последовательности пар наблюдений \( y \) и внешних входных данных \( u \) (как показано на рисунке 6). Если вы хотите узнать больше о методе KKL-энкодера, вы можете посмотреть вот эту статью [Recognition Models to Learn Dynamics from Partial Observations with Neural ODEs].

Рис. 6. Использование KKL в качестве энкодера начального скрытого состояния

Вывод

В реальной жизни нам часто приходится обучать модели для предсказания поведения сложных динамических систем на основе частичных наблюдений. Для обучения модели в скрытых переменных нам необходимо так или иначе оценить/восстановить начальное скрытое состояние, а затем, используя выбранную архитектуру и последовательность (внешних) входов, распространить его. Есть различные методы для оценки начального скрытого состояния. Пожалуй, самый простой из них — сделать начальное состояние оптимизационной переменной. У этого метода есть один большой недостаток: в зависимости от типа обучения (batch vs mini-batch) и длительности распространения динамики количество оптимизационных переменных может сильно вырасти. Самый распространенный метод — автоэнкодер, где энкодер принимает на вход последовательность частичных наблюдений и внешних входов и возвращает скрытое состояние. Декодер, в свою очередь, принимает на вход скрытое состояние и пытается восстановить вход энкодера. И еще есть такие методы, как RNN- и KKL-энкодеры. Они динамические — принимают на вход последовательность частичных наблюдений и внешних входов, распространяют динамику обратно во времени для поиска начального скрытого состояния.

В [Recognition Models to Learn Dynamics from Partial Observations with Neural ODEs] показывается, что разница между подходами несильно велика для моделирования скрытой динамики экзоскелета. Поэтому на практике я бы сначала реализовал автоэнкодер. А при неудовлетворительном качестве модели уже перешел бы на динамические энкодеры.

Ссылки

[1] https://habr.com/ru/companies/hsespb/articles/672938/

[2] https://towardsdatascience.com/the-ultimate-beginners-guide-to-reinforcement-learning-588c071af1ec

[3] https://ru.wikipedia.org/wiki/Ковариация

[4] https://arxiv.org/abs/2103.12443

Телеграм-канал

DeepSchool

Короткие посты по теории ML/DL, полезные
библиотеки и фреймворки, вопросы с собеседований
и советы, которые помогут в работе

Открыть Телеграм

Увидели ошибку?

Напишите нам в Telegram!