Это шестой выпуск в нашей серии уроков, извлеченных из внедрения AlphaZero. Посмотрите Часть 1, Часть 2, Часть 3, Часть 4 и Часть 5.

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

Обзор

Пока мы внедряли AlphaZero, нам потребовалось некоторое время, чтобы осознать, насколько привередливым может быть алгоритм, потому что даже когда у вас нет всех гиперпараметров, он все равно может учиться, хотя и медленно. Кроме того, существует довольно много гиперпараметров, многие из которых не полностью объяснены в статьях AZ.

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

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

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

Наши улучшения

Прежде чем углубляться в детали каждого из наших улучшений, давайте взглянем на диаграмму, которая обобщает все наши настройки:

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

Циклическая скорость обучения

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

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

По мере развития обучения мы снижали нашу базовую скорость обучения, но обнаружили, что нам не нужно делать это так часто и точно, как без 1 цикла.

C-PUCT

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

Во время наших экспериментов мы пробовали различные значения для C-PUCT, но в конечном итоге обнаружили, что c в диапазоне 3–4 является оптимальным вариантом.

Альфа

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

Ниже представлена ​​диаграмма кривых обучения для различных значений альфа. Мы обнаружили, что в нашем тестировании альфа-версия 1 показала наилучшие результаты.

Усреднение позиции

В какой-то момент во время экспериментов мы начали отслеживать количество уникальных позиций, присутствующих в нашем обучающем наборе, чтобы отслеживать влияние различных параметров исследования AlphaZero. Например, когда C = 1, мы наблюдаем большую избыточность в сгенерированных позициях, что указывает на то, что алгоритм выбирает одни и те же пути с высокой частотой и потенциально недостаточно исследует. При C = 4 количество повторных позиций было меньше. В общем, с Connect Four нет ничего необычного в том, что ~ 30–50% дублированных данных в вашем тренировочном окне.

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

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

Дополнительные фильтры последнего слоя

В статье AlphaZero нейронная сеть принимает входные данные игры, а затем пропускает их через 20 остаточных сверточных слоев. Выходные данные этих остаточных сверточных слоев затем передаются в сверточную политику и заголовок значения, которые имеют 2 и 1 фильтр соответственно.

Первоначально мы реализовали модель и ее головные сети, как описано в статье. Основываясь на результатах исследования Leela Chess, мы увеличили количество фильтров в наших головных сетях до 32, что значительно ускорило обучение.

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

Несколько эпох на поколение

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

Медленное окно

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

Чтобы противодействовать этому, мы реализовали медленно увеличивающееся окно выборки, где размер окна сначала был небольшим, а затем медленно увеличивался по мере увеличения количества генераций модели. Это позволило нам быстро отказаться от очень ранних данных, прежде чем перейти к фиксированному размеру окна. Мы начали с размера окна 4, так что к модели 5 первое (и худшее) поколение данных было прекращено. Затем мы увеличивали размер истории на одну каждые две модели, пока не достигли полных 20 размеров истории моделей в 35 поколении.

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

Собираем все вместе

Итак, насколько быстрее мы сможем учиться со всеми этими настройками? Почти в 4 раза быстрее: раньше для обучения игрока Connect Four требовалось ~ 150 поколений, теперь мы можем обучать ~ 40 поколений моделей.

Для нас это означало сокращение с 77 часов работы графического процессора до 21 часа работы графического процессора. По нашим оценкам, наше первоначальное обучение без улучшений, упомянутых здесь или в предыдущей статье (таких как INT8, параллельное кэширование и т. Д.), Заняло бы более 450 часов графического процессора.

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