A3C 策略只选择一个动作,不管输入状态

A3C policy only selects a single action, no matter the input state

我正在尝试创建一个使用 A3C(异步优势演员评论家)的强化学习代理,使 黄色 代理球体到达 red立方体的环境如下图:

状态space由代理和立方体的坐标组成。代理可用的操作是向上、向下、向左或向右移动到下一个方块。这是一个离散的动作 space。当我 运行 我的 A3C 算法时,它似乎过早地收敛并选择一个主要优于其他动作的动作,无论代理观察到什么状态。例如,我第一次训练它时,它可以选择向左走,即使立方体在智能体的右侧。另一次我训练它时,它可以选择主要向上,即使目标低于它。

奖励功能非常简单。智能体收到负奖励,负奖励的大小取决于它与立方体的距离。代理离立方体越近,它的负奖励越低。当智能体非常靠近立方体时,它会获得很大的正奖励,并且情节终止。我的代理接受了超过 1000 集的训练,每集 200 步。有多个环境同时执​​行训练,如 A3C 中所述。

神经网络如下:

dense1 = layers.Dense(64, activation='relu')
batchNorm1 = layers.BatchNormalization()
dense2 = layers.Dense(64, activation='relu')
batchNorm2 = layers.BatchNormalization()
dense3 = layers.Dense(64, activation='relu')
batchNorm3 = layers.BatchNormalization()
dense4 = layers.Dense(64, activation='relu')
batchNorm4 = layers.BatchNormalization()
policy_logits = layers.Dense(self.actionCount, activation="softmax")
values = layers.Dense(1, activation="linear")

我正在使用 Adam 优化器,学习率为 0.0001,gamme 设置为 0.99。

如何防止我的代理每次都选择相同的操作,即使状态已更改?这是一个探索问题,还是我的奖励函数有问题?

好的,我发现我哪里出错了。 Logits 是 softmax 的输入,而不是输出。我需要删除策略 logits 和值层中的激活,并在损失函数中以不同方式处理 softmax:

def _compute_loss(self, lastTransition, memory, discountFactor):
    # If this is the terminal state
    if lastTransition.terminalState == 1:
        rewardSum = 0.
    else:
        # networkOutput = self.localModel.get_prediction(tf.convert_to_tensor(np.array([lastTransition.newState])))
        networkOutput = self.localModel(tf.convert_to_tensor([lastTransition.newState], dtype=tf.float32))
        rewardSum = networkOutput[1].numpy()[0][0]

    discountedRewards = []
    # rewards = [transition.reward for transition in memory.buffer][::-1]
    for reward in memory.rewards[::-1]:
        rewardSum = reward + (discountFactor * rewardSum)
        discountedRewards.append(rewardSum)

    discountedRewards.reverse()

    # Compute the nn output over the whole batch/episode
    networkOutput = self.localModel(tf.convert_to_tensor(np.vstack(memory.initialStates), dtype=tf.float32))

    # Calculate the value loss
    advantage = tf.convert_to_tensor(discountedRewards, dtype=tf.float32) - networkOutput[1]
    valueLoss = advantage ** 2

    # Calculate the policy loss
    oheAction = tf.one_hot(memory.actions, self.actionCount, dtype=tf.float32)

    # Adding entropy to the loss function discourages premature convergence
    policy = tf.nn.softmax(networkOutput[0])
    entropy = tf.reduce_sum(policy * tf.math.log(networkOutput[0] + 1e-20), axis=1)

    policyLoss = tf.compat.v1.nn.softmax_cross_entropy_with_logits_v2(labels=oheAction, logits=networkOutput[0])
    policyLoss = policyLoss * tf.stop_gradient(advantage)
    policyLoss = policyLoss - 0.01 * entropy

    totalLoss = tf.reduce_mean((0.5 * valueLoss) + policyLoss)
    return totalLoss