Вводный блог о пользовательской среде TF-Agent

Фон

Обучение с подкреплением - это развивающаяся область искусственного интеллекта, которая показала многообещающие возможности в таких областях, как игры, робототехника, производство и аэрокосмическая промышленность. После победы над человеческими чемпионами в таких играх, как го [1] и шахматы [2] в середине 2010-х годов, обучение с подкреплением стало популярным. Google купил DeepMind [3], уважаемый стартап в области искусственного интеллекта, который внес свой вклад в большинство прорывов в обучении с подкреплением в 2010-х годах. Точно так же OpenAI была основана в конце 2015 года Илоном Маском, Сэмом Альтманом и другими [4], которые пообещали выделить 1 миллиард долларов США на проведение исследований в области искусственного интеллекта. OpenAI заявил о своей цели продвигать и развивать дружественный ИИ таким образом, чтобы приносить пользу всему человечеству. OpenAI Five, проект OpenAI, продемонстрировал способность достигать производительности на уровне экспертов, изучать взаимодействие человека и ИИ и работать в масштабе Интернета в игре Dota 2 [5]. Недавно Google применил обучение с подкреплением при размещении чипа, один из самых сложных и трудоемких этапов процесса проектирования чипа, с целью минимизировать PPA (мощность, производительность и площадь) и показал, что сгенерированные размещения являются сверхчеловеческими [6 ].

Обучение с подкреплением существует с 1950-х годов [7], создавая множество интересных приложений в играх и управлении машинами. Они никогда не получали заголовков до 2013 года, когда исследователи DeepMind продемонстрировали его использование в играх Atari, которые в большинстве из них превзошли людей [8]. Определяющим улучшением стало использование нейронных сетей для изучения значений Q [9]. Как и в любой другой области искусственного интеллекта, нейронные сети произвели революцию в области обучения с подкреплением, представив глубокое обучение с подкреплением [9]. С тех пор обучение с подкреплением повсюду и приобретает беспрецедентную популярность. На недавней конференции ICLR (ICLR 2020) мы видим, что обучение с подкреплением было наиболее частым признаком [10].

Итак, что такое обучение с подкреплением?

В отличие от машинного обучения с учителем, где доступны помеченные данные, обучение с подкреплением не предоставляется с явными помеченными данными. При обучении с подкреплением агент выполняет некоторые действия в некоторой среде, из-за которых состояние среды изменяется. Основываясь на обратной связи (вознаграждение или штраф), предоставленной средой за какое-либо действие, алгоритм изучает оптимальную политику. Ребенок, обучающийся самостоятельно ходить, напоминает парадигму обучения с подкреплением. Ребенок, уравновешивающий себя, - это стадия вознаграждения, тогда как ребенок, теряющий равновесие, - стадия наказания или неудачи. Более теоретическое объяснение можно найти в вводных блогах по обучению с подкреплением, и читателю настоятельно рекомендуется это сделать, если обучение с подкреплением для него / нее в новинку.

TF-агенты

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

Стабильная версия TF-Agents может быть установлена ​​с помощью следующего кода:

pip install --user tf-agents
pip install --user tensorflow==2.1.0

Более подробную информацию о TF-агентах можно найти здесь.

Среда

Среда - это окружение или окружение, в котором агент выполняет действия. Агент взаимодействует с окружающей средой, и состояние среды изменяется. При реализации алгоритмов обучения с подкреплением в некоторых приложениях требуется среда для этого приложения. Хотя TensorFlow предоставляет среду для некоторых из популярных проблем, таких как CartPole, мы попадаем в ситуацию, когда нам нужно создавать собственные среды. Здесь я покажу реализацию Tic-tac-toe путем создания пользовательской среды.

Пользовательская среда для крестиков-ноликов

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

Начнем сначала с необходимого импорта.

import tensorflow as tf
import numpy as np
from tf_agents.environments import py_environment
from tf_agents.environments import tf_environment
from tf_agents.environments import tf_py_environment
from tf_agents.environments import utils
from tf_agents.specs import array_spec
from tf_agents.environments import wrappers
from tf_agents.environments import suite_gym
from tf_agents.trajectories import time_step as ts

Среды могут быть либо средой Python, либо средой TensorFlow. Среды Python просты в реализации, но среды TensorFlow более эффективны и допускают естественное распараллеливание. Здесь мы создаем среду Python и используем одну из наших оболочек для ее автоматического преобразования в среду TensorFlow.

Избиратели

Создание настраиваемой среды состоит в основном из четырех методов: action_spec, Наблюдение_spec, _reset и _step. Давайте посмотрим, что означает каждый из них:

action_spec: описывает спецификации (TensorSpecs) действия, ожидаемого на этапе
Наблюдение_spec: определяет спецификации (TensorSpec ) наблюдений, предоставленных средой
_reset: возвращает текущую ситуацию (TimeStep) после сброса среды
_step : применяет действие и возвращает новую ситуацию (TimeStep).

Класс SimplifiedTicTacToe

Теперь приступим к созданию класса SimplifiedTicTacToe. Класс наследуется от класса py_environment.PyEnvironment для извлечения уже доступных методов и свойств.

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

Наблюдение - это состояние окружающей среды. Спецификация наблюдения содержит спецификации наблюдений, предоставляемых окружающей средой. Поскольку на доске 9 позиций, форма наблюдения будет (1, 9). Если какая-то позиция занята, мы можем обозначить состояние позиции 1, иначе 0. Изначально доска пуста, поэтому мы представляем состояние окружения девятью нулями.

class SimplifiedTicTacToe(py_environment.PyEnvironment):
  def __init__(self):
    self._action_spec = array_spec.BoundedArraySpec(
        shape=(), dtype=np.int32, minimum=0, maximum=8, name='play')
    self._observation_spec = array_spec.BoundedArraySpec(
        shape=(1,9), dtype=np.int32, minimum=0, maximum=1, name='board')
    self._state = [0, 0, 0, 0, 0, 0, 0, 0, 0]
    self._episode_ended = False
  def action_spec(self):
    return self._action_spec
  def observation_spec(self):
    return self._observation_spec

После завершения игры мы должны сбросить среду (или состояние). Для этого мы можем написать метод под названием _reset в созданной нами настраиваемой среде. Метод должен возвращать состояние среды по умолчанию в начале игры.

def _reset(self):
  # state at the start of the game
  self._state = [0, 0, 0, 0, 0, 0, 0, 0, 0]
  self._episode_ended = False
  return ts.restart(np.array([self._state], dtype=np.int32))

Здесь стоит упомянуть о эпизоде ​​ и шаге. Эпизод - это экземпляр игры (или жизненного цикла игры). Если игра заканчивается или жизнь уменьшается, эпизод заканчивается. Шаг, с другой стороны, - это время или какое-то дискретное значение, которое монотонно увеличивается в эпизоде ​​. При каждом изменении состояния игры значение step увеличивается, пока игра не закончится.

Давайте также определим два метода для проверки того, пусто ли какое-то место и все ли места заняты.

def __is_spot_empty(self, ind):
    return self._state[ind] == 0
def __all_spots_occupied(self):
    return all(i == 1 for i in self._state)

Теперь нам нужно написать последний метод: _step. Он применяет действие и возвращает новую ситуацию в игре. Ситуация относится к классу TimeStep в TensorFlow. TimeStep содержит четыре информации: наблюдение, вознаграждение, тип_шага и скидка. Подробности о каждой информации можно найти здесь.

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

def _step(self, action):    
    if self._episode_ended:
        return self.reset()
    if self.__is_spot_empty(action):        
        self._state[action] = 1
        
        if self.__all_spots_occupied():
            self._episode_ended = True
            return ts.termination(np.array([self._state], dtype=np.int32), 1)
        else:
            return ts.transition(np.array([self._state], dtype=np.int32), reward=0.05, discount=1.0)
    else:
        self._episode_ended = True
        return ts.termination(np.array([self._state], dtype=np.int32), -1)

За прохождение каждого шага дается награда 0,05. Награда в размере 1 применяется, когда мы делаем тики всех 9 позиций. Если игра заканчивается с менее чем 9 тиками позиции, получается отрицательное вознаграждение в размере -1. Здесь используется скидка 1,0, чтобы вознаграждение не уменьшалось по времени / шагу.

Теперь давайте создадим среду TensorFlow.

python_environment = SimplifiedTicTacToe()
tf_env = tf_py_environment.TFPyEnvironment(python_environment)

Ура! Среда TensorFlow создана!

Давайте играть

А теперь давайте поиграем в игру 10000 эпизодов.

time_step = tf_env.reset()
rewards = []
steps = []
number_of_episodes = 10000
for _ in range(number_of_episodes):
  reward_t = 0
  steps_t = 0
  tf_env.reset()
  while True:
    action = tf.random.uniform([1], 0, 9, dtype=tf.int32)
    next_time_step = tf_env.step(action)
    if tf_env.current_time_step().is_last():
      break
    episode_steps += 1
    episode_reward += next_time_step.reward.numpy()
  rewards.append(episode_reward)
  steps.append(episode_steps)

Мне интересно знать среднее количество шагов. Итак, я выполняю следующий код.

mean_no_of_steps = np.mean(steps)

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

Ожидание количества шагов

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

X состоит из девяти случайных величин X_1, X_2,…, X_9. X_i равен 1, если нет повторений до i -го шага. Нам нужно найти ожидание X.

Если для некоторого значения i, X_i = 0; X_j = 0 для всех значений j ›i.

So, E[X] = E[X_1] + E[X_2|X_1] + … + E[X_9|X_1, … , X_8]

Теперь давайте вычислим значение E [X_i | X_1,…, X_ (i - 1)].

Случайная величина X_i равна 1, если нет повторений до i -го шага. Для этого вероятность:

P (без повторения до i-го шага) = отсутствие неповторяющихся перестановок до i-го шага / общее количество перестановок до i-го шага
= P (9, i) / (9 ^ i)

Вероятность, умноженная на 1, дает саму вероятность. Итак, ожидание становится суммой этих вероятностей.

Следовательно, ожидание таково:

E [X] = сумма от i = 1 до i = 9 (P (9, i) / (9 ^ i))3,46

Еще один изящный подход к поиску ожидания можно найти здесь - благодаря Хенку Брозиусу.

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

Вот как можно создать пользовательскую среду в TensorFlow. TF-Agents предоставляют модульные компоненты, упрощающие создание прототипов. У вас хорошее начало. С TF-агентами мы можем сделать гораздо больше. Продолжайте исследовать! Небо - предел!

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

  1. Среды: https://www.tensorflow.org/agents/tutorials/2_environments_tutorial
  2. tf_agents.specs.BoundedArraySpec: https://www.tensorflow.org/agents/api_docs/python/tf_agents/specs/BoundedArraySpec

Если у вас есть какие-либо вопросы, комментарии или недоразумения, не стесняйтесь оставлять комментарии здесь. Я постараюсь ответить на них.

использованная литература

  1. Https://www.newscientist.com/article/2132086-deepminds-ai-beats-worlds-best-go-player-in-latest-face-off/
  2. Https://www.theguardian.com/technology/2017/dec/07/alphazero-google-deepmind-ai-beats-champion-program-teaching-itself-to-play-four-hours
  3. Https://techcrunch.com/2014/01/26/google-deepmind/
  4. Https://openai.com/blog/introduction-openai/
  5. Https://openai.com/projects/five/
  6. Https://ai.googleblog.com/2020/04/chip-design-with-deep-reinforcement.html
  7. Http://incompleteideas.net/book/first/ebook/node12.html
  8. Https://arxiv.org/abs/1312.5602
  9. Орелиен Жерон - Практическое машинное обучение с помощью Scikit-Learn, Keras и TensorFlow_. Концепции, инструменты и методы для создания интеллектуальных систем (2019, O’Reilly Media)
  10. Https://iclr.cc/virtual_2020/paper_vis.html
  11. Https://www.tensorflow.org/agents
  12. Https://www.quora.com/Suppose-we-are-drawing-a-number-randomly-from-the-list-of-numbers-1-to-9-After-each-draw-the-number -is-replace-How-can-we-find-the-expected-number-of-draws-after-which-we-meet-the-first-repetition / answer / Henk-Brozius? __ filter __ = all & __ nsrc __ = 1 & __ sncid __ = 5298994587 & __ snid3__ = 8434034083