Агент Tensorflow, выбирающий случайное действие - PullRequest
3 голосов
/ 25 мая 2019

Я хочу создать агента с помощью tenorflow. У меня есть 9 категорий действий: крен, крен влево, крен вправо, тормоз ... и т. Д. Выход из конвейера тензорного потока - массив [9]. Основываясь на том, что я буду имитировать пуш-комбинацию WSAD. Однако иногда я хочу выбрать случайное действие, но не полностью случайное, а на основе плотного вывода softmax. Функция, которая делает именно то, что я хочу, это numpy.random.multinomial. Однако тензор потока.random.multinomial возвращает только индекс выбранного действия, а не тензор с размерами, аналогичными входным. Я попытался сохранить действия и передать их позже в фазе обучения агенту, однако пример, на котором я основывался, должен был кормить действия во время фазы игры, которую я не хочу. Я знаю, что это возможно с помощью tenorflow.cond и tesorflow.equal, но конвейер будет выглядеть как беспорядок, и я не уверен в производительности. Есть ли другие слова в функции tenorflow, которая ведет себя как numpy.random.multinomial, или есть причина, по которой их нет, а архитектура моего агента неверна?

Сам агент:

 class agentY():
    def __init__(self,lr,s_size,a_size,h_size):
        self.state_in = tf.placeholder(shape = [None]+list(s_size),dtype=tf.float32)
        conv1         = tf.layers.conv2d(self.state_in,32,4,strides=(4, 4))
        max_pool1     = tf.layers.max_pooling2d(conv1,32,4)
        flatten       = tf.layers.flatten(max_pool1)
        hidden        = tf.layers.dense(flatten,4096,activation=tf.nn.tanh)


        hidden_action       = tf.layers.dense(hidden,2048, activation=tf.nn.elu)
        self.action         = tf.layers.dense(hidden_action,9, activation=tf.nn.softmax)

        self.action_in      = tf.placeholder(shape =[None,9],dtype=tf.float32, name='acin') 
        cross_entropy       = tf.nn.softmax_cross_entropy_with_logits_v2(labels=self.action_in,
                                                                  logits=self.action)
        optimizer             = tf.train.AdamOptimizer(lr)
        grads_and_vars = optimizer.compute_gradients(cross_entropy)

        self.gradients = [grad for grad, variable in grads_and_vars]
        self.gradient_placeholders = []
        grads_and_vars_feed = []
        for grad, variable in grads_and_vars:
            gradient_placeholder = tf.placeholder(tf.float32, shape=grad.get_shape())
            self.gradient_placeholders.append(gradient_placeholder)
            grads_and_vars_feed.append((gradient_placeholder, variable))
        self.training_op = optimizer.apply_gradients(grads_and_vars_feed)

Фаза игры:

    state = get_state()
    action = sess.run([myAgent.action], feed_dict={myAgent.state_in:[state]}) #
    action = numpy.random.multinomial(1,action[0][0])
    if do_action:
        releaseKeys();
        update_pressed_keys(categoriesToKeys(action))

    reward = reward + delta_time
    current_rewards.append(reward)
    current_gradients.append(myAgent.gradients)

Фаза обучения:

    def teach_agent(agent, all_rewards, all_gradients,sess):
        rewards = np.array(discount_and_normalize_rewards(all_rewards,0.99))
        test = []
        feed_dict = {}
        for var_index, gradient_placeholder in enumerate(agent.gradient_placeholders):
            mean_gradients = np.mean([reward * all_gradients[game_index][step][var_index]
                                      for game_index, rewards in enumerate(all_rewards)
                                          for step, reward in enumerate(rewards)], axis=0)
            feed_dict[gradient_placeholder] = mean_gradients
        sess.run(agent.training_op, feed_dict=feed_dict)  

Фаза обучения еще не проверена. Этот код основан на книге «Практическое машинное обучение с Scikit-Learn и TensorFlow»

1 Ответ

0 голосов
/ 27 мая 2019

Мне удалось запустить тензор потока.nn.softmax_cross_entropy_with_logits_v2 () с метками и логитами с формой [Нет, 1], где этот тензор является индексом действия (категория). У меня был сбой на стороне графического процессора, и я понял, что все время был неправ, и забыл об одной из самых важных функций: кодировании одним нажатием. Я использовал многочлен для вычисления индекса, а затем один горячий результат. Пример ниже:

import tensorflow as tf
import numpy as np

p = tf.placeholder(shape = [None,4],dtype=tf.float32)
t = tf.nn.softmax(p)
t1      = tf.random.categorical(tf.log(t),1)
t2 = tf.one_hot(t1, 4,
           on_value=1.0, off_value=0.0,
           axis=-1)


with tf.Session() as sess:
    inArray = [[0.8,0.5,0.1,0.2]]
    index, outArray = sess.run([t1,t2],feed_dict={p:inArray})
    print("Index:",index)
    print("Array:",outArray)

Это была, конечно, ошибка новичка, я новичок в ML и с трудом понимал тензорный поток. Теперь агент выглядит так:

class agentY():
    def __init__(self,lr,s_size,a_size,h_size):
        self.state_in = tf.placeholder(shape = [None]+list(s_size),dtype=tf.float32)
        conv1         = tf.layers.conv2d(self.state_in,32,4,strides=(4, 4))
        max_pool1     = tf.layers.max_pooling2d(conv1,32,4)
        flatten       = tf.layers.flatten(max_pool1)
        hidden        = tf.layers.dense(flatten,4096,activation=tf.nn.tanh)


        hidden_action       = tf.layers.dense(hidden,2048, activation=tf.nn.elu)
        self.action_logits  = tf.layers.dense(hidden_action,9, activation=tf.nn.softmax)
        self.action_out     = tf.one_hot(tf.multinomial(self.action_logits,1), 9,on_value=1.0, off_value=0.0,axis=-1)
        cross_entropy       = tf.nn.softmax_cross_entropy_with_logits_v2(labels=self.action_out,
                                                                  logits=self.action_logits)
        optimizer             = tf.train.AdamOptimizer(lr)
        grads_and_vars = optimizer.compute_gradients(cross_entropy)

        self.gradients = [grad for grad, variable in grads_and_vars]
        self.gradient_placeholders = []
        grads_and_vars_feed = []
        for grad, variable in grads_and_vars:
            gradient_placeholder = tf.placeholder(tf.float32, shape=grad.get_shape())
            self.gradient_placeholders.append(gradient_placeholder)
            grads_and_vars_feed.append((gradient_placeholder, variable))
        self.training_op = optimizer.apply_gradients(grads_and_vars_feed)

tf.reset_default_graph()
testAgent = agentY(0.1,(300,400,1),9,11) 

Проблема сейчас в том, что Iam собирает градиенты при каждом решении Агента. Это занимает огромное количество оперативной памяти, и я уверен, что не рекомендуется. Посмотрите ниже:

while True:
    time0 = time.time()
    #-----------------zzx
    if collectData:
        state = get_state()
        action_out, gradients = sess.run([myAgent.action_out,myAgent.gradients], feed_dict={myAgent.state_in:[state]})

        if do_action:
            releaseKeys();
            update_pressed_keys(categoriesToKeys(action))

        reward = reward + delta_time
        current_rewards.append(reward)
        current_gradients.append(gradients)

Позже я буду использовать эти градиенты в функции teach_agent (), чтобы ввести вознаграждение в сеть Агента. (teach_agent опубликован в оригинальном сообщении) Прежде чем я вернусь к книге и попытаюсь понять следующий пример агента Q-Learning, может ли кто-нибудь (если это возможно) легко объяснить другой способ Q-Learning или Reinforce Learning?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...