但是在训练神经网络来表示映射时,我究竟如何获得训练样本呢?为了更具体,假设状态是一个维向量并且有总共可能的动作,其中是动作空间。s∈Rdd|A|A
您的神经网络训练数据是表示的(可能是特征工程的)状态向量、动作选择以及作为当前策略的最佳估计的动作值。如果您正在使用某种形式的 TD 学习,例如 Q-learning,那么这个最佳估计也称为TD 目标。saQ(s,a)
您的目标策略在 Q 学习中不断变化,因为它取决于当前的 Q 估计。因此,您不能像监督学习训练数据集那样简单地存储一组价值估计以及开始状态和选择的动作。相反,您需要做的是在使用之前计算 TD 目标。这就是贝尔曼方程和更新规则的用武之地。您引用的那些具有内置的所有内容来进行表格更新。TD目标是这部分:
r+γmaxa∈AQ(st+1,a)
这个 TD 目标是神经网络的输出值 ( )。以最简单的形式与该目标相关联的输入 (连接的向量表示。但在实践中,您经常会看到一个仅以状态向量作为输入的函数一次输出所有动作值。yx(s,a)
当你有这种结构时,从经验回放中训练数据的典型循环涉及多次调用神经网络,但不需要你以某种方式从每个状态下的每个可能动作中收集经验。我已对此进行了简化,以避免讨论不必要的细节,因此如果不添加更多循环控制、将学习网络复制到目标网络的选项等,它将无法工作。对于实际示例,您需要取消选择参考 DQN 实现。
# DURING EXPERIENCE GATHERING
# Assume we have a current state value
# This is the greedy action. Exploring not shown
action = np.argmax(learning_nn(state))
next_state, reward, done, info = env.step(action)
store_in_experience_replay(state, action, reward, next_state, done)
# DURING UPDATES
# In real projects, this code will be vectorised to process
# a mini-batch with multiple samples at once.
s, a, r, next_s, done = sample_from_experience_replay()
# This gets the current vals, we're going to modify it later to make the target
q_val_targets = learning_nn(s)
if done:
td_target = r # we're done, so Q(next_s, *) = 0 by definition
else:
td_target = r + gamma * max(target_nn(next_s))
end
# Here's the "trick" to allow us to train from the single
# sample. We assume all the other actions have same prediction as we just
# generated, so their error will be 0
q_val_targets[a] = td_target
# I just made up this syntax, you will probably have a helper function anyway
learning_nn.train_on_batch([s], [q_val_targets])
这不是唯一的方法。您可以将除与 TD 目标相关联的输出之外的所有输出任意设置误差或梯度为零。然而,类似上述代码的内容相对常见,因为 NN 框架将主要支持输入/输出对的训练,而不是在反向传播期间调整内部步骤。