Среднее вознаграждение в алгоритме актера-критика за то, что картпол не улучшается

#python #machine-learning #reinforcement-learning #openai-gym #policy-gradient-descent

Вопрос:

Я пытался внедрить актера-критика для Cartpole env в тренажерном зале. Я успешно реализовал градиент политики для того же env. Поэтому была обновлена только актерская часть. Но алгоритм, похоже, не работает, так как среднее вознаграждение не улучшается.

Я несколько раз пытался настроить параметры сети, чтобы улучшить функции потерь, но, похоже, ничего не работает. Ниже приведен мой код.

Код для сетей актеров и критиков

 class Actor(Model):

    def __init__(self, output_shape):
        super(Actor,self).__init__()
        self.layer1 = Dense(32, activation='relu', name='layer1')
        self.layer2 = Dense(16, activation='relu', name='layer2')
        self.layer3 = Dense(16, activation='relu', name='layer3')
        self.layer4 = Dense(output_shape, activation='softmax', name='layer4')

    def call(self, input_data):
        input_data = tf.convert_to_tensor(input_data)
        input_data= tf.reshape(input_data, shape=(1,input_data.shape[0]))

        output = self.layer1(input_data)
        output = self.layer2(output)
        output = self.layer3(output)
        output = self.layer4(output)
        return output

class Critic(Model):

    def __init__(self):
        super(Critic,self).__init__()
        self.layer1 = Dense(16, activation='relu', name='layer1')
        self.layer2 = Dense(16, activation='relu', name='layer2')
        self.layer3 = Dense(16, activation='relu', name='layer3')
        self.layer4 = Dense(1, activation='relu', name='layer4')

    def call(self, state):
        input_data = tf.convert_to_tensor(state)
        input_data= tf.reshape(input_data, shape=(1,input_data.shape[0]))

        output = self.layer1(input_data)
        output = self.layer2(output)
        output = self.layer3(output)
        output = self.layer4(output)
        return output
 

Я обновляю сети, как показано ниже:

 def loss_function_policy(prob, action, q_value):
    selected_probs = tf.math.log((tf.reduce_sum(prob * tf.one_hot(action, num_actions),keepdims=[1])))
    cost = -tf.reduce_sum(q_value * selected_probs)
    return cost

def update_policy(policy, Q, state, action):
    opt = tf.keras.optimizers.Adam(learning_rate=0.0001, 
                                    beta_1=0.8,
                                    beta_2=0.999,
                                    epsilon=1e-05,
                                    amsgrad=True,)
    step_loss = []
    with tf.GradientTape() as tape:
        prob = policy(state)
        q_value = Q(state)
        loss = loss_function_policy(prob, action, q_value)
        step_loss.append(loss)
        gradients = tape.gradient(loss, policy.trainable_variables)

    opt.apply_gradients(zip(gradients, policy.trainable_variables))
    step_policy_loss.append(np.sum(step_loss))
    


def update_Q(Q,td_error, state, action): # td error = reward   gamma*Q(s') - Q(s)
    # Optimizer
    opt = tf.keras.optimizers.Adam(learning_rate=0.0003, 
                                    beta_1=0.9,
                                    beta_2=0.999,
                                    epsilon=1e-07,
                                    amsgrad=True,)

    step_loss = []
    with tf.GradientTape() as tape:
        q_value = Q(state)
        loss = -tf.reduce_sum(q_value * td_error)
        step_loss.append(loss)
        gradients = tape.gradient(loss, Q.trainable_variables)

    opt.apply_gradients(zip(gradients, Q.trainable_variables))
    step_q_loss.append(np.sum(step_loss))
    
 

Остальное-тот же стандартный код RL. Тем не менее, я также прилагаю весь код.
Пожалуйста, разберитесь в этом и помогите понять, где я ошибаюсь.

Ссылка для кода