Галлюциногенное глубокое обучение с подкреплением с использованием Python и Keras

Обучение машины навыкам автогонок и избеганию огненных шаров с помощью «Мировых моделей».

Если вам нравится искусственный интеллект, вам нужно это проверить:



https://arxiv.org/abs/1803.10122

Короче говоря, это шедевр по трем причинам:

  1. Он сочетает в себе несколько методов глубокого обучения / обучения с подкреплением для получения потрясающего результата - первого известного агента, решающего популярную среду обучения с подкреплением «Гонки на автомобилях».
  2. Он написан в очень доступном стиле и является отличным учебным ресурсом для всех, кто интересуется передовыми технологиями искусственного интеллекта.
  3. Вы можете сами запрограммировать решение

Этот пост представляет собой пошаговое руководство по бумаге.

Мы расскажем о технических деталях, а также расскажем, как запустить версию на собственном компьютере.

Как и в случае с моим сообщением на AlphaZero, я не связан с авторами статьи, а просто хотел поделиться своей интерпретацией их потрясающей работы.

Шаг 1. Проблема

Мы собираемся создать алгоритм обучения с подкреплением (агент), который научится водить машину по двухмерной гоночной трассе. Эта среда (Автомобильные гонки) доступна через OpenAI Gym.

На каждом временном шаге в алгоритм подается наблюдение (цветное изображение автомобиля и ближайшего окружения размером 64 x 64 пикселя), и ему необходимо возвращать следующий набор действий, которые необходимо предпринять, в частности, направление рулевого управления (от -1 до 1). , ускорение (от 0 до 1) и тормоз (от 0 до 1).

Затем это действие передается в среду, которая возвращает следующее наблюдение, и цикл начинается снова.

Агент получает оценку 1000 / N за каждый из N посещенных фрагментов дорожки и -0,1 за каждый сделанный временной шаг. Например, если агент завершит трек за 732 кадра, награда составит 1000–0,1 * 732 = 926,8 балла.

Вот пример агента, который выбирает действие [0,1 0] для первых 200 временных шагов, а затем что-то случайное… не самая лучшая стратегия вождения.

Цель состоит в том, чтобы научить агента понимать, что он может использовать информацию из своего окружения для информирования о следующем лучшем действии.

Шаг 2: решение

В Интернете есть отличное интерактивное объяснение методологии, написанное авторами, поэтому я не буду вдаваться в детали того же уровня здесь, а сосредоточусь на высокоуровневом резюме того, как части сочетаются друг с другом, с аналогия с реальным вождением, чтобы объяснить, почему решение интуитивно понятно.

Решение состоит из трех отдельных частей, которые обучаются отдельно:

Вариационный автоэнкодер (VAE)

Когда вы принимаете решения во время вождения, вы не анализируете активно каждый «пиксель» в поле зрения - вместо этого ваш мозг концентрирует визуальную информацию в меньшее количество «скрытых» сущностей, таких как прямолинейность дороги, предстоящие повороты и т. Д. ваше положение относительно дороги, чтобы сообщить о вашем следующем действии.

Это именно то, чему обучается VAE - конденсировать входное изображение размером 64x64x3 (RGB) в 32-мерный скрытый вектор (z), который следует гауссовскому распределению.

Это полезно, потому что агент теперь может работать с гораздо меньшим представлением своего окружения и, следовательно, может более эффективно обучаться.

Рекуррентная нейронная сеть с выходным слоем Mixture Density Network (MDN-RNN)

Если бы у вас не было компонента MDN-RNN для принятия решений, ваше вождение могло бы выглядеть примерно так.

Во время вождения каждое последующее наблюдение не будет для вас полной неожиданностью. Вы знаете, что если текущее наблюдение предполагает левый поворот дороги и вы поворачиваете колесо влево, вы ожидаете, что следующее наблюдение покажет, что вы все еще находитесь на одной линии с дорогой.

Это дальновидное мышление - задача RNN - в частности, это сеть с долгосрочной краткосрочной памятью (LSTM) с 256 скрытыми блоками. Вектор скрытых состояний представлен буквой h.

Подобно VAE, RNN пытается зафиксировать скрытое понимание текущего состояния автомобиля в его среде, но на этот раз с целью предсказать, как может выглядеть следующий z, на основе предыдущего z и предыдущее действие.

Выходной слой MDN просто учитывает тот факт, что следующий «z» может быть фактически взят из любого из нескольких гауссовых распределений.

Тот же метод был применен в этой статье тем же автором для генерации почерка, чтобы описать тот факт, что следующая точка пера может попасть в любую из выделенных красным цветом областей.

Точно так же в статье World Models следующее наблюдаемое скрытое состояние может быть получено из любого из пяти гауссовых распределений.

Контроллер

До этого момента мы ничего не упоминали о выборе действия. Эта ответственность лежит на Контролере.

Контроллер - это просто плотно связанная нейронная сеть, где вход представляет собой конкатенацию z (текущее скрытое состояние из VAE - длина 32) и h (скрытое состояние RNN - длина 256). . Три выходных нейрона соответствуют трем действиям и масштабируются, чтобы попасть в соответствующие диапазоны.

Диалог

Чтобы понять различные роли трех компонентов и то, как они работают вместе, мы можем представить диалог между ними:

VAE: (смотрит на последнее наблюдение 64 * 64 * 3) Это похоже на прямую дорогу с небольшим приближающимся поворотом влево, когда автомобиль смотрит в сторону дороги (z).

RNN: на основании этого описания (z) и того факта, что Контроллер выбрал резкое ускорение на последнем временном шаге (действии), я обновлю свое скрытое состояние (h), чтобы следующее наблюдение все еще было прямым. дорога, но с чуть большим левым поворотом в поле зрения.

Контроллер: на основе описания из VAE (z) и текущего скрытого состояния из RNN (h) моя нейронная сеть выводит следующее действие как [0,34, 0,8, 0].

Затем это действие передается в среду, которая возвращает обновленное наблюдение, и цикл начинается снова.

Теперь мы рассмотрим, как настроить среду, которая позволит вам обучать вашу собственную версию агента для автомобильных гонок.

Время для кода!

Шаг 3. Настройте среду

Если у вас ноутбук с высокими техническими характеристиками, вы можете запустить решение локально, но я бы рекомендовал использовать Google Cloud Compute для доступа к мощным машинам, которые можно использовать короткими сериями.

Следующее было протестировано в Linux (Ubuntu 16.04) - просто измените соответствующие команды для установки пакета, если вы работаете на Mac или Windows.

  1. Клонировать репозиторий

В командной строке перейдите к месту, где вы хотите сохранить репозиторий, и введите следующее:

git clone https://github.com/AppliedDataSciencePartners/WorldModels.git

Репозиторий адаптирован из очень полезной библиотеки estool, разработанной Дэвидом Ха, первым автором статьи о моделях мира.

Для обучения нейронной сети эта реализация использует Keras с бэкэндом Tensorflow, хотя в исходной статье авторы использовали необработанный Tensorflow.

2. Настройте виртуальную среду

Создайте себе виртуальную среду Python 3 (я использую virutalenv и virtualenvwrapper)

sudo apt-get install python-pip
sudo pip install virtualenv
sudo pip install virtualenvwrapper
export WORKON_HOME=~/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh
mkvirtualenv --python=/usr/bin/python3 worldmodels

2. Установить пакеты

sudo apt-get install cmake swig python3-dev zlib1g-dev python-opengl mpich xvfb xserver-xephyr vnc4server

3. Установите файл requirements.txt

cd WorldModels
pip install -r requirements.txt

Здесь их больше, чем требуется в примере с автогонками, но у вас будет все установлено на тот случай, если вы захотите протестировать некоторые другие среды в тренажерном зале Open AI, для которых требуются дополнительные пакеты.

Шаг 4. Создайте случайное внедрение

В среде автомобильных гонок и VAE, и RNN могут быть в случайных данных развертывания, то есть данных наблюдений, сгенерированных путем случайного выполнения действий на каждом временном шаге. Фактически, мы используем псевдослучайные действия, которые заставляют машину изначально разогнаться, чтобы сойти с линии старта.

Поскольку VAE и RNN не зависят от контроллера, принимающего решения, все, что нам нужно, это убедиться, что мы сталкиваемся с разнообразным диапазоном наблюдений и выбираем разнообразный диапазон действий для сохранения в качестве обучающих данных.

Чтобы сгенерировать случайные развертывания, запустите в командной строке следующее:

python 01_generate_data.py car_racing --total_episodes 2000 --start_batch 0 --time_steps 300

или если вы работаете на сервере без дисплея,

xvfb-run -a -s "-screen 0 1400x900x24" python 01_generate_data.py car_racing --total_episodes 2000 --start_batch 0 --time_steps 300

Это произведет 2000 развертываний (сохраненных в десяти пакетах по 200), начиная с пакета номер 0. Каждое развертывание будет иметь максимум 300 временных шагов.

Два набора файлов сохраняются в ./data, (* - номер пакета)

obs_data_*.npy (хранит изображения размером 64 * 64 * 3 в виде массивов numpy)

action_data_*.npy (хранит трехмерные действия)

Шаг 5: Тренируйте VAE

Для обучения VAE требуются только obs_data_*.npy файлы. Убедитесь, что вы выполнили шаг 4, и эти файлы находятся в папке ./data.

В командной строке запустите:

python 02_train_vae.py --start_batch 0 --max_batch 9 --new_model

Это обучит новый VAE каждому пакету данных от 0 до 9.

Вес модели будет сохранен в ./vae/weights.h5. Флаг --new_model указывает скрипту обучать модель с нуля.

Если в этой папке есть существующий weights.h5 и флаг --new_model не указан, сценарий загрузит веса из этого файла и продолжит обучение существующей модели. Таким образом, вы можете итеративно тренировать VAE группами, а не все за один раз.

Спецификация архитектуры VAE в файле ./vae/arch.py.

Шаг 6. Сгенерируйте данные RNN

Теперь, когда у нас есть обученный VAE, мы можем использовать его для создания обучающего набора для RNN.

RNN требует закодированных данных изображения (z) от VAE и действий (a) в качестве ввода и данных изображения, закодированных на один шаг вперед, от VAE в качестве вывода.

Вы можете сгенерировать эти данные, запустив:

python 03_generate_rnn_data.py --start_batch 0 --max_batch 9

При этом файлы obs_data_*.npy и action_data_*.npy из пакетов от 0 до 9 будут преобразованы в правильный формат, необходимый RNN для обучения.

Два набора файлов будут сохранены в ./data, (* - номер пакета)

rnn_input_*.npy (хранит [z a] конкатенированные векторы)

rnn_output_*.npy (сохраняет вектор z на один временной шаг вперед)

Шаг 7: Обучите RNN

Для обучения RNN требуются только файлы rnn_input_*.npy и rnn_output_*.npy . Убедитесь, что вы выполнили шаг 6, и эти файлы находятся в папке ./data.

В командной строке запустите:

python 04_train_rnn.py --start_batch 0 --max_batch 9 --new_model

Это обучит новую RNN каждому пакету данных от 0 до 9.

Вес модели будет сохранен в ./rnn/weights.h5. Флаг --new_model указывает скрипту обучать модель с нуля.

Аналогично VAE, если в этой папке есть существующий weights.h5 и не указан флаг --new_model, сценарий загрузит веса из этого файла и продолжит обучение существующей модели. Таким образом, вы можете итеративно обучать свою RNN партиями, а не все за один раз.

Спецификация архитектуры RNN находится в файле ./rnn/arch.py.

Шаг 8: Обучите Контроллера

А теперь самое интересное!

До сих пор мы просто использовали глубокое обучение для создания VAE, который может конденсировать изображения большой размерности до низкоразмерного скрытого пространства и RNN, которая может предсказать, как скрытое пространство будет развиваться с течением времени. Это стало возможным, потому что мы смогли создать обучающий набор для каждого, используя случайные данные развертывания.

Для обучения контроллера мы будем использовать форму обучения с подкреплением, в которой используется эволюционный алгоритм, известный под названием CMA-ES (адаптация ковариационной матрицы - стратегия эволюции).

Поскольку входные данные - это вектор размерности 288 (= 32 + 256), а выход - вектор размерности 3, у нас есть 288 * 3 + 1 (смещение) = 867 параметров для обучения.

CMA-ES работает, сначала создавая несколько случайно инициализированных копий 867 параметров («совокупность»). Затем он проверяет каждого члена популяции внутри среды и записывает его средний балл. Точно так же, как и при естественном отборе, весам, которые приносят наивысшие баллы, разрешается «воспроизводиться» и порождать следующее поколение.

Чтобы запустить этот процесс на вашем компьютере, выполните следующую команду с соответствующими значениями аргументов

python 05_train_controller.py car_racing --num_worker 16 --num_worker_trial 2 --num_episode 4 --max_length 1000 --eval_steps 25

или на сервере без дисплея:

xvfb-run -s "-screen 0 1400x900x24" python 05_train_controller.py car_racing --num_worker 16 --num_worker_trial 2 --num_episode 4 --max_length 1000 --eval_steps 25

--num_worker 16: установите не более числа доступных ядер

--num_work_trial 2: количество членов популяции, которое будет тестировать каждый рабочий (num_worker * num_work_trial дает общий размер популяции для каждого поколения)

--num_episode 4: количество эпизодов, по которым будет оцениваться каждый член населения (т. Е. Оценка будет средней наградой за это количество эпизодов)

--max_length 1000: максимальное количество временных шагов в эпизоде

--eval_steps 25: количество поколений между оценками наилучшего набора весов в 100 эпизодах

--init_opt ./controller/car_racing.cma.4.32.es.pk По умолчанию контроллер запускается с нуля каждый раз при запуске и сохраняет текущее состояние процесса в файл pickle в каталоге controller. Этот аргумент позволяет продолжить обучение с последней точки сохранения, указав ее на соответствующий файл.

После каждого поколения текущее состояние алгоритма и лучший набор весов будут выводиться в папку ./controller.

Шаг 9: Визуализируйте агента

На момент написания статьи мне удалось обучить агента получить средний балл ~ 833,13 после 200 поколений обучения. Это было обучено в Google Cloud с использованием Ubuntu 16.04, 18 vCPU, 67,5 ГБ RAM с шагами и параметрами, приведенными в этом руководстве.

Авторам статьи удалось получить средний балл ~ 906 после 2000 поколений обучения, что считается наивысшим баллом в этой среде на сегодняшний день. При этом использовалась немного более высокая спецификация (например, 10000 эпизодов обучающих данных, 64 размера популяции, 64-ядерная машина, 16 эпизодов на испытание и т. Д.)

Чтобы визуализировать текущее состояние вашего контроллера, просто запустите:

python model.py car_racing --filename ./controller/car_racing.cma.4.32.best.json --render_mode --record_video

--filename: путь к json весов, которые вы хотите прикрепить к контроллеру

--render_mode: визуализировать окружающую среду на вашем экране

--record_video: выводит файлы mp4 в папку ./video, показывая каждый эпизод.

--final_mode: запустите 100-серийный тест вашего контроллера и выведите средний балл.

Вот демо!

Шаг 10: галлюциногенное обучение

Это уже довольно круто, но следующая часть статьи невероятно впечатляет и, как мне кажется, имеет большое значение для ИИ.

Далее документ показывает удивительный результат в другой среде, DoomTakeCover. Цель здесь - переместить агента, чтобы избежать огненных шаров и остаться в живых как можно дольше.

Авторы показывают, как агент может на самом деле научиться играть в игру в своих собственных галлюциногенных снах, вдохновленных VAE / RNN, а не внутри самой среды.

Единственное необходимое дополнение - это то, что RNN обучена также предсказывать вероятность быть убитой на следующем временном шаге. Таким образом, комбинацию VAE / RNN можно обернуть как отдельную среду и использовать для обучения Контроллера. В этом суть концепции «модели мира».

Мы могли бы резюмировать изучение галлюциногенов следующим образом:

Исходные данные для обучения агента - это не что иное, как случайные взаимодействия с реальной средой. Благодаря этому он создает скрытое понимание того, как мир «работает» - его естественные группы, физику и то, как его собственные действия влияют на состояние мира.

Затем он может использовать это понимание, чтобы установить оптимальную стратегию для данной задачи, без необходимости фактически проверять ее в реальном мире, потому что он может использовать свою собственную ментальную модель окружающей среды в качестве «игровой площадки» для экспериментов.

Это может быть описание ребенка, который учится ходить. Есть поразительные сходства, которые, возможно, лежат глубже, чем простая аналогия, что делает эту область исследований поистине увлекательной.

Резюме

Надеюсь, эта статья окажется для вас полезной - дайте мне знать в комментариях ниже, если вы обнаружите какие-либо опечатки или у вас возникнут вопросы по поводу чего-либо в кодовой базе или статье, и я свяжусь с вами как можно скорее.

Если вы хотите узнать больше о том, как наша компания Applied Data Science разрабатывает инновационные решения в области науки о данных для бизнеса, свяжитесь с нами через наш веб-сайт или напрямую через LinkedIn.

… и если вам это нравится, не стесняйтесь оставить несколько сердечных хлопков :)

Applied Data Science - это лондонская консалтинговая компания, которая внедряет комплексные решения для обработки данных для предприятий, обеспечивая измеримую ценность. Если вы хотите больше работать с данными, давайте поговорим.