A3C 策略只选择单个动作,无论输入状态如何

Posted

技术标签:

【中文标题】A3C 策略只选择单个动作,无论输入状态如何【英文标题】:A3C policy only selects a single action, no matter the input state 【发布时间】:2021-10-10 22:49:13 【问题描述】:

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

状态空间由代理和立方体的坐标组成。代理可用的动作是向上、向下、向左或向右移动到下一个方块。这是一个离散的动作空间。当我运行我的 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,游戏设置为 0.99。

如何防止我的代理每次都选择相同的操作,即使状态发生了变化?这是一个探索问题,还是我的奖励功能有问题?

【问题讨论】:

【参考方案1】:

好的,我找到了错误的地方。 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

【讨论】:

以上是关于A3C 策略只选择单个动作,无论输入状态如何的主要内容,如果未能解决你的问题,请参考以下文章

Vuex动作和对话窗口

强化学习——代理如何知道选择哪个动作?

如何将情节提要中的多个按钮连接到单个动作?

状态流程图和 C 动作语言。设置数组值以在单个步骤中输出一个向量

Policy-Based Method RL

Policy-Based Method RL