当开始或目标状态可以动态变化时,为什么 DQN 不收敛?

人工智能 深度学习 强化学习 Python dqn
2021-10-22 12:24:11

我正在尝试将 DQN 应用于随机环境,但我无法使其收敛。

我在这里发现了一些类似的问题,但还没有解决方案。

我可以很容易地让 DQN 在静态环境中收敛,但是我在没有给出结尾的动态环境中遇到了麻烦。

示例:我制作了一个非常简单的冰冻湖模型(没有任何孔) - 简单地从 A 导航到 B。当 A 和 B 始终相同时,此导航工作正常,但是当我将 A 或 B 的位置打乱每个会话,DQN 都不能正确收敛。

我使用网格(3x3、4x4 大小)作为输入神经元。每个都有“0”值。我分配当前位置“0.5”和结束位置“1”。4x4 网格为我们提供了 16 个输入神经元。3x3 网格示例:

 0.5  0  0 
  0   0  0 
  0   0  1

在这方面我有几个问题:

  • 训练 DQN 时,如何应用 Q 值?(或者我真的需要吗?我不确定如何正确“奖励”网络。此时我没有使用任何对抗网络或目标网络。)

  • 我只使用最后一步的简短回放记忆来训练网络,或者最后 N 个导致成功的动作。这是处理这个问题的正确方法吗?

  • 我使用 Keras,并且只是在网络每次做正确的事情时对其进行训练——而忽略失败的尝试。- 但这是否接近正确的方法?

  • 我还缺少其他东西吗?

也许我应该注意到我的数学能力不是很强,但我尽力了。

任何输入表示赞赏。

1个回答

您的问题不在于环境是随机的或动态的。实际上,您使用的术语略有错误。这些术语通常不是指起始状态可以不同或目标位置可以逐集移动的事实。它们通常指的是状态转换的行为。

尽管在您的情况下,您可以将初始状态视为随机的,但这并不是什么大问题,也不太可能成为您的问题的原因。

从您的问题来看,在我看来,您还没有真正运行 DQN 算法。目前还不是 100% 清楚您的神经网络在预测什么,但我最好的猜测是您有 4 个输出来选择“最佳”动作,并将神经网络视为分类器。由于您如何仅选择“成功”导航,这种训练方法似乎最接近交叉熵方法 (CEM) 。

在训练 DQN 时,我如何应用 Q 值?

这个问题最能说明你没有使用 DQN。这太复杂了,无法在答案中完整描述,但基础是:

  • 您的神经网络 (NN) 应该估计 Q 值。通常在 DQN 中,您输入状态,NN 输出每个动作的 Q 估计值数组(尽管其他架构也是可能的)。这应该是一个回归问题,所以最后一层网络需要是线性的。

  • 当前最佳策略的最佳猜测是向前运行 NN 并找到最大化动作。

  • 在 DQN 中,您还有一个“行为策略”——一个简单而流行的选择是使用ϵ-贪婪的行动选择,这只是意味着采取最大化行动(如上计算),除了概率ϵ(一些小的值,例如 0.1)采取随机行动。

  • 要找出您的训练数据以改进 NN,您需要 Q 值来计算 TD 目标。在单步 Q 学习中,这将是r+γQ(s,a)在哪里r是即时奖励s是下一个看到的状态,并且a是该状态下的最大化动作。你应该强迫Q(s,a)=0(即不使用NN)如果s是一个终端状态。

这意味着您通常需要在内部循环中的 2 或 3 个位置使用 Q 值。在给定当前状态的情况下,您的内部循环每个时间步长应该看起来current_state这样:

# Figure out how to act
current_q_values = NN_predict(current_state)
current_action = argmax(current_q_values)
if random() < epsilon:
  current_action = random_action()

# Take an action
reward, next_state, done = call_environment(current_state, current_action)

# Remember what happened
store_in_replay_memory(current_state, current_action, reward, next_state, done)

# Train the NN from memory
repeat N times: # This can be vectorised for efficiency
  mem_state, mem_action, mem_reward, mem_next_state, mem_done = sample_replay_memory()
  mem_q_values = NN_predict(mem_next_state)
  mem_max_action = argmax(mem_q_values)
  if done:
    td_target = mem_reward
  else
    td_target = mem_reward + gamma * mem_q_values[mem_max_action]
  target_q_values = NN_predict(mem_state)
  target_q_values[mem_action] = td_target
  NN_train(mem_state, target_q_values)

# Maybe end an episode (this can include generating new map)
if done:
  current_state = reset_environment()
else:
  current_state = next_state

您可以在上面看到,NN_predict在略有不同的上下文中调用了三个不同的时间来获取 Q 值。我忽略了额外的东西,例如使用单独的目标网络。

我只使用最后一步的简短回放记忆来训练网络,或者最后 N 个导致成功的动作。这是处理这个问题的正确方法吗?

重要的是包括导致失败的动作,以便 NN 了解差异。通常,您需要一个包含几百到几十万个条目的重放存储器。你可能会因为你的简单问题而逃脱几百。这个想法是使用这个训练数据有点像来自监督学习的数据集。

我使用 Keras,并且只是在网络每次做正确的事情时对其进行训练——而忽略失败的尝试。- 但这是否接近正确的方法?

这不是 DQN 的正确方法,尽管可能被认为是 CEM 的粗略版本。