2

Я реализую Q-сеть, как описано в Управлении уровня человека, посредством обучения глубокой арматуре (Mnih et al., 2015) в TensorFlow.Внедрение Tensorflow потери Q-сети с нарезкой

Для приближения Q-функции используется нейронная сеть. Q-функция отображает состояние и действие на скалярное значение, известное как Q-значение. То есть это функция типа Q (s, a) = qvalue.

Но вместо того, чтобы принимать как состояние, так и действие в качестве входных данных, они принимают только состояние в качестве входных данных и выводят вектор с одним элементом для каждого юридического действия в заданном порядке. Таким образом, Q (s, a) становится Q '(s) = array([val_a1, val_a2, val_a3,...]), где val_a1 - Q (s, a1).

В связи с этим возникает вопрос о том, как изменить функцию потерь. Функция потерь - это функция потерь L2, вычисленная на разности мишени (y) и Q (s, a).

Моя идея - создать новую операцию TF и ​​использовать двоичную маску, указывающую, какое действие я хочу обучать и умножать на выход сети. Эффективно создавая вектор, такой как [0, 0, val_a3, 0, ...], если данное действие составляет a3.

И затем подайте результат новой операции на операцию потери, которую TF минимизирует.

Вопросы:

  1. Это здравая идея? Или есть лучший способ решить это?

  2. Как это можно решить с помощью TensorFlow?

    Существует нить SO на чем-то подобном (Adjust Single Value within Tensor -- TensorFlow), но я хотел бы выбрать значение столбца с помощью tf.placeholder, который я могу подать в сеть во время выполнения. Кажется, что это не работает, когда просто заменяйте статические списки в этих примерах с помощью заполнителей.

ответ

2

Есть несколько реализаций там делать DeepQ обучения в TensorFlow, которые могли бы быть полезными ссылками, чтобы проверить:

https://github.com/asrivat1/DeepLearningVideoGames

https://github.com/nivwusquorum/tensorflow-deepq

https://github.com/mrkulk/deepQN_tensorflow

Я m не уверен, что лучшая идея не углубляется, но вы можете определенно приложить в маске несколькими способами.

Если у вас есть двоичная маска в качестве булева вектора, например, [Ложных, False, True, False] установить уже, то вы можете сделать:

val_array = ... 
binary_mask = tf.constant([False, False, True, False]) 
result = tf.select(binary_mask, val_array, tf.zeros_like(val_array)) 

Это выбирает запись из val_array везде, где binary_mask является Правда, и нули в противном случае.

Если ваша маска не является логической, но уже является числовым типом того же типа, что и val_array (например, 0.0s и 1.0s), вы можете сделать tf.mul (mask, val_array).

+0

Так что ссылки, которые вы предоставили, это иметь местозаполнитель для действия типа 'action_mask = tf.placeholder (" float ", [None, num_actions])'.И затем они 'masked_action = tf.mul (network_output, action_mask)', за которым следует 'tf.reduce_sum (masked_action, reduction_index = [1,])'. Это кажется хорошей идеей. По крайней мере, из того, что я могу сказать. – Skeppet