Реализация AI с алгоритмом AlphaZero для EvoPawness (временное имя), настольной игры по моей идее.

Всем привет, добро пожаловать в третью часть создания ИИ на EvoPawness (временное имя). В этой статье мы реализуем в игре алгоритм AlphaZero. Эта статья расскажет вам краткое описание AlphaZero и реализации AlphaZero, хотя и в упрощенном виде. Мы сделаем это шаг за шагом. Мы будем использовать некоторую терминологию, указанную в Части 1, такую ​​как функция результата, возможные действия и функция терминала.

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

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

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

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

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

Готовьтесь, это будет длинная статья. Прочитано 25 минут!

Контур

  1. Репозиторий
  2. Краткое описание AlphaZero
  3. Измененное правило
  4. Шаги
  5. Компоненты AlphaZero
  6. Реализация AlphaZero
  7. Урок выучен
  8. Заключение
  9. Послесловие

Репозиторий

Если вы начнете читать о ходе игры с этой статьи, вот репозиторий:



Я добавил несколько изменений в репозиторий:

  • Добавить реализацию AlphaZero
  • Переформатировать модуль или структуру папок
  • Изменить ключ представления действия.
  • Измените модель игры и контроллер в соответствии с новым правилом

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

Изменить (3/12/2018): я почистил код. Теперь у нас есть Config.py для редактирования конфигурации. См. main.py -h о том, как запустить программу. Для получения дополнительной информации подождите, пока я завтра отредактирую README.md.

Редактировать 2 (12.10.2018): я отправил обновленную README.md

Краткое описание AlphaZero

AlphaZero создан Deep Mind, который опубликован в следующей статье [Источник 4]. Что делает его особенным, так это то, что он может превзойти лучший ИИ в шахматах и ​​сёги за 24 часа тренировки. Это делает этот алгоритм лучшим на то время в играх с ИИ. Для получения дополнительной информации вы можете прочитать эту статью о том, насколько мощным может быть этот алгоритм.

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

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

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

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

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

В этой статье мы упростим архитектуру, используемую в статье. Мы будем использовать упрощенную реализацию AlphaZero, основанную на статье, которую я прочитал. В реализации, используемой Дэвидом Фостером [Источник 2], он использует 4 остаточных уровня, которые связаны с заголовком политики и заголовком значения. Я использовал его архитектуру и изменил некоторые гиперпараметры. Я также вижу реализацию AlphaZero в [Source 1] и изменяю реализацию, чтобы она соответствовала этой игре. Я слежу за реализацией поиска по дереву Монте-Карло в этой статье и меняю реализацию с рекурсивного использования на структурированное дерево данных.

Реализация, используемая в этих статьях, встроена в статью с некоторыми пропущенными частями. Я пропустил несколько шагов, например v resignation. В этих двух статьях они не реализуют сложенное состояние. В этой статье я реализую сложенное состояние и использую 140 плоскостей в качестве входных данных модели. В этой статье реализация AlphaZero также не реализовала многопоточную MCTS с использованием виртуальных потерь.

Измененное правило

  1. Руна появится в 3 разных положениях. Есть (по оси y, x) (4,0), (4,4) и (4,8). Руна, появляющаяся в (4,0), поднимет 2 очка атаки. Руна, появляющаяся в (4,4), поднимет 2 очка здоровья. а руна, появляющаяся в (4,8), поднимет 1 очко шага.
  2. Положение руны, которое занимает пешка, когда во время появления руны (каждые 5 ходов) руна не появляется.
  3. Количество шагов, здоровья и атаки ограничено. 3 для шагов, 20 для здоровья и 8 для очков атаки

Шаги

В этой статье AlphaZero будет реализован в следующем порядке:

  1. Определите представление состояния для входа модели. Мы используем сложенное состояние.
  2. Определите представление действия для игры.
  3. Решите, какая сторона будет использоваться для представления состояния (черная или белая) для всех игроков, и определите, как изменить сторону.
  4. Определите несколько идентичных состояний, которые можно использовать для увеличения входных данных модели.
  5. Определить функцию вознаграждения
  6. Реализовать архитектуру нейронной сети, которая используется для вывода оценки политики.
  7. Реализовать поиск по дереву Монте-Карло
  8. Добавьте функцию дуэли, чтобы оценить лучшую модель.

Компоненты AlphaZero

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

Состояние представительства

В этом разделе мы увидим состояние представления для входа нейронной сети. Входными данными нейронной сети является стек изображений, представляющий состояние. В реализации используется 28 входных функций. Здесь мы будем использовать 5-шаговую историю (Примечание: в статье AlphaZero количество шагов истории равно 8. Здесь в этой статье будет использоваться другое число). Из количества используемых нами пошаговых историй это означает, что имеется 140 входных функций (28 X 5).

История сохранит представление состояния на предыдущем повороте. Если мы используем 5-шаговую историю, учитывая, что состояние находится в T-повороте, мы возьмем состояние T, T-1, T-2, T-3, T-4, которое будет сложено и станет входом для нейронной сети.

Вот особенности ввода:

В № 4–10, 13 используются двоичные функции, а в остальных - частотные.

Поскольку размер платы 9 x 9, если у нас есть batch_size в качестве общего экземпляра входа нейронной сети, у нас есть (batch_size, 9, 9, 140) shape в качестве входа нейронной сети. Итак, у нас есть 4-х мерные данные в качестве входных данных.

Что касается кода, вы можете увидеть функцию get_representation_stack() в исходном коде ниже:



В исходном коде мы будем использовать AIElements class, который содержит элементы, которые мы определяем в части 1. Мы используем deque в качестве нашей структуры данных (например, стека).

Прежде чем мы получим входное представление нейронной сети, мы сложим состояние, представление состояния, которое мы определили в Части 1, в структуру deque data с желаемой максимальной длиной (в этой статье мы установили ее равной 5). Затем мы обрабатываем deque и превращаем его во входное представление для нейронной сети.

Представление действия

В игре доступно 5 типов действий. Есть активировать, продвигать, перемещать, атаковать и пропускать.

Для действия активации нам нужно выбрать пешку, которую нужно активировать. Нам нужны координаты пешки. Итак, у нас есть 81 (9 x 9) различных уникальных действий активации.

Примечание. у нас другое представление клавиш действия, которое указано в Части 1, новое представление указано ниже:

Action Key Representation for the activate action: a*y,x
y : pawn's axis-y
x : pawn's axis-x
example a*1,0

Для действия «Повышение» нам нужно выбрать пешку, которую нужно повысить, а затем выбрать возможный вариант повышения пешки. Нам нужны координаты пешки. У нас есть 9 x 9 различных уникальных действий для выбора возможной пешки. Существует 4 типа повышенных пешек (ферзь, ладья, слон, конь), поэтому существует 324 (9 x 9 x 4) уникальных способа сделать действие перехода.

Action key representation for the promote action : p*y,x*choice
y : pawn's axis-y
x : pawn's axis-x
choice : promote choice, K for Knight, R for Rook, B for Bishop, and Q for Queen
example p*3,3*Q

Для атак и действий. В этой игре у нас есть 7 типов пешек. Направление движения было определено в Части 1. В Части 1 у нас есть атака и движение как отдельные действия. В этой статье мы объединим действие атаки и действие перемещения в одно (они не пересекаются, поэтому мы можем их объединить). Мы видим, что направление движения солдата, ладьи, слона и короля является подмножеством ферзя. Он перемещается по вертикали, горизонтали и диагонали в направлениях N, NE, E, SE, W, SW, W и NW. Только у коня разные ходы. Он движется в форме буквы L во всех направлениях компаса. Таким образом, у нас есть 2 типа ходов: ферзь и конь.

У нас есть 2 шага для выполнения действия: выбор пешки и выбор допустимого хода пешки на основе возможного действия. В данном случае у нас есть 81 (9 x 9) различных действий для выбора пешки. Затем для выбора допустимого хода у нас есть 8 различных действий для типа хода конем и 24 (8 x 3) для типа хода ферзя (Примечание: у нас есть 3 как предел количества шагов, поэтому ферзь ход может состоять из 24 ходов). Общее количество уникальных действий, которые могут быть выполнены, составляет 2592 (81 x 32) для выбора допустимого хода для атаки и действия движения.

Action Key Representation for the activate action: m*y1,x1*y2,x2
y1 : selecting the pawn in axis-y
x1 : selecting the pawn in axis-x
y2 : direction of the move in axis-y
x2 : direction of the move in axis-x
Example m*0,1*2,1 (means that it will move from (0,1) to (2,2)

Пропустите, если игрок ничего не может сделать.

The action key representation for skip is skip

Сумма уникальной акции - 2998 (9 x 9 x 37 + 1)

Представление действия используется для кодирования распределения вероятностей, которое используется для выбора действия позже при выполнении поиска по дереву Монте-Карло (MCTS). Позже действие, которое невозможно выполнить в этом состоянии, маскируется и устанавливает вероятность равной 0 и повторно нормализует распределение вероятностей для возможного действия.

См. Репозиторий для реализации того, как сгенерировать все возможные действия. Я использовал LabelEncoder и OneHotEncoder из библиотеки scikit-learn, чтобы закодировать действие в One Hot Encoder.

Один класс горячего кодировщика (см. fit()):



Сгенерировать все уникальные действия (см. action_spaces() функцию):



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

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

Как мы можем это сделать?

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

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

Вот псевдокод:

def mirror(self, pawn):
    pawn.y = pawn.y - 4 # 4 is the center position of the board
    pawn.y *= -1 # after we move the center to 0, we mirror it
    pawn.y += 4 # Then we move the center point to 4
    pawn.color = inverse(pawn.color)

Мы поступаем так со всеми пешками (включая короля). Мы отразили положение пешек.

Поскольку мы меняем перспективу доски, меняя позицию пешки, нам также необходимо изменить действие. Нам нужно отразить координаты действия и направление, если действие - движение или атака. Это похоже на изменение положения пешки, мы изменим координаты действия, отразив координаты, манипулируя осью y. Для направления нам нужно только умножить ось Y на -1.

Например:

{} = * means multiplication in this bracket
original = a*2,3
mirror = a*{(2-4)*-1+4},3 = a*6,3
original = m*1,0*1,0
mirror = m*{(1-4)*-1+4,0}*{1*-1},0 = m*7,0*-1,0

Вот так мы меняем точку зрения игрока.

Для реализации см. Все функции, определенные в этом исходном коде:



По сути, это то же самое, что и псевдокод, но в стиле ООП. Мы изменим атрибуты всего объекта пешек. Зеркало действия также определяется в исходном коде.

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

Мы должны определить некоторые идентичные состояния, которые могут быть использованы для ввода нейронной сети, если она есть в игре. Позже его можно использовать для увеличения ввода нейронной сети. Кроме того, в документе идентичное состояние будет использоваться для оценки состояния в листовом узле MCTS, где оно будет равномерно выбрано случайным образом. Идентичные состояния обычно являются двугранным отражением или поворотом исходного состояния. Я думаю, что цель этого компонента - ускорить обучение и убедиться, что в него включено состояние, которое должно иметь такую ​​же ситуацию или оценку.

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

Определить функцию вознаграждения

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

Функция вознаграждения - это функция полезности, которую мы определили в части 2. Мы нормализуем значение до диапазона {-1,1}. Вот реализация высокоуровневого псевдокода:

def reward_function(state, player):
   if state.win(player):
       return 1
   else
       return -1

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

Для реализации вы можете увидеть функцию State.sparse_eval(). способ вызова терминального состояния определен в Части 1.



Архитектура нейронной сети

В этом разделе мы создадим архитектуру нейронной сети, используемой в AlphaZero. В документе они используют 20 остаточных блоков, за которыми следуют заголовок политики и заголовок значения. Они использовали его, потому что это была самая современная архитектура глубокого обучения на тот момент в задачах компьютерного зрения. Конечно, мы этим не воспользуемся. Специально для меня, у кого малый бюджет и минимальные ресурсы для проведения этого эксперимента 😢.

Вместо этого мы будем использовать упрощенную архитектуру. Мы используем архитектуру, определенную в [Источник 2], с некоторыми изменениями. Вот архитектура:

Итак, у нас будет 4 остаточных блока с 2 CNN, за которыми следует заголовок политики и заголовок значения.

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

Вход нейронной сети - это представление состояния, которое мы определили выше.

Есть два выхода нейронной сети: скалярная функция v и вектор вероятностей перемещения p. Диапазон выходных данных нейронной сети составляет {-1,1} для v и {0,1} для p. Вот почему мы используем tanh для функции активации для v и softmax для функции активации для p.

Нейронная сеть минимизирует следующую целевую функцию:

Где vθ(st) - результат заголовка значения, скалярный, который оценивает ситуацию текущего состояния, а pθ(st), результат заголовка политики, - это прогнозируемая политика из состояния st.

vθ(st) будет обучен приближаться к zt, что является окончательным результатом игры для игрока с точки зрения выбранной точки обзора (POV). в нашем случае POV - белый игрок. zt value может быть -1, 0 или 1 в зависимости от результата игры. vθ(st) будет обучен вычислять оценку текущего состояния.

Πt - это оценка политики штата st. Нам также необходимо обучить параметр нейронной сети, чтобы pθ(st) был достаточно близок к πt. pθ(st) будет вектором распределения вероятностей, который говорит нам, что чем выше значение, тем лучше действие и есть высокий шанс быть выбранным. Он будет обучен приближаться к πt. Как получить πt определяется в следующем разделе. Конечно, это также должна быть такая же перспектива выбранной точки обзора.

Оптимизатор использует Adam Optimizer с заданной скоростью обучения.

Таким образом, мы минимизируем ошибку при прогнозировании оценки текущего состояния и политики текущего состояния. Пусть batch_size - это общий экземпляр, который будет входить в нашу нейронную сеть. Форма ввода - (batch_size, 9,9,140) для представления состояния. Есть два выхода: заголовок политики и заголовок значения. Заголовок политики имеет (batch_size, 2998) (общее количество уникальных действий), а заголовок значения имеет форму (batch_size, 1).

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

Для реализации см. Ниже (класс PawnNetZero):



Поиск по дереву Монте-Карло

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

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

Дерево в MCTS будет состоять из узлов, представляющих конфигурацию платы. Направленное ребро существует между каждым узлом и представляет действительное действие состояния. Ребро отличается от Minimax Tree Search не только для сохранения имени действия, у ребра есть несколько параметров, которые будут обновляться при каждой симуляции.

Ребро будет содержать несколько параметров, которые мы будем обновлять:

  1. Q(s,a): ожидаемое вознаграждение или среднее вознаграждение за выполнение действия a в состоянии s, оно будет обновлено на этапе резервного копирования. Это будет среднее значение оценки или вознаграждения для всех прогнозируемых vθ(st), которые производятся нейронной сетью, или фактическое вознаграждение (-1,0,1) в конечном состоянии в листовом узле (который является потомком узла s).
  2. N(s,a): сколько раз симуляция выполняла действие a в состоянии s.
  3. P(s,a): оценка вероятности выполнения действия a в состоянии s, которое является политикой, созданной моделью нейронной сети.

Тогда как узел будет содержать несколько параметров:

  1. N(s): количество раз, когда моделирование принимает это состояние (s). Он равен сумме N(s,a) для всех возможных действий a в состоянии s.

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

После инициализации дерева есть 4 шага для выполнения MCTS в AlphaZero:

  1. Выбирать
  2. Разверните и оцените
  3. Резервное копирование
  4. Играть

Шаг 1–3 повторяется по количеству симуляций, а затем выполняется шаг 4.

Выбирать

Моделирование в MCTS начнется в корневом узле (s0) и закончится, если моделирование встретит листовой узел sL на временном шаге L. На каждом из этих временных шагов для каждого узла, который уже развернут на шаге Expand and Evaluate, действие выбирается в соответствии с параметром на краю каждого узла. Здесь мы выберем действие a в состоянии s, которое имеет наивысший U(s,a), верхний предел достоверности, используя вариант алгоритма PUCT.

где cpuct - гиперпараметр для определения уровня исследования. сумма N(s,b) равна N(s).

Если s - это s0 (корневой узел), P(s,a) изменяется на be P (s, a) = (1 — e)*pa + e*ηa

где η - распределение вероятностей с использованием шума Дирихле с выбранным параметром, а e равно 0,25. Это заставит исследование попробовать все ходы в корневом состоянии.

Этот шаг будет выполняться до тех пор, пока не будет найден листовой узел. Если листовой узел обнаружен, вызывается шаг «Развернуть и оценить».

Разверните и оцените

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

Вход будет преобразован в любое идентичное состояние случайным образом с равномерным распределением вероятностей (он может выбрать неизменное). Поскольку в этой игре его нет, состояние не будет преобразовано, и вход нейронной сети всегда будет одним и тем же. поэтому в реализации EvoPawness (временное имя) вывод function di вернет sL без преобразования формы.

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

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

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

N(sL,a) = 0, Q(sL,a) = 0, N(s) = 0, P = p, P(sL,a) = pa
Where a is a possible action in the state sL.

Резервное копирование

После того, как мы развернем листовой узел (sL), параметр будет обновлен при обратном проходе ко всем родительским узлам до корневого узла, что происходит на каждом этапе t ≤ L. Эти параметры будут обновлены следующим образом:

Q(st,at) = (Q(st,at)* N(st,at) + v)/ (N(st,at) + 1)
N(st,at) = N(st,at) + 1
N(st) = N(st) + 1

Обратите внимание, что v = v * -1, если игрок st отличается от игрока sL. например: ход st’с черный, а ход sL’с белый. Поскольку это игра с нулевой суммой, оценка противоположного игрока (v) будет отрицательной для текущего игрока.

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

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

Играть

В конце поиска пора выбрать действие a в корневой позиции s0 на основе параметра, обновленного при моделировании. Вероятность действия данного корневого состояния (πa|s) выбирается пропорционально экспоненциальному числу посещений N(s,a), подсчитанному при моделировании.

Мы рассчитаем политику всех действий по следующей формуле:

Где τ - температура, которая используется для контроля степени разведки. Когда ход или шаг в игре меньше 30, τ устанавливается на 1, иначе бесконечно мало.

Реализация высокоуровневого псевдокода MCTS выглядит следующим образом:

Реализацию можно найти здесь:



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

Арена

Для поддержания качества модели мы должны убедиться, что используемая модель является лучшей. Для этого AlphaZero сравнит качество текущей лучшей модели и текущей модели. Сделать это довольно просто. Нам нужны два агента, которые будут сражаться друг с другом.

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

Если текущая модель выигрывает с выбранным отрывом (в документе 55%), лучшая модель заменяется текущей моделью. Лучшая модель используется в следующем эпизоде.

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

Мы инициируем 2 MCTS, один с лучшей модельной нейронной сетью, а другой с текущей нейронной сетью. Цвет плеера можно выбрать самостоятельно (например: белый - лучшая модель, а черный - текущая).

Вот псевдокод

Реализацию можно найти здесь (функция fight_agent()):



Вот и все. Мы определили все компоненты, готовые для AlphaZero. Теперь мы подключим все наши определенные компоненты и выполним алгоритм AlphaZero.

Реализация AlphaZero

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

Шаг реализации AlphaZero на основе компонентов, которые мы определили, следующий:

  1. Создавайте все уникальные действия, которые могут быть использованы каждым игроком.
  2. Создайте модель нейронной сети, которая будет использоваться для оценки в MCTS с вводом уникальных сгенерированных действий. Заголовок политики в модели будет корректировать свою форму вывода на сумму уникальных действий.
  3. Создайте данные структуры deque , которые будут использоваться для хранения информации о результате каждого самостоятельного воспроизведения и будут использоваться для ввода нейронной сети. Должна быть определена максимальная длина deque .
  4. Для каждого эпизода мы создаем новые экземпляры MCTS, которые будут использоваться для обучения нашего агента путем самостоятельной игры. Мы увидим эти шаги более подробно ниже.
  5. После завершения самостоятельной игры обучите модель нейронной сети на основе данных, сгенерированных в процессе самостоятельной игры в deque. Общее количество экземпляров в deque ограничено определенной максимальной длиной deque.
  6. После обучения модели мы проверим, лучше ли текущая модель, чем текущая лучшая модель. Если это правда, замените лучшую модель текущей. Лучшая модель будет использована для оценки в следующем эпизоде.

Моделирование за эпизод

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

Во-первых, нам нужно инициировать состояние игры и MCTS. Затем сделайте следующее:

Сначала мы заполняем параметр внутри MCTS (self_play()), затем получаем вероятность действия на корне (play()). Мы заполняем deque действием, состоянием и информацией об игроке. После того, как состояние достигло терминала или максимального шага, мы, наконец, добавляем информацию о награде в deque.

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

Функция self_play - это симулятор MCTS, который действует следующим образом:

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

Вот и все, мы определили, как создать реализацию AlphaZero в игре.

Для реализации вы можете увидеть fit_train() and в train_module.py в репозитории.



Чтобы запустить обучение, используйте main_from_start.py для обучения с самого начала. и main_from_continue.py тренироваться с КПП. А пока я предлагаю вам не пытаться обучать модель, пока я не проведу рефакторинг и не почищу код. Планирую сделать это в следующую субботу.

Ниже приведен код main_from_start.py



Урок выучен

При внедрении AlphaZero я извлек несколько уроков.

  1. Я запустил код для обучения модели. Я понял, что сначала очень сложно получить серию, которая приводит к победе или поражению. Часто это заканчивается ничьей (достигнуто максимальное количество шагов). Я прихожу к выводу, что установленной мной максимальной симуляции недостаточно. Мне нужна симуляция более высокого максимума на MCTS. Я также пробовал другой способ решить эту проблему. Я попытался взломать симуляцию MCTS, позволив агенту всегда атаковать врага. Если вы не понимаете, что такое greed variable внутри MCTS, для 1/8 максимальных эпизодов, которые я установил, и выбранного минимального шага, симуляция всегда будет выполнять действие атаки, а действие продвижения имеет больший Q на верхней границе уверенности, чем другие действия. Это будет отключено при питтинге двух моделей. Мне нужно найти лучший способ решить эту проблему.
  2. Мне нужно реализовать многопоточность для моделирования MCTS. Единственный поток по-прежнему можно использовать, но он очень медленный. Итак, в следующей части я попытаюсь реализовать многопоточный MCTS.
  3. Я не настраивал гиперпараметр нейронной сети и MCTS. Итак, я до сих пор не знаю, сколько остаточных слоев мне следует использовать. В настоящее время я использую 4 остаточных слоя. Не настраивал, потому что тренировки очень медленные 😢.
  4. Обязательно внимательно прочтите статью. Я несколько раз исправлял свой код, потому что пропустил какую-то часть статьи.

Заключение

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

В этой статье для обучения модели по-прежнему используется один графический процессор. Он также использует один поток для моделирования MCTS. Так что тренировка будет очень медленной.

Послесловие

Ого, посмотрите мою статью о времени чтения за 25 минут 😆. Наконец, статья написана и опубликована. Благодаря нескольким статьям, которые я прочитал, я могу поэкспериментировать с алгоритмом AlphaZero и понять его.

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

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

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

О, я обещал подробно рассказать вам о структуре проекта и графическом интерфейсе в последней части. Извините, я забыл это написать 😅. Если будет время, напишу в следующей статье.

В следующих нескольких моих проектах я сосредоточусь на задачах НЛП или компьютерного зрения. Я напишу кое-что об использовании GAN для этих задач. Я хочу изучить GAN и реализовать его, поскольку в настоящее время это горячая тема в глубоком обучении.

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

Увидимся в моей следующей статье!

Серия статей

Часть 1: Создание ИИ для вашей собственной настольной игры с нуля - Подготовка - Часть 1

Часть 2: Создайте ИИ для вашей собственной настольной игры с нуля - Minimax - Часть 2

Часть 3: Создание ИИ для вашей собственной настольной игры с нуля - AlphaZero-Часть 3

Источник и подтверждение





[Источник 2] Дэвид Фостер

[Источник 3] Сильвер, Дэвид и др. «Освоение игры в го без человеческого знания». Природа 550.7676 (2017): 354.

[Источник 4] Сильвер, Дэвид и др. «Освоение шахмат и сёги путем самостоятельной игры с помощью общего алгоритма обучения с подкреплением». Препринт arXiv arXiv: 1712.01815 (2017).

Спасибо, Томас Симонини за предложение перейти от Deep Q Network к обучению на основе политик.