Обратите внимание, что это дискретное пространство действий - на каждом шаге есть action_space.n
различные возможные действия, и агент выбирает одно.
Для этого MLP возвращает логиты (которые являются функцией вероятностей) различных действий. Это указывается в коде + [act_dim]
, который добавляет счетчик action_space в качестве конечного уровня MLP. Обратите внимание, что последний уровень MLP является выходным уровнем. Входной слой не определен в тензорном потоке, он выводится из входных данных.
tf.random.categorical берет логиты и выбирает из них действие политики pi
, которое возвращается как число.
mlp_categorical_policy
также возвращает logp
, логарифмическая вероятность действия a
(используется для назначения кредита) и logp_pi
, логарифмическая вероятность действия политики pi
.
Похоже, ваш вопрос больше касается возврата из mlp.
mlp создает серию полностью связанных слоев в al oop. На каждой итерации l oop, mlp равен , создавая новый слой, используя предыдущий слой x в качестве входных данных, и назначая его вывод перезаписать x с этой строкой x = tf.layers.dense(inputs=x, units=h, activation=activation)
.
Таким образом, выходные данные не совпадают с входными данными, на каждой итерации x перезаписывается значением нового слоя. Это тот же вид кодирования, что и x = x + 1
, который увеличивает x на 1. Это эффективно объединяет слои в слои.
Вывод tf.layers.dense имеет тензор размера [:,h]
, где :
- размер партии (обычно его можно игнорировать). Создание последнего слоя происходит вне l oop, видно, что число узлов в этом слое равно act_dim (поэтому форма равна [:,3]
). Вы можете проверить форму, выполнив это:
import tensorflow.compat.v1 as tf
import numpy as np
def mlp(x, hidden_sizes=(32,), activation=tf.tanh, output_activation=None):
for h in hidden_sizes[:-1]:
x = tf.layers.dense(x, units=h, activation=activation)
return tf.layers.dense(x, units=hidden_sizes[-1], activation=output_activation)
obs = np.array([[1.0,2.0]])
logits = mlp(obs, [64, 64, 3], tf.nn.relu, None)
print(logits.shape)
результат: TensorShape([1, 3])
Обратите внимание, что наблюдение в этом случае [1.,2.]
, оно вложено в партию размером 1 .