Практический курс RL — часть 6

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

Добро пожаловать на курс ❤️

Добро пожаловать в часть 6 практического курса по обучению с подкреплением, который проведет вас с нуля до HERO 🦸‍♂️.

Это то, что сделано до сих пор:

  1. Введение в обучение с подкреплением
  2. Табличное Q-обучение
  3. Табулярная САРСА
  4. Линейное Q-обучение
  5. Глубокое Q-обучение
  6. 👉🏻 Гиперпараметры в Deep RL (сегодня)

В части 5 мы создали идеальный агент для решения среды Cart Pole, используя Deep Q Learning.

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

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

Сегодня мы будем использовать лучшую библиотеку с открытым исходным кодом для поиска гиперпараметров в экосистеме Python: Optuna.

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

Хочешь поделиться любовью? Пожалуйста, поставьте ⭐ на Github!

Часть 6

Содержание

  1. "Проблема"
  2. Решение: байесовский поиск
  3. Поиск гиперпараметров с Optuna
  4. Резюме ✨
  5. Домашнее задание 📚
  6. "Что дальше? ❤️»

1. Проблема

Модели машинного обучения имеют параметры и гиперпараметры.

В чем разница между этими двумя?

Параметры — это числа, которые вы найдете ПОСЛЕ обучения вашей модели. Например, параметры нейронной сети, которая отображает состояния в оптимальные q-значения.

С другой стороны, гиперпараметры — это числа, которые необходимо задать ДО обучения модели. Вы не можете найти их через обучение, но вам нужно заранее правильно их угадать. После их установки вы обучаете модель и находите остальные параметры.

Гиперпараметры существуют повсюду в машинном обучении. Например, в задачах машинного обучения с учителем (подобных той, которую мы решили в части 5) вам необходимо установить скорость обучения. Слишком малое число, и модель застрянет в локальных минимумах. Слишком большое число приведет к тому, что модель будет слишком сильно колебаться и никогда не сойдется к оптимальным параметрам.

В глубоком обучении с подкреплением все становится еще сложнее.

Почему?

Потому что

  • Алгоритмы глубокого RL имеют больше гиперпараметров, чем модели контролируемого машинного обучения.
  • И, что еще более важно, гиперпараметры в Deep RL оказывают огромное влияние на конечный результат обучения. Другими словами, алгоритмы глубокого RL очень чувствительны к заранее заданным вами гиперпараметрам. Чем сложнее среда, тем более важны гиперпараметры.

В части 5 мы видели, как два набора гиперпараметров в сочетании с одной и той же параметризацией сети q-значений приводят к двум очень разным агентам с очень разной производительностью. Один из агентов был в порядке (со средней наградой около 180), а другой был идеальным решением (средняя награда 500).

Тогда вопрос…

Как мы можем найти **хорошие** гиперпараметры? 🤔

Чтобы найти хорошие гиперпараметры, мы используем метод проб и ошибок.

По сути, это 4 шага:

  1. Мы выбираем набор гиперпараметров,
  2. Обучить агента,
  3. Оцените агента.
  4. Если мы довольны результатом, мы закончили. В противном случае мы выбираем новый набор гиперпараметров и повторяем весь процесс.

Поиск по сетке

Если количество гиперпараметров невелико (например, 2–3), мы можем попробовать все возможные комбинации и выбрать ту, которая работает лучше всего. Этот метод называется поиск по сетке, и он хорошо работает для многих задач машинного обучения с учителем.

Например, если наш алгоритм имеет только 2 гиперпараметра, каждый из которых принимает 1 из 5 возможных значений, мы получим 5 x 5 = 25 комбинаций. Мы можем обучить агента 25 раз, используя каждую комбинацию гиперпараметров, и найти лучшие из них.

С другой стороны, в задачах Deep RL гиперпараметров намного больше, например, 10–20. И каждый гиперпараметр может принимать множество возможных значений.

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

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

10 минут x 10 000 000 000 = 190 258 лет 😵‍💫

Что простыми словами означает… невозможно.

Вы можете распараллелить поиск и уменьшить это число на несколько порядков. Например, если у вас есть большой кластер компьютеров, который может запускать до 100 000 параллельных процессов, это займет у вас около 2 лет…

Тем не менее, это очень неэффективный способ решения проблемы, вам не кажется?

Случайный поиск

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

Идея проста: вместо проверки каждой из N возможных комбинаций гиперпараметров (где N — очень большое число, например, 1 000 000 000), мы случайным образом проверяем их подмножество с размером T (где T намного меньше чем N, например 100), и обучите и оцените агента T раз. Из этих T испытаний мы выбираем комбинацию гиперпараметров, которая работает лучше всего.

Случайный поиск является более эффективным способом поиска и работает намного лучше, чем поиск по сетке, с точки зрения скорости и качества решения.

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

Должен быть более разумный способ, не так ли? 🤔

2. Решение: байесовский поиск

Чтобы хорошо искать (что бы вы ни искали в жизни), обычно полезно вспомнить, что вы пробовали в прошлом, и использовать эту информацию, чтобы решить, что лучше попробовать дальше.

Это именно то, что делают методы байесовского поиска.

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

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

В конце концов, ваша суррогатная модель достаточно хороша, чтобы направить поиск в сторону хороших гиперпараметров. И вуаля, вот как вы их получите!

Байесовские методы поиска превосходят случайный поиск и являются идеальным выбором для использования в Deep RL.

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

Скажи 👋 Оптуне

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

Optuna имеет чистый API, который абстрагируется от всех мелких деталей, лежащих в основе TPE и других байесовских методов поиска. Это идеальная библиотека plug-and-play, которую мы можем начать использовать без глубокого понимания математики, лежащей в основе байесовских методов.

Если вы хотите вникнуть в мельчайшие детали байесовского поиска и оценки Парзена с древовидной структурой, я рекомендую вам прочитать этот замечательный пост Уилла Кёрсена:
📝 Концептуальное объяснение байесовского гиперпараметра Оптимизация для машинного обучения

Вооружившись байесовскими методами и Optuna, мы готовы найти гиперпараметры, которые решат нашу задачу.

Итак, давайте сделаем это!

3. Поиск гиперпараметров с помощью Optuna

👉🏽 блокноты/09_hyperparameter_search.ipynb

Начнем с загрузки среды:

Для визуализации параметров и показателей оценки для каждого запуска гиперпараметров мне нравится использовать MLflow.

MLflow — очень модульная библиотека, предназначенная для операционализации моделей ML (также известных как MLOps). Один из его компонентов называется MLFlow Tracking, и, как следует из названия, он помогает нам отслеживать все, что нам нужно во время разработки модели. Это важно, когда вы проводите много экспериментов с гиперпараметрами и хотите регистрировать точную конфигурацию, которую вы использовали при каждом запуске.

Мы будем регистрировать показатели MLflow в MLFLOW_RUNS_DIR в рамках эксперимента под названием hyperparameter_search.

🔎 Визуализация результатов поиска гиперпараметров

Чтобы увидеть панель инструментов MLFLow, перейдите в командную строку и перейдите в корневой каталог сегодняшнего урока.

Вот как это выглядит на моем компьютере
$ cd ~/src/online-courses/hands-on-rl/03_cart_pole

Затем вы запускаете сервер отслеживания MFLow:
$ mlflow ui --backend-store-uri mlflow_runs/

и щелкните URL-адрес, напечатанный на консоли, в моем случае это http://127.0.0.1:5000

Для оптимизации гиперпараметров с помощью Optuna мы инкапсулируем

  • выборка гиперпараметров
  • обучение
  • и оценка агента RL

в функции objective(), которая возвращает метрику, которую мы хотим оптимизировать.

Целевая функция

В нашем случае функция objective() производит выборку гиперпараметров с помощью вызова sample_hyper_parameters(), обучает агент на 200 эпизодах и оценивает его на 1000 новых эпизодах. Результатом этой функции является среднее вознаграждение за эти 1000 эпизодов. Это показатель, который мы хотим максимизировать.

Функция sample_hyper_parameters() производит выборку и возвращает значения гиперпараметров в соответствии с

  • диапазоны, которые мы указываем
  • и сэмплер, используемый Optuna, по умолчанию является TPE.

Если вы проверите определение функции sample_hyper_parameters() в src/optimize_hyperparameters.py, вы увидите, что мы предоставляем только широкие интервалы или диапазоны значений, где имеет смысл использовать гиперпараметр. Нам не нужно внедрять какую-либо методологию байесовской выборки, так как Optuna сделает это за нас.

Следующим шагом является создание объекта исследования Optuna.

Обратите внимание, как мы устанавливаем параметрstorage для локального файла sqlite. Это важно, потому что позволяет возобновить поиск, если по какой-либо причине компьютер или процесс, на котором мы запускаем код, выйдет из строя.

Наконец, мы начинаем поиск с study.optimize() и говорим Optuna, чтобы он попробовал до 100 попыток.

В моем MacBook требуется около 15 минут, чтобы попасть в гиперпараметры, которые дают 500 баллов, то есть идеального агента.

Я рекомендую вам отслеживать результаты на панели инструментов MLflow и прервать поиск Optuna, как только вы увидите, что агент получает 500 вознаграждений.

Вот как результаты выглядят для меня:

Наконец, чтобы убедить вас, что вы отлично решили CartPole, я призываю вас загрузить своего лучшего агента (agent_id = 298 в моем случае)...

…и оцените его снова. Вы должны набирать 500 очков в каждом эпизоде!

Бинго!

Поздравляю! Наконец-то мы узнали, как настроить гиперпараметр, чтобы максимизировать производительность нашего агента Deep Q.

Это CartPole приключение было долгим.

Время сесть, расслабиться и оглянуться на путь, который мы только что прошли.

4. Резюме ✨

Вот основные выводы на сегодня:

  • Гиперпараметры в Deep RL имеют решающее значение. Вам нужно поэкспериментировать, чтобы найти хорошие, и это может занять очень много времени, если вы не будете следовать разумной стратегии поиска. Только грубая сила (т. е. поиск по сетке) НЕ осуществима в большинстве случаев.
  • Байесовские методы поиска являются одними из лучших инструментов для решения этой проблемы. Они изучают и изучают наиболее перспективные области в пространстве гиперпараметров, которые стоит попробовать дальше. Они сходятся быстрее, чем случайный поиск.
  • Optuna — отличная библиотека с открытым исходным кодом для поиска по гиперпараметрам. Это готовое решение, которое абстрагируется от всех мелких деталей байесовского поиска. С помощью нескольких строк кода вы можете создать мощный конвейер экспериментов с гиперпараметрами.

5. Домашнее задание 📚

👉🏽 тетради/10_homework.ipynb

Пора запачкать руки:

  1. Git clone репозиторий на локальный компьютер.
  2. Настройка среды для этого урока 03_cart_pole
  3. Открыть 03_cart_pole/notebooks/10_homework.ipynb

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

Если вы внимательно посмотрите на функцию sample_hyper_parameters(), вы поймете, что я сохранил фиксированную архитектуру нейронной сети (т.е. nn_hidden_layers = [256, 256]).

Сможете ли вы найти идеального агента, используя Q-сеть только с одним скрытым слоем?

6. Что дальше? ❤️

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

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

Хотите знать, как?

Следите за обновлениями.

До тех пор,

Мир, любовь и обучение.

Хотите стать профессионалом в области машинного обучения и получить доступ к лучшим курсам по машинному обучению и науке о данных?

👉🏽 Подпишитесь на рассылку datamachines.

👉🏽 Подпишитесь на меня на Medium.

👉🏽 Поставить ⭐ репозиторий курса на GitHub

Хорошего дня 🧡❤️💙

Пау