Реализация MADDPG-алгоритма для многоагентного обучения с подкреплением - PullRequest
0 голосов
/ 12 марта 2020

В настоящее время я работаю над многоагентной проблемой обучения с подкреплением для решения проблемы координации. Я пытаюсь реализовать алгоритм MADDPG Р. Лоу. Это расширение обычного подхода Actor-Criti c -Approach для многоагентных сред. Поскольку я использую tenorflow 2.0, я не нашел много примеров по inte rnet, поэтому я начал разрабатывать его сам с нуля.

Прямо сейчас я сталкиваюсь с проблемой, что мой средний критический c убыток и средняя потеря актера скорее взрывается, чем конвертируется, как вы можете видеть на картинке. Для мониторинга я рассчитал среднюю потерю нескольких критиков, а также актеров.

Средний актер и криты c потери за 500 эпизодов

К сожалению, я не совсем уверен, как интерпретировать эти потери. Поскольку потеря должна показывать разницу между прогнозируемым значением и фактическим значением, она должна сходиться к нулю в процессе обучения.

Модель актера определяется следующим образом:

class Actor(tf.keras.Model):
    def __init__(self, state_size, num_actions, learning_rate, num_agents):
        super(Actor, self).__init__()
        self.state_size = state_size
        self.num_actions = num_actions
        self.learning_rate = learning_rate
        self.num_agents = num_agents

        self.obs_input = Input(self.num_agents, name="obs_input", dtype='float64')
        self.h1 = Dense(50, activation='relu', dtype='float64', name='TEST1')
        self.h2 = Dense(20, activation='relu', dtype='float64', name='TEST2')
        self.out = Dense(self.num_actions, activation='linear', name='actor_output', dtype='float64')

        # Create optimizer
        self.opt = tf.optimizers.Adam(learning_rate = self.learning_rate)      

    @tf.function
    def call(self, inputs):
        x = self.h1(inputs)
        x = self.h2(x)
        out = self.out(x)
        return out

Критика c:

class Critic(tf.keras.Model):
    def __init__(self, obs_dim, action_dim, critic_learning_rate, num_agents):
        super(Critic, self).__init__()
        self.obs_dim = obs_dim
        self.action_dim = action_dim
        self.learning_rate = critic_learning_rate
        self.num_agents = num_agents

        self.obs_input = Input(shape=(num_agents, obs_dim), name="obs_input", dtype='float64')
        self.obs_dense = Dense(1, activation='relu', dtype='float64', name="obs_dense")

        self.action_input = Input(shape=(1, action_dim), name="actions_input", dtype='float64')
        self.action_dense = Dense(1, activation='relu', dtype='float64', name="action_dense")

        self.other_action_input = Input(shape=(num_agents-1, action_dim), name="other_actions_input", dtype='float64')
        self.other_action_dense = Dense(1, activation='relu', dtype='float64', name="other_action_dense")

        self.merged_input = Concatenate([self.obs_dense, self.action_dense])
        self.first_dense = Dense(30, activation='relu', dtype='float64')
        self.second_dense = Dense(20, activation='relu', dtype='float64')
        self.flatten = Flatten()
        self.out = Dense(1, activation='linear', name="q_output", dtype='float64')

        self.opt = tf.optimizers.Adam(learning_rate = self.learning_rate)

        self.initialize_trainable_weights()


    @tf.function
    def call(self, obs_inputs, action_inputs, other_action_inputs):
        obs_x = self.obs_dense(obs_inputs)
        act_input = tf.concat([action_inputs, other_action_inputs], axis=1)
        act_x = self.action_dense(act_input)
        x = tf.keras.layers.concatenate([obs_x, act_x])
        x = self.first_dense(x)
        x = self.second_dense(x)
        x = self.flatten(x)
        out = self.out(x)
        return out

Обновление выполняется этой функцией с использованием tf.GradientTape () :

    @tf.function
    def update(self, indiv_reward_batch, indiv_obs_batch, global_state_batch, other_action_inputs, agent_action_inputs, global_next_state_batch, other_next_action_inputs, agent_next_action_inputs, batch_size, all_agents):
        """
        indiv_reward_batch      : only rewards of agent i
        indiv_obs_batch         : only observations of agent i
        global_state_batch      : observations of all agents are concatenated
        global actions_batch    : actions of all agents are concatenated
        global_next_state_batch : observations of all agents are concatenated
        next_global_actions     : actions of all agents are concatenated
        """

        # --------------------- Update Critic ---------------------
        avg_critic_loss = 0
        indiv_reward_batch = tf.cast(indiv_reward_batch, dtype=tf.float64)
        indiv_reward_batch = tf.reshape(indiv_reward_batch, (batch_size, 1))

        with tf.GradientTape() as tape:
            tape.watch(self.critic.trainable_variables)
            current_q = self.critic(global_state_batch, agent_action_inputs, other_action_inputs)
            next_Q = self.critic_target(global_next_state_batch, agent_next_action_inputs, other_next_action_inputs)
            y = indiv_reward_batch + self.gamma * next_Q
            critic_loss = tf.reduce_mean((y - current_q)**2)

        critic_grads = tape.gradient(critic_loss, self.critic.trainable_variables)
        critic_grads_and_vars = zip(critic_grads, self.critic.trainable_variables)
        self.critic.opt.apply_gradients(critic_grads_and_vars)

        avg_critic_loss = critic_loss

        # --------------------- Update Actor ---------------------
        with tf.GradientTape() as tape:
            tape.watch(self.actor.trainable_variables)            
            policy_loss = -tf.reduce_mean(self.critic(global_state_batch, self.actor(indiv_obs_batch), other_action_inputs))

        grads = tape.gradient(policy_loss, self.actor.trainable_variables)
        grads_and_vars = zip(grads, self.actor.trainable_variables)
        self.actor.opt.apply_gradients(grads_and_vars)

Я не привык выполнять обновление градиента вручную, поэтому я не совсем уверен, есть ли ошибка. Глядя на уравнения в MADDPG-Paper, я считаю, что функции потерь правильны.

Я был бы очень признателен, если бы у кого-то было представление, откуда может возникнуть проблема или из каких частей мне следует ближе посмотри на. Если кто-то знает пример реализации MADDPG-алгоритма с использованием TF 2.0, я также был бы очень благодарен (единственные примеры, которые я нашел, когда использовали Pytorch).

Любые идеи приветствуются! :)

Спасибо!

...