RLlib - это библиотека с открытым исходным кодом на Python, основанная на Ray, которая используется для обучения с подкреплением (RL). Эта статья представляет собой краткое руководство о том, как создавать пользовательские среды Тренажерный зал для использования с RLlib. Вы можете использовать это как отправную точку для представления собственных вариантов использования, которые нужно решить с помощью обучения с подкреплением (RL).

Обратите внимание, что эта статья является продолжением:



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

Исходный код этой статьи доступен по адресу https://github.com/DerwenAI/gym_example.

Материал здесь взят из Anyscale Academy и дополняет документацию RLlib. Это предназначено для тех, у кого есть:

  • некоторый опыт программирования на Python
  • некоторое знакомство с машинным обучением
  • введение в обучение с подкреплением и RLLib (см. предыдущая статья)

Основные выводы для этой статьи включают в себя:

  • представляют проблему, которую нужно решить с помощью RL
  • создавать индивидуальные тренажерные залы, которые хорошо работают с RLlib
  • структурировать репозиторий Git для поддержки пользовательских сред тренажерного зала
  • зарегистрировать индивидуальную среду тренажерного зала
  • обучить политику в RLlib с помощью PPO
  • запустить развертывание обученной политики

Предыстория

Одна из первых вещей, которую многие люди запускают, когда узнают о RL, - это пример среды CartPole. OpenAI Gym имеет реализацию под названием CartPole-v1, которая имеет анимированный рендеринг, который есть во многих учебниках RL:

Это стало своего рода «Hello World» для обучения с подкреплением, и визуализация CartPole того, как RL обучает политику для агента, очень полезна.

Однако когда придет время представить ваш собственный вариант использования как среду для RL, что вы должны использовать в качестве основы? Хотя существует множество примеров для тренажерного зала, документации очень мало. Более того, эти примеры используют наследование классов таким образом, что их исходный код часто становится трудным для понимания. Кроме того, требования к структурированию библиотеки Python (в виде репозитория Git), чтобы ее можно было зарегистрировать как настраиваемую среду - они не являются интуитивно понятными, простыми для устранения неполадок и не особенно хорошо документированы.

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

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

Представьте проблему для обучения с подкреплением

Давайте поработаем с относительно простым примером, который иллюстрирует большинство элементов эффективного представления проблемы для обучения с подкреплением. Рассмотрим среду, которая представляет собой просто массив со значениями индекса от min до max и с позицией goal, установленной в середине массива.

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

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

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

  • наблюдать его положение в массиве
  • решить, двигаться влево или вправо
  • получить награду

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

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

Нам также необходимо ограничить максимальное количество шагов в эпизоде, чтобы агент не только правильно определял цель, но и был эффективным. Слишком маленький предел ограничит информацию, которую агент получает за эпизод. Слишком большой предел приведет к дополнительной работе с уменьшающейся отдачей. Чтобы не усложнять задачу, мы установим ограничение на длину массива. Дополнительная благодарность: если мы называем предел максимального количества шагов гиперпараметром, как вы можете определить его оптимальную настройку? Забегая вперед, несколько руководств, вот подсказка.

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

Определите индивидуальную среду в тренажерном зале

Исходный код для этой настраиваемой среды находится на GitHub, а основная часть того, что исследуют следующие фрагменты кода, находится в модуле по адресу https://github.com/DerwenAI/gym_example/blob/master/gym-example/gym_example /envs/example_env.py

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

import gym
from gym.utils import seeding

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

Затем нам нужно определить класс Python для нашей пользовательской среды:

class Example_v0 (gym.Env):

Наша настраиваемая среда называется Example_v0 и определяется как подкласс gym.Env. В этом классе мы определим несколько постоянных значений для описания «массива» в нашей среде. Тренажерному залу они не нужны, но они помогают управлять симуляцией массива…

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

LF_MIN = 1
RT_MAX = 10

На каждом шаге агент может перемещаться влево или вправо, поэтому давайте определим константы для представления этих действий:

MOVE_LF = 0
MOVE_RT = 1

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

MAX_STEPS = 10
                                
REWARD_AWAY = -2
REWARD_STEP = -1
REWARD_GOAL = MAX_STEPS

Класс среды Gym может определять необязательный metadata словарь:

metadata = {
    "render.modes": ["human"]
  }

В этом случае мы определим один параметр метаданных render.modes как список с "human" в качестве единственного элемента. Это означает, что среда будет поддерживать простой «человеческий» режим рендеринга текста на терминал, а не что-то более сложное, например, данные изображения, которые нужно преобразовать в анимацию.

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

Метод __init __ ()

Давайте определим требуемый __init__() метод, который инициализирует класс:

def __init__ (self):
    self.action_space = gym.spaces.Discrete(2)
    self.observation_space = gym.spaces.Discrete(self.RT_MAX + 1)
    # possible positions to chose on `reset()`
    self.goal = int((self.LF_MIN + self.RT_MAX - 1) / 2)
    self.init_positions = list(range(self.LF_MIN, self.RT_MAX))
    self.init_positions.remove(self.goal)
    # change to guarantee the sequence of pseudorandom numbers
    # (e.g., for debugging)
    self.seed()
    self.reset()

Эта функция инициализирует два обязательных элемента как пробелы Gym:

  • self.action_space - область действий возможных действий, предпринятых агентом
  • self.observation_space - область наблюдения, чтобы узнать, какую информацию получает агент после выполнения действия.

Пространство действий основано на gym.spaces.Discrete и представляет собой конечный массив с двумя значениями: константами MOVE_LF = 0 и MOVE_RT = 1, определенными выше. Они определяют, как агент взаимодействует с окружающей средой.

Пространство наблюдения также основано на gym.spaces.Discrete и представляет собой конечный массив, который равен длине массива окружения плюс один. Напомним, что для простоты выше мы выбрали массив, начинающийся с 1.

Члены self.goal и self.init_positions относятся к этой среде и не требуются Gym. Эти члены помещают нашу цель в середину массива, чтобы она не выбиралась случайным образом. Мы решили сделать это, чтобы облегчить читателю понимание, устранение неполадок, анализ, рекомбинирование частей и т.д. Позже в этом руководстве, когда мы обучаем политику с помощью RLlib, мы покажем, как этот пример быстро сходится, а кривые производительности для метрик обучения RL имеют классические формы - то, что вы надеетесь увидеть в задаче RL.

Мы вызываем self.seed(), чтобы рандомизировать псевдослучайные числа (подробнее об этом позже), а затем вызываем self.reset(), чтобы сбросить среду до начала эпизода.

Метод reset ()

Теперь мы определим требуемый reset() метод. Это сбрасывает состояние среды для нового эпизода, а также возвращает начальное наблюдение:

def reset (self):
    self.position = self.np_random.choice(self.init_positions)
    self.count = 0
    self.state = self.position
    self.reward = 0
    self.done = False
    self.info = {}
    return self.state

Члены self.position и self.count относятся к этой среде и не требуются Gym. Они отслеживают позицию агента в массиве и количество шагов, выполненных в текущем эпизоде.

В спортзале обычно используются четыре других члена для описания результата шага: self.state, self.reward, self.done, self.info как условные обозначения. Для возвращаемого значения после сброса мы предоставим self.state в качестве начального состояния, которое является рандомизированной начальной позицией агента.

Метод step ()

Теперь мы определим необходимый step() метод для обработки того, как агент выполняет действие на одном этапе эпизода:

def step (self, action):
   if self.done:
      # should never reach this point
      print("EPISODE DONE!!!")
   elif self.count == self.MAX_STEPS:
      self.done = True;
   else:
      assert self.action_space.contains(action)
      self.count += 1
      // insert simulation logic to handle an action ...
   try:
      assert self.observation_space.contains(self.state)
   except AssertionError:
      print("INVALID STATE", self.state)
   return [self.state, self.reward, self.done, self.info]

Другими словами, возьмите action как единственный параметр для этого шага. Если установлен флаг self.done, значит, серия уже закончилась. Хотя этого никогда не должно происходить, давайте рассмотрим это как крайний случай. Если агент превышает максимальное количество шагов в этом эпизоде, не достигнув цели, мы устанавливаем флаг self.done и завершаем эпизод.

В противном случае подтвердите, что ввод action действителен, увеличьте счетчик шагов, затем выполните логику моделирования для обработки действия. В конце функции мы утверждаем, что результирующее состояние допустимо, а затем возвращаем ожидаемый список [self.state, self.reward, self.done, self.info] для завершения этого действия.

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

if action == self.MOVE_LF:
    if self.position == self.LF_MIN:
        # invalid
        self.reward = self.REWARD_AWAY
    else:
        self.position -= 1
    if self.position == self.goal:
        # on goal now
        self.reward = self.REWARD_GOAL
        self.done = 1
    elif self.position < self.goal:
        # moving away from goal
        self.reward = self.REWARD_AWAY
    else:
        # moving toward goal
        self.reward = self.REWARD_STEP

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

Логика обработки действия «двигаться вправо» написана аналогичным образом:

elif action == self.MOVE_RT:
    if self.position == self.RT_MAX:
        # invalid
        self.reward = self.REWARD_AWAY
    else:
        self.position += 1
    if self.position == self.goal:
        # on goal now
        self.reward = self.REWARD_GOAL
        self.done = 1
    elif self.position > self.goal:
        # moving away from goal
        self.reward = self.REWARD_AWAY
    else:
        # moving toward goal
        self.reward = self.REWARD_STEP

После обработки этой логики обновите состояние среды, а также определите необязательный член self.info, который представляет собой словарь Python, который предоставляет диагностическую информацию, которая может быть полезна для устранения неполадок:

self.state = self.position
self.info["dist"] = self.goal - self.position

Содержимое self.info может быть любым, что подходит для словаря Python. В этом случае давайте отследим расстояние между агентом и целью, чтобы определить, приближаемся ли мы. Примечание: эта дополнительная информация не может использоваться RLlib во время обучения.

Метод render ()

Затем мы определим необязательный render() метод для визуализации состояния окружающей среды:

def render (self, mode="human"):
    s = "position: {:2d}  reward: {:2d}  info: {}"
    print(s.format(self.state, self.reward, self.info))

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

Метод seed ()

Теперь мы определим необязательный seed() метод, чтобы задать начальное значение для генератора псевдослучайных чисел в этой среде:

def seed (self, seed=None):
    self.np_random, seed = seeding.np_random(seed)
    return [seed]

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

Метод close ()

Для необязательного close() метода мы определим, как обрабатывать закрытие среды:

def close (self):
    pass

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

Вот и у нас получилось! Мы определили индивидуальную среду. Даже в этом случае мы пока не можем использовать его ... Сначала нам нужно добавить инструкции по настройке для использования его исходного кода в качестве библиотеки Python.

Структурируйте библиотеку Python и репозиторий Git

Теперь, когда у нас есть среда, нам нужно структурировать подкаталоги для того, чтобы импортировать и зарегистрировать их для использования. Это становится немного сложнее, поскольку среда будет использовать несколько программных библиотек. Python будет рассматривать его как библиотеку для импорта, а также как класс для создания экземпляра - для этого требуются определенные соглашения об именах. Затем RLlib необходимо будет зарегистрировать настраиваемую среду перед обучением. Затем Gym нужно будет построить среду отдельно, чтобы мы могли десериализовать обученную политику для развертывания. RLlib и Gym имеют разные способы обращения к среде, чем импорт Python. Поэтому мы должны тщательно структурировать макет и наименование подкаталогов.

Учитывая, что модуль исходного кода example_env.py находится в репозитории Git, вот подкаталог и макет файла для репозитория:

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

Из-за того, что среды тренажерного зала устанавливаются и импортируются Python, нам необходимо определить gym-example/setup.py для описания имен путей и зависимостей библиотек, необходимых для установки:

from setuptools import setup
setup(name="gym_example",
      version="1.0.0",
      install_requires=["gym"]
)

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

Затем нам нужно определить сценарий gym-example/gym_example/__init__.py, чтобы наша пользовательская среда могла быть зарегистрирована перед использованием:

from gym.envs.registration import register
register(
    id="example-v0",
    entry_point="gym_example.envs:Example_v0",
)

Другими словами, в подкаталоге envs будет определен класс Python Example_v0. Когда мы регистрируем среду перед обучением в RLlib, мы будем использовать example-v0 в качестве ее ключа. Зайдя в подкаталог envs, нам нужно определить сценарий gym-example/gym_example/envs/__init__.py как:

from gym_example.envs.example_env import Example_v0

Нам также необходимо добавить наш модуль исходного кода example_env.py в подкаталог envs.

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

Измерьте базовый уровень случайного действия

Теперь, когда у нас есть библиотека, давайте воспользуемся ею. Прежде чем перейти к использованию RLlib, сначала мы создадим простой скрипт Python, который запускает агента, выполняющего случайные действия. Исходный код доступен по адресу https://github.com/DerwenAI/gym_example/blob/master/sample.py

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

Сначала нам нужно импортировать тренажерный зал и нашу настраиваемую среду:

import gym
import gym_example

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

def run_one_episode (env):
    env.reset()
    sum_reward = 0
    for i in range(env.MAX_STEPS):
        action = env.action_space.sample()
        state, reward, done, info = env.step(action)
        sum_reward += reward
        if done:
            break
    return sum_reward

На каждом шаге действие выбирается с использованием env.action_space.sample(), а затем используется в вызове env.step(action). Это еще одна веская причина использовать env.seed() для устранения неполадок - заставить эту последовательность «случайных» действий каждый раз быть одинаковой. Кстати, вы можете добавить несколько точек останова отладки или print() операторов по всему этому циклу, чтобы увидеть, как работает эпизод в деталях.

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

env = gym.make("example-v0")
sum_reward = run_one_episode(env)

Обратите внимание, что мы вызвали gym.make("example-v0") с ключом, определенным в предыдущем разделе, а не именем класса Python или путем к библиотеке. Учитывая, что этот код работает, как ожидалось, давайте теперь вычислим базовый статистический план вознаграждений на основе случайных действий:

history = []
for _ in range(10000):
    sum_reward = run_one_episode(env)
    history.append(sum_reward)
avg_sum_reward = sum(history) / len(history)
print("\nbaseline cumulative reward: {:6.2}".format(avg_sum_reward))

Этот блок кода выполняет итерацию по 10000 эпизодам для вычисления среднего совокупного вознаграждения. На практике результирующее значение должно составлять примерно -5.0 плюс-минус небольшую долю.

Обучите политику с RLlib

Наконец, мы готовы использовать нашу настраиваемую среду в RLlib. Давайте определим еще один сценарий Python для обучения политики с обучением с подкреплением. Исходный код этого скрипта находится по адресу https://github.com/DerwenAI/gym_example/blob/master/train.py

Давайте позаботимся о некоторых приготовлениях, прежде чем мы начнем тренировку. Инициализируйте каталог, в котором будут сохранены контрольные точки (т. Е. Сериализовать политику на диск), как подкаталог ./tmp/exa, а также каталог, в который будут записывать журналы, которые Рэй ожидает иметь по умолчанию ~/ray_results/:

import os
import shutil
chkpt_root = "tmp/exa"
shutil.rmtree(chkpt_root, ignore_errors=True, onerror=None)
ray_results = "{}/ray_results/".format(os.getenv("HOME"))
shutil.rmtree(ray_results, ignore_errors=True, onerror=None)

Мы запустим Ray в локальном режиме, то есть не в удаленном кластере:

import ray
ray.init(ignore_reinit_error=True)

Кстати, если вам когда-нибудь понадобится использовать отладчик для устранения неполадок в настраиваемой среде, для Ray есть «локальный режим», который объединяет все задачи в один процесс для упрощения отладки. Просто добавьте еще один параметр local_mode=True в вызов ray.init().

Далее нам нужно зарегистрировать нашу настраиваемую среду:

from ray.tune.registry import register_env
from gym_example.envs.example_env import Example_v0
select_env = "example-v0"
register_env(select_env, lambda config: Example_v0())

Обратите внимание, как нам нужно было использовать как ключ "example-v0", так и имя класса Example_v0() Python, и что для импорта Python требуется полный путь к исходной модели.

Затем мы настроим среду для использования проксимальной оптимизации политики (PPO) и создадим агент для обучения с использованием RLlib:

import ray.rllib.agents.ppo as ppo
config = ppo.DEFAULT_CONFIG.copy()
config["log_level"] = "WARN"
agent = ppo.PPOTrainer(config, env=select_env)

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

status = "{:2d} reward {:6.2f}/{:6.2f}/{:6.2f} len {:4.2f} saved {}"
n_iter = 5
for n in range(n_iter):
    result = agent.train()
    chkpt_file = agent.save(chkpt_root)
    print(status.format(
            n + 1,
            result["episode_reward_min"],
            result["episode_reward_mean"],
            result["episode_reward_max"],
            result["episode_len_mean"],
            chkpt_file
            ))

Для каждой итерации мы вызываем result = agent.train() для запуска эпизодов, а затем вызываем chkpt_file = agent.save(chkpt_root), чтобы сохранить контрольную точку последней политики. Затем мы печатаем метрики, которые показывают, насколько хорошо продвигается обучение. Полученный результат должен выглядеть примерно так:

 1 reward -21.00/ -6.96/ 10.00 len 7.83 saved tmp/exa/checkpoint_1/checkpoint-1
 2 reward -20.00/  1.24/ 10.00 len 5.51 saved tmp/exa/checkpoint_2/checkpoint-2
 3 reward -20.00/  5.89/ 10.00 len 3.90 saved tmp/exa/checkpoint_3/checkpoint-3
 4 reward -17.00/  7.19/ 10.00 len 3.30 saved tmp/exa/checkpoint_4/checkpoint-4
 5 reward -17.00/  7.83/ 10.00 len 2.92 saved tmp/exa/checkpoint_5/checkpoint-5

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

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

tensorboard --logdir=$HOME/ray_results

Напомним, что наша базовая мера для среднего совокупного вознаграждения была -5.0, поэтому политика, обученная RLlib, значительно улучшилась по сравнению с агентом, выполняющим произвольные действия. Кривые в визуализациях Tensorboard выше, такие как episode_len_mean и episode_reward_mean, имеют классические формы для того, что вы обычно надеетесь увидеть в задаче RL.

Примените обученную политику в развертывании

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

import gym
agent.restore(chkpt_file)
env = gym.make(select_env)
state = env.reset()

Теперь давайте рассмотрим 20 эпизодов, отображая состояние среды в конце каждого эпизода:

sum_reward = 0
n_step = 20
for step in range(n_step):
    action = agent.compute_action(state)
    state, reward, done, info = env.step(action)
    sum_reward += reward
    env.render()
    if done == 1:
        print("cumulative reward", sum_reward)
        state = env.reset()
        sum_reward = 0

Строка action = agent.compute_action(state) представляет собой большую часть магии развертывания здесь для использования политики вместо обучающей политики. Полученный результат должен выглядеть примерно так:

position:  5  reward: 10  info: {'dist': 0}
cumulative reward 10
position:  3  reward: -1  info: {'dist': 2}
position:  4  reward: -1  info: {'dist': 1}
position:  5  reward: 10  info: {'dist': 0}
cumulative reward 8
position:  7  reward: -1  info: {'dist': -2}
position:  6  reward: -1  info: {'dist': -1}
position:  5  reward: 10  info: {'dist': 0}
cumulative reward 8

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

Резюме

Полный исходный код этого руководства на Python находится в репозитории GitHub https://github.com/DerwenAI/gym_example.

Используйте Git для клонирования этого репозитория, подключитесь к его каталогу, а затем установите эту настраиваемую среду:

pip install -r requirements.txt
pip install -e gym-example

Таким образом, мы создали специальную среду тренажерного зала, чтобы представить проблему, которую нужно решить с помощью RL. Мы показали шаблон того, как реализовать эту среду, как структурировать подкаталоги репозитория Git. Мы создали сценарий «тестовой оснастки» и проанализировали среду, чтобы получить базовый показатель совокупного вознаграждения, когда агент выполняет случайные действия. Затем мы использовали RLlib для обучения политики с помощью PPO, сохраненных контрольных точек и оценки результатов, сравнивая с нашими базовыми показателями случайного действия. Наконец, мы выполнили развертывание обученной политики, показав, как получившуюся политику можно развернуть в конкретном случае использования.

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

Также посетите Anyscale Academy, чтобы узнать о связанных обучающих материалах, обсуждениях и событиях. В частности, вы можете узнать больше об обучении с подкреплением (инструменты, примеры использования, последние исследования и т. Д.) На конференции Ray Summit, которая будет проходить онлайн с 30 сентября по 1 октября (бесплатно!), А обучающие программы - 29 сентября. (номинальная плата).

Престижность https://deepdreamgenerator.com/ за обработку изображений с глубоким обучением.