@PrizmMARgh

Как правильно учить с подкреплением?

Пыталась написать алгоритм для обучения бота, который выбирает лучшее будущее состояние игры и "ходит" в него.
Алгоритм выглядит примерно так:
1. сыграть N партий, ошибаясь с шансом eps.
2. каждую партию, записывать как две последовательности состояний от лица двух игроков т.е. в одной последовательности чётные номера, в другой - нечётные. (конечное состояние "переворачиваю" и кладу в противоположный от списка с обычным конечным состоянием список).
3. для каждого состояния вычисляю соответствующее значение v'[i] = v[i] + alpha*(r[i] + gamma * v[i+1] - v[i]), где v = оценка состояния с помощью встроенного в бота нейронки, а r[i] - награда, соответствующая состоянию.
4. учу нейронку, как обычную feed-forward модель с помощью небольшого (порядка 10) количества итераций градиентного спуска по функции потерь (v - v')^2.
5. очищаю список записей партий.
6. повторяю большое количество раз .

Для игры "ручки" (у тебя есть N ручек, можешь взять 1/2/3 и передать ход сопернику, если возьмёшь последнюю - проиграл) данный алгоритм работал вполне разумно. Но когда я попыталась применить ту же логику для крестиков-ноликов, то ничего не вышло. Пробовала в качестве моделей перцептроны с 2 или 1 скрытыми слоями (на вход всем подаются значения +-1 или 0 в зависимости от клетки) и другие. В качестве нелинейной функции использовала leak relu, который "загнут" в x=+-1, т.к. нейронка должна стремиться выдавать значения +-1, соответственно. Да, спустя действительно огромное количество партий бот начинает сводить в ничью при игре против меня, но он не смог доучиться до состояния, при котором бы 5 партий подряд сыграл бы в ничью.

В чём может быть проблема? В самом алгоритме? В неправильно настроенных параметрах обучения? В архитектуре нейронки?

P.S. использую c++ для всего этого, поэтому лучше приводить в пример псевдокод.
  • Вопрос задан
  • 46 просмотров
Решения вопроса 1
@imageman
1. Функция активации всегда нелинейная (поэтому leak relu должен быть ломаной, не должен быть простой прямой).
2. Активации разных слоев могут быть разными - в скрытых слоях leak relu, в финальном - сигмоида
3. Один скрытый слой мало. Пробуйте 2-3 хотя бы.
4. Пробуйте разные скорости обучения (0,001)
5. Число итераций градиентного спуска может и побольше нужно делать.

А точно всё это нужно самостоятельно писать на C++? Может лучше взять готовые реализации библиотек обучения (PyTorch, tensorflow)? Проект ONNX https://ru.wikipedia.org/wiki/ONNX позволяет экспортировать модели (но сам я пока не попробовал). Так же никто не запрещает из программы на C++ вызывать питоновский скрипт (как внешнюю программу).
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы