3D-симуляции и обучение с подкреплением с MuJoCo и Gym
Делиться

Вступление
Гуманоидные роботы — это машины, напоминающие по форме и движениям человеческое тело, предназначенные для работы вместе с людьми и взаимодействия с нашими инструментами. Они всё ещё находятся на начальной стадии развития, но, согласно прогнозам, к 2050 году число гуманоидов достигнет миллиардов. В настоящее время наиболее продвинутыми прототипами являются NEO от 1XTech, Optimus от Tesla, Atlas от Boston Dynamics и G1 от китайской компании Unitree Robotics.
Робот может выполнить задачу двумя способами: ручное управление (когда вы специально программируете, что именно он должен делать) или искусственный интеллект (он учится делать, пробуя). В частности, обучение с подкреплением позволяет роботу осваивать оптимальные действия методом проб и ошибок для достижения цели, что позволяет ему адаптироваться к изменяющимся условиям, обучаясь на основе поощрений и штрафов без заранее заданного плана.
На практике обучение реального робота выполнению задачи обходится невероятно дорого. Поэтому современные подходы предполагают обучение в процессе симуляции , где генерация данных происходит быстро и недорого, а затем передача знаний реальному роботу (подход «sim-to-real» / «sim-first»). Это позволяет параллельно обучать несколько моделей в условиях симуляции.
Наиболее используемые на рынке 3D-симуляторы физики: PyBullet (начинающие) , Webots (средний), MuJoCo (для продвинутых) и Gazebo (для профессионалов). Вы можете использовать любой из них как отдельное программное обеспечение или через Gym — библиотеку OpenAI для разработки. Алгоритмы обучения с подкреплением, построенные на основе различных физических движков.
В этом уроке я покажу, как создать 3D-симуляцию гуманоидного робота с искусственным интеллектом . Я представлю несколько полезных фрагментов кода на Python, которые можно легко применить в других подобных случаях (просто скопируйте, вставьте и запустите), а также прокомментирую каждую строку кода, чтобы вы могли повторить этот пример (ссылка на полный код в конце статьи).
Настраивать
Среда — это моделируемое пространство, в котором агенты могут взаимодействовать и учиться выполнять задачу. Оно имеет определённое пространство наблюдения (информацию, которую получают агенты) и пространство действий (набор возможных действий).
Я буду использовать Gym (pip install gymnasium) для загрузки одной из сред по умолчанию, созданных с помощью MuJoCo (динамика Multi-Joint с Contact, pip install mujoco).
импортировать спортзал как спортзал env = gym.make(«Humanoid-v4″, render_mode=»human») obs, info = env.reset() env.render()

Агент — это трёхмерный двуногий робот, способный двигаться подобно человеку. Он имеет 12 звеньев (твёрдых частей тела) и 17 суставов (гибких частей тела). Полное описание можно найти здесь.
Перед началом новой симуляции необходимо сбросить настройки среды с помощью команды obs, info = env.reset(). Эта команда возвращает информацию о начальном состоянии агента. Эта информация обычно включает в себя дополнительную информацию о роботе.

В то время как наблюдения — это то, что видит агент (т. е. с помощью датчиков), модели ИИ необходимо будет обработать эти наблюдения, чтобы решить, какое действие предпринять.

Обычно все среды спортзалов имеют одинаковую структуру. Первое, что следует проверить, — это пространство действий , то есть набор всех возможных действий. В симуляции гуманоида действие представляет собой силу, приложенную к одному из его 17 суставов (в диапазоне от -0,4 до +0,4, что указывает направление толчка).
env.action_space

env.action_space.sample()

Симуляция должна охватывать как минимум один эпизод — полный цикл взаимодействия агента с окружающей средой, от начала до конца. Каждый эпизод представляет собой цикл reset() -> step() -> render(). Давайте рассмотрим пример запуска одного эпизода, где гуманоид выполняет случайные действия , то есть не использует искусственный интеллект.
import time env = gym.make(«Humanoid-v4″, render_mode=»human») obs, info = env.reset() reset = False #сбросить, если гуманоид падает или эпизод заканчивается episode = 1 total_reward, step = 0, 0 for _ in range(240): ## action step += 1 action = env.action_space.sample() #случайное действие obs, reward, terminated, truncated, info = env.step(action) ## reward total_reward += reward ## render env.render() #рендерить шаг физики (скорость ЦП = 0,1 секунды) time.sleep(1/240) #замедлить до реального времени (240 шагов × 1/240 секунды sleep = 1 секунда) if (step == 1) or (step % 100 == 0): #вывести первый шаг и каждые 100 шагов print(f»EPISODE {episode} — Шаг:{step}, Награда:{reward:.1f}, Итого:{total_reward:.1f}») ## сбросить, если сброс выполнен: если завершен или усечен: #вывести последний шаг print(f»EPISODE {episode} — Шаг:{step}, Награда:{reward:.1f}, Итого:{total_reward:.1f}») obs, info = env.reset() episode += 1 total_reward, step = 0, 0 print(«——————————————«) env.close()


По мере развития эпизода и движения робота мы получаем награду . В данном случае награда положительная, если агент остаётся на месте или движется вперёд, и отрицательная, если он падает и касается земли. Награда — важнейшая концепция для искусственного интеллекта, поскольку она определяет цель. Это сигнал обратной связи, который мы получаем от окружающей среды после каждого действия, указывающий, было ли это движение полезным или нет. Следовательно, её можно использовать для оптимизации принятия решений роботом посредством обучения с подкреплением.
Обучение с подкреплением
На каждом этапе симуляции агент оценивает текущую ситуацию (т.е. своё положение в среде), решает предпринять действие (т.е. перемещает один из своих суставов) и получает положительный или отрицательный ответ (вознаграждение, штраф). Этот цикл повторяется до завершения симуляции. Обучение с подкреплением (RL) — это тип машинного обучения, позволяющий агенту максимизировать вознаграждение путём проб и ошибок . Таким образом, в случае успеха робот будет знать наилучший вариант действий.
Математически обучение с подкреплением основано на марковском процессе принятия решений, в котором будущее зависит только от текущей ситуации, а не от прошлого . Проще говоря, агенту не нужна память о предыдущих шагах, чтобы решить, что делать дальше. Например, роботу достаточно знать только своё текущее положение и скорость, чтобы выбрать следующий ход, ему не нужно помнить, как он туда попал.
RL — это максимизация награды. Таким образом, всё искусство построения симуляции заключается в разработке функции награды, которая действительно отражает ваши желания (здесь цель — не упасть). Самый простой алгоритм RL обновляет список предпочтительных действий после получения положительной награды. Скорость, с которой это происходит, называется скоростью обучения : если это число слишком велико, агент будет перекорректировать, а если слишком мало, он будет повторять одни и те же ошибки и учиться мучительно медленно.
На обновления предпочтительных действий также влияет скорость исследования , которая представляет собой частоту случайного выбора. По сути, это уровень любопытства ИИ. Обычно он относительно высок в начале (когда агент ничего не знает) и снижается со временем, по мере того как робот использует свои знания.
import gymnasium as gym import time import numpy as np env = gym.make(«Humanoid-v4″, render_mode=»human») obs, info = env.reset() reset = True #сбросить, если гуманоид падает или эпизод заканчивается episode = 1 total_reward, step = 0, 0 explore_rate = 0.5 #запустить wild prefered_action = np.zeros(env.action_space.shape) #знания для обновления с опытом for _ in range(1000): ## шаг действия += 1 explore = np.random.normal(loc=0, scale=exploration_rate, size=env.action_space.shape) #добавить случайный шум action = np.clip(a=preferred_action+exploration, a_min=-1, a_max=1) obs, reward, terminated, truncated, info = env.step(action) ## награда total_reward += reward если награда > 0: prefered_action += (action-preferred_action)*0.05 #learning_rate explore_rate = max(0.05, explore_rate*0.99) #min_exploration=0.05, decay_exploration=0.99 ## render env.render() time.sleep(1/240) if (step == 1) or (step % 100 == 0): print(f»EPISODE {episode} — Step:{step}, Reward:{reward:.1f}, Total:{total_reward:.1f}») ## reset if reset: if terminated or truncated: print(f»EPISODE {episode} — Step:{step}, Reward:{reward:.1f}, Total:{total_reward:.1f}») obs, info = env.reset() episode += 1 total_reward, step = 0, 0 print(«——————————————«) env.close()


Очевидно, что это слишком примитивно для такой сложной среды, как Гуманоид, поэтому агент будет продолжать падать, даже если он обновит предпочтительные действия.
Глубокое обучение с подкреплением
Когда связь между действиями и вознаграждениями нелинейна, вам нужны нейронные сети. Глубокое обучение с подкреплением (RL) позволяет обрабатывать многомерные входные данные и оценивать ожидаемые будущие вознаграждения за действия, используя возможности глубоких нейронных сетей.
В Python самый простой способ использовать алгоритмы глубокого обучения с подкреплением — использовать StableBaseline, набор самых известных моделей, уже реализованных и готовых к использованию. Обратите внимание, что существуют StableBaseline (написанный на TensorFlow) и StableBaselines3 (написанный на PyTorch). В настоящее время все используют последний.
pip install torch pip install stable-baselines3
Один из наиболее распространённых алгоритмов глубокого обучения с подкреплением (Deep RL) — PPO (Proximal Policy Optimization), поскольку он прост и стабилен. Цель PPO — максимизировать общую ожидаемую награду, внося небольшие изменения в эту политику и поддерживая стабильный рост.
Я буду использовать StableBaseline для тренировки PPO в среде Gym Humanoid . Стоит учитывать несколько моментов:
- нам не нужно графически отображать окружение, поэтому обучение может происходить с ускоренной скоростью.
- Оболочку Gym env необходимо поместить в DummyVecEnv, чтобы сделать ее совместимой с векторизованным форматом StableBaseline.
- Что касается модели нейронной сети, PPO использует многослойный персептрон (MlpPolicy) для числовых входных данных, сверточную нейронную сеть (CnnPolicy) для изображений и комбинированную модель (MultiInputPolicy) для наблюдений смешанных типов.
- Поскольку я не рендерю гуманоида, мне очень полезно отслеживать ход обучения в TensorBoard, наборе инструментов для визуализации статистики в реальном времени (pip install tensorboard). Я создал папку «logs» и могу просто запустить tensorboard —logdir=logs/ в терминале, чтобы открыть панель управления локально (http://localhost:6006/).
from stable_baselines3 import PPO from stable_baselines3.common.vec_env import DummyVecEnv ## environment env = gym.make(«Humanoid-v4») #без рендеринга для ускорения env = DummyVecEnv([lambda:env]) ## train print(«Training START») model = PPO(policy=»MlpPolicy», env=env, verbose=0, learning_rate=0.005, ent_coef=0.005, #exploration tensorboard_log=»logs/») #>tensorboard —logdir=logs/ model.learn(total_timesteps=3_000_000, #1h tb_log_name=»model_humanoid», log_interval=10) print(«Training DONE») ## save model.save(«model_humanoid»)

После завершения обучения мы можем загрузить новую модель и протестировать её в визуализированной среде. Теперь агент больше не будет обновлять предпочтительные действия. Вместо этого он будет использовать обученную модель для прогнозирования следующего оптимального действия с учётом текущего состояния.
env = gym.make(«Humanoid-v4″, render_mode=»human») model = PPO.load(path=»model_humanoid», env=env) obs, info = env.reset() reset = False #сбросить, если гуманоид падает или эпизод заканчивается episode = 1 total_reward, step = 0, 0 for _ in range(1000): ## действие step += 1 action, _ = model.predict(obs) obs, reward, terminated, truncated, info = env.step(action) ## награда total_reward += reward ## рендер env.render() time.sleep(1/240) if (step == 1) or (step % 100 == 0): #вывести первый шаг и каждые 100 шагов print(f»EPISODE {episode} — Step:{step}, Reward:{reward:.1f}, Total:{total_reward:.1f}») ## сбросить, если сбросить: если завершено или усечено: #вывести последний шаг print(f»EPISODE {episode} — Step:{step}, Reward:{reward:.1f}, Total:{total_reward:.1f}») obs, info = env.reset() episode += 1 total_reward, step = 0, 0 print(«——————————————«) env.close()

Обратите внимание, что в этом руководстве мы ни разу не программировали робота специально на то, чтобы он оставался в вертикальном положении. Мы не управляем агентом. Робот просто реагирует на функцию вознаграждения окружающей среды. Более того, если вы будете тренировать модель с подкреплением гораздо дольше (например, 30 миллионов временных шагов), вы увидите, что робот не только идеально стоит, но и идёт вперёд. Таким образом, при обучении агента с использованием ИИ проектирование трёхмерного мира и его правил важнее, чем создание самого робота.
Заключение
Эта статья представляет собой руководство по знакомству с MuJoCo и Gym, а также по созданию 3D-симуляций для робототехники . Мы использовали гуманоидную среду для изучения основ обучения с подкреплением. Мы обучили глубокую нейронную сеть, чтобы робот не падал. В ближайшее время появятся новые руководства с более продвинутыми роботами.
Полный код для этой статьи: GitHub
Надеюсь, вам понравилось! Обращайтесь ко мне с вопросами и отзывами, а также просто делитесь своими интересными проектами.
👉 Давайте общаться 👈

(Все изображения принадлежат автору, если не указано иное)
Источник: towardsdatascience.com



























