Рубрики
Без рубрики

Tic-Tac-Toe с нейронной сетью

Давайте тренируем игроку Tic-Tac-Toe с нейронной сетью с помощью укрепления укрепления, используя Pytorch. Теги с тиктадой, NeuralnetWorks, Pytorch, Python.

TIC-TAC-TOE (4 части серии)

В Tic-Tac-Toe с табличным Q-обучением мы разработали агент Tic-Tac-Toe с использованием обучения подкрепления. Мы использовали таблицу, чтобы назначить значение Q для каждого перемещения из заданного положения. Обучающие игры использовались для постепенного подталкивания этих q-значений в направлении, которое произвело лучшие результаты: хорошие результаты вытащили значения Q для действий, которые привели к тем результатам выше, в то время как плохие результаты нажимают их ниже. В этой статье вместо использования таблиц мы применяем такую же идею подкрепления укрепления к нейронным сетям.

Нейронная сеть как функция

Мы можем подумать о Q-Table в качестве многомерной функции: вход представляет собой заданное положение TIC-TAC-тона, а выход – это список q-значений, соответствующих каждому переходу из этого положения. Мы постараемся преподавать нейронную сеть к приближению этой функции.

Для ввода в нашу сеть мы высказываем позицию доски в массив 9 Значения: 1 представляет Икс , -1 представляет О и 0 является пустой ячейкой. Выходной слой будет массивом 9 Значения, представляющие значение Q для каждого возможного движения: низкое значение, ближе к 0 это плохо, и более высокая ценность ближе к 1 хорошо. После тренировки сеть выберет шаг, соответствующий наибольшему выходу от этой модели.

Диаграмма ниже показывает вход и вывод для заданного положения после тренировки (изначально все значения зависят от 0,5 ):

Как мы видим, выигрышный ход для Х , A2 имеет наибольшее значение Q, 0,998 И нелегальные движения имеют очень низкие значения Q. Q-значения для других юридических ходов больше нелегальных, но меньше, чем выигрышный ход. Это то, что мы хотим.

Модель

Сеть (с помощью Pytorch) имеет следующую структуру:

class TicTacNet(nn.Module):
    def __init__(self):
        super().__init__()
        self.dl1 = nn.Linear(9, 36)
        self.dl2 = nn.Linear(36, 36)
        self.output_layer = nn.Linear(36, 9)

    def forward(self, x):
        x = self.dl1(x)
        x = torch.relu(x)

        x = self.dl2(x)
        x = torch.relu(x)

        x = self.output_layer(x)
        x = torch.sigmoid(x)
        return x

9 Входные значения, которые представляют положение текущей платы, пропускаются через две плотные скрытые слои 36 Нейроны каждый, затем на выходной слой, который состоит из 9 значения, которые соответствуют ценному Q-значение для данного движения

Обучение

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

Код ниже, от qneural.py , показывает, как параметры сети обновляются для одной тренировки:

def update_training_gameover(net_context, move_history, q_learning_player,
                             final_board, discount_factor):
    game_result_reward = get_game_result_value(q_learning_player, final_board)

    # move history is in reverse-chronological order - last to first
    next_position, move_index = move_history[0]

    backpropagate(net_context, next_position, move_index, game_result_reward)

    for (position, move_index) in list(move_history)[1:]:
        next_q_values = get_q_values(next_position, net_context.target_net)
        qv = torch.max(next_q_values).item()

        backpropagate(net_context, position, move_index, discount_factor * qv)

        next_position = position

    net_context.target_net.load_state_dict(net_context.policy_net.state_dict())


def backpropagate(net_context, position, move_index, target_value):
    net_context.optimizer.zero_grad()
    output = net_context.policy_net(convert_to_tensor(position))

    target = output.clone().detach()
    target[move_index] = target_value
    illegal_move_indexes = position.get_illegal_move_indexes()
    for mi in illegal_move_indexes:
        target[mi] = LOSS_VALUE

    loss = net_context.loss_function(output, target)
    loss.backward()
    net_context.optimizer.step()

Мы поддерживаем две сети, политику сети ( Policy_net ) и целевая сеть ( target_net ). Мы выполняем обратную обработку в сети политики, но получаем максимальное значение Q для следующего состояния из целевой сети. Таким образом, значения Q, полученные из целевой сети, не меняются в ходе тренировки для одной игры. Как только мы завершим обучение для игры, мы обновляем целевую сеть с параметрами политики сети ( load_state_dict ).

move_history Содержит переходы агента Q-обучения для одной тренировки за раз. Для последнего шага играют агентом Q-Surlection, мы обновляем выбранный вами ход с вознагражденной стоимостью для этой игры – 0 для потери и 1 для победы или ничьей. Затем мы проходим через оставшиеся движения в истории игры в обратном хронологическом порядке. Мы передаем значение Q для перемещения, которое было воспроизведено в направлении максимального значения Q из следующего состояния (следующее состояние является государством, которое является результатом действия, предпринятых в текущем состоянии).

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

Результаты

Результаты сопоставимы с табличным агентом по изучению Q. В следующей таблице (основана на 1000 Игры в каждом случае) является представителем результатов, полученных после типичного тренировочного прогона:

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

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

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

Наша сеть предлагает то же самое награду за победу, что и для ничьей. Я попытался дать меньшую награду за розыгрыш, чем победа, но даже снижение ценности для розыгрыша к чему-то вроде 0,95 кажется, уменьшает стабильность сети. В частности, играя как Х Сеть может в конечном итоге потерять значительное количество игр против рандомизированного агента MiniMax. Делать награду за победу и нарисовать то же самое, кажется, решает эту проблему.

Несмотря на то, что мы даем то же награду за победу и ничье, агент, похоже, делает хорошую работу победителей игр. Я верю, что это потому, что выиграть игру обычно заканчивается рано, прежде чем все 9 Клетки на доске были заполнены. Это означает, что здесь меньше разбавления вознаграждения, возвращающиеся через каждый шаг истории игры (та же идея применяется к потерям и незаконным ходам). С другой стороны, ничья требует (по определению) все 9 Движения, которые должны быть воспроизведены, что означает, что награды за ходы в данной игре, ведущей к нитям, более разбавлены, поскольку мы идем от одного перехода к предыдущему, играющему агентом Q-Sucess. Поэтому, если данный ход последовательно приводит к победе раньше, у него все еще будет иметь преимущество перед шагом, который в конечном итоге приводит к нисули.

Топология сети и гиперпараметры

Как упоминалось ранее, эта модель имеет два скрытых плотных слоя 36 нейроны каждая. MSELOSS используется в качестве функции потери и скорость обучения – 0,1 Отказ RELU используется в качестве функции активации для скрытых слоев. Сигмоид используется в качестве активации для выходного слоя, чтобы выжать результаты в диапазон между 0 и 1 Отказ

Учитывая простоту сети, этот дизайн может показаться самоочевидной. Тем не менее, даже для этого простого тематического исследования, настройка этой сети была довольно много времени. Сначала я пытался использовать Тан (гиперболический касательный) для выходного слоя – именно у меня смысл установить -1 как ценность для потери и 1 как ценность для победы. Однако я не смог получить стабильные результаты с этой функцией активации. В конце концов, после попытки нескольких других идей я заменил его с Сигмоид , который произвел гораздо лучшие результаты. Точно так же замена RELU С чем-то еще в скрытых слоях сделали результаты хуже.

Я также попробовал несколько разных топологий сети, с комбинациями одного, двух или трех скрытых слоев и используя комбинации 9 , 18 , 27 и 36 Нейроны на скрытый слой. Наконец, я экспериментировал с количеством тренировок, начиная с 100 000 и постепенно увеличивать это число для 2 000 000 , кажется, производит самые стабильные результаты.

Кандидат

Эта реализация вдохновлена архитектурой DQN Deepmind (см. Оборудование для управления уровнем человека благодаря глубокому обучению ), но это не совсем одинаково. DeepMind использовал сверточную сеть, которая предприняла прямые изображения в качестве ввода. Здесь я почувствовал, что целью состояла в том, чтобы научить сети основную логику TIC-TAC-TAC, поэтому я решил, что упрощение представительства имело смысл. Удаление необходимости обработки ввода в качестве изображения также означало меньше слоев (без слоев для идентификации визуальных особенностей доски), которые сосредоточены.

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

Можем ли мы вызвать эту реализацию Tic-Tac-Tac-Toe «глубокое» обучение? Я думаю, что этот термин обычно зарезервирован для сетей с не менее трех скрытых слоев, так что, вероятно, нет. Я считаю, что увеличение количества слоев имеет тенденцию быть более ценным с сверточными сетями, где мы можем более четко понимать это как процесс, в котором каждый слой дополнительно тесно, что характеристики, идентифицированные в предыдущем слое, и где количество параметров уменьшается по сравнению с плотные слои. В любом случае, добавление слоев – это то, что мы должны делать только, если он производит лучшие результаты.

Код

Полный код доступен на Github ( qneural.py и main_qneural.py ):

NestedSoftware/Tictac.

Экспериментируя с различными методами для игры Tic-Tac-Toe

Демо-проект для разных подходов для игры TIC-TAC-TOE.

Код требует python 3, numpy и ptest. Для реализации нейронной сети/DQN (QNeural.py) требуется pytorch.

Создать виртуальную среду с использованием Pipenv:

  • Pipenv --site-packages

Установить с помощью Pipenv:

  • Pipenv Shell.
  • Pipenv Установить --dev.

Установить Пифит к главному каталогу проекта:

  • В Windows Run путь
  • В Bash Run Исходный путь .sh.

Пробеги тесты и демонстрация:

  • Пробеги тесты: питиш
  • Запустите демонстрацию: python -m tictac.main.
  • Запустите Neural Net Demo: Python -m. tictac.main_qneural.

Последние результаты:

C:\Dev\python\tictac>python -m tictac.main
Playing random vs random
-------------------------
x wins: 60.10%
o wins: 28.90%
draw  : 11.00%
Playing minimax not random vs minimax random
---------------------------------------------
x wins: 0.00%
o wins: 0.00%
draw  : 100.00%

Playing minimax random vs minimax not random:
---------------------------------------------
x wins: 0.00%
o wins: 0.00%
draw  : 100.00%

Playing minimax not random vs minimax not random:
-------------------------------------------------
x wins: 0.00%
o wins: 0.00%
draw  : 100.00%

Playing minimax random vs minimax random:

Связанный

  • Tic-Tac-Toe с табличным Q-обучением
  • Грунтовка нейронных сетей
  • Распознавание изображения Pytorch с плотной сетью

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

TIC-TAC-TOE (4 части серии)

Оригинал: “https://dev.to/nestedsoftware/tic-tac-toe-with-a-neural-network-1fjn”