您的问题不在于环境是随机的或动态的。实际上,您使用的术语略有错误。这些术语通常不是指起始状态可以不同或目标位置可以逐集移动的事实。它们通常指的是状态转换的行为。
尽管在您的情况下,您可以将初始状态视为随机的,但这并不是什么大问题,也不太可能成为您的问题的原因。
从您的问题来看,在我看来,您还没有真正运行 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 的粗略版本。