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
我正在尝试创建一个使用 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