Преобразование обычного дистрибутива в softmax

#python #tensorflow #math #neural-network #softmax

#python #tensorflow #математика #нейронная сеть #softmax

Вопрос:

Я нашел на github хороший пример обучения с подкреплением, который я хотел бы использовать. Моя проблема в том, что результат является уровнем нормального распределения (код ниже), потому что он используется для пространств непрерывных действий, тогда как я хотел бы использовать его для пространств дискретных действий, где модель имеет 4 выхода, и я выбираю один из этих выходов в качестве действия для среды.

В качестве быстрого теста я argmax проверяю выходные данные уровня обычного дистрибутива, а затем повторно запускаю выбранное действие для backprop.

 env_action = np.argmax(action)
action = np.zeros(ppo.a_dim)    # turn action into one-hot representation
action[env_action] = 1 
  

Это работает довольно хорошо, но, очевидно, простое выполнение argmax заставляет агента вести себя жадно и не исследовать.

Итак (и я понимаю, что это очень халтурно), могу ли я сделать это:

 nd_actions =  self.sess.run([self.sample_op], {self.state: state})       
rescale_nd = scale(nd_actions, 0, 1)
probs = tf.nn.softmax(rebase_nd)
action = np.random.choice(4, p=probs.numpy()[0])
  

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

 l1 = tf.layers.dense(self.state, 400, tf.nn.relu, trainable=trainable,
                     kernel_regularizer=w_reg, name="pi_l1")
l2 = tf.layers.dense(l1, 400, tf.nn.relu, trainable=trainable, kernel_regularizer=w_reg, name="pi_l2")
mu = tf.layers.dense(l2, self.a_dim, tf.nn.tanh, trainable=trainable,
                     kernel_regularizer=w_reg, name="pi_mu_out")
log_sigma = tf.get_variable(name="pi_log_sigma_out", shape=self.a_dim, trainable=trainable,
                            initializer=tf.zeros_initializer(), regularizer=w_reg)
norm_dist = tf.distributions.Normal(loc=mu * self.a_bound, scale=tf.exp(log_sigma))
  

Ответ №1:

Я нашел уровень выходного дистрибутива, который предоставляет то, что я ищу, и теперь мне не нужно переписывать огромные куски кода — УРА!

 a_logits = tf.layers.dense(l2, self.a_dim, kernel_regularizer=w_reg, name="pi_logits") 
dist = tf.distributions.Categorical(logits=a_logits)