В моем предыдущем посте Балансировка полюсов тележки с помощью Q-Learning я дискретизировал пространство состояний на несколько сегментов, чтобы построить Q-таблицу. Здесь я заменил его нейронной сетью под названием Q-network.

Созданная мной Q-сеть имеет три полностью связанных скрытых слоя (я не рисовал соединения на диаграмме ниже). Входными данными в сеть являются четыре переменные состояния: положение (x), скорость (x_dot), угол (theta) и угловая скорость. (theta_dot). Выходы - это значения Q двух возможных действий: движение влево или движение вправо.

После обучения Q-сеть делает то же самое, что и Q-таблица. Он сообщает вам значение Q для каждого действия с учетом состояния.

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

Q'(state, action) = reward + DISCOUNT_FACTOR * max(Q(next_state))

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

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

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

С трехуровневой Q-сетью для решения проблемы потребовалось всего 493 эпизода! Для такой простой задачи, как Cart-Pole, метод Q-table определенно оказался быстрее. Однако метод Q-сети может решить гораздо более сложные проблемы!

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

Вот код этой реализации: