如何在强化学习中形成深度 Q 网络的训练样例?

数据挖掘 强化学习 q学习 dqn 开放式健身房
2022-02-28 21:26:28

尝试通过自学一些博客和文本来学习强化学习的基础知识。如果这个问题太基本并且我理解的不同部分有点混乱,请原谅我,但即使在查阅了一些参考资料之后,我也无法真正了解使用神经网络进行深度 Q 学习的工作原理。

我像这样理解贝尔曼方程

Vπ(s)=R(s,π(s))+γsP(s|s,π(s))Vπ(s)

以及Q表的更新规则。

Qn+1(st,at)=Qn(st,at)+α(r+γmaxaAQ(st+1,a)Qn(st,at))

但是在训练神经网络来表示映射时,我究竟如何获得训练样本呢?为了更具体,假设状态是一个维向量并且有总共可能的动作,其中是动作空间。sRdd|A|A

从一些读数中,我了解到神经网络将有个输入神经元,输出神经元和中间的隐藏层。在足够数量的 epoch 之后,任何的前向传递都会为输出层的不同动作生成值。那么对于这个网络,监督学习的训练数据应该具有的形状,其中是训练样本的数量。d|A|sRdQN×(d+|A|)N

现在假设我正在使用gym库中的环境。根据他们的文档,这就是你如何对环境采取行动,以获得新的状态、奖励和其他信息。

state, reward, done, info = env.step(action)

那么如何从上面的代码行生成个训练样本呢?即使我执行次,它也会给我这些动作的单步奖励,而不是考虑折扣未来奖励N×(d+|A|)NQ

1个回答

但是在训练神经网络来表示映射时,我究竟如何获得训练样本呢?为了更具体,假设状态是一个维向量并且有总共可能的动作,其中是动作空间。sRdd|A|A

您的神经网络训练数据是表示的(可能是特征工程的)状态向量、动作选择以及作为当前策略的最佳估计的动作值。如果您正在使用某种形式的 TD 学习,例如 Q-learning,那么这个最佳估计也称为TD 目标saQ(s,a)

您的目标策略在 Q 学习中不断变化,因为它取决于当前的 Q 估计。因此,您不能像监督学习训练数据集那样简单地存储一组价值估计以及开始状态和选择的动作。相反,您需要做的是在使用之前计算 TD 目标。这就是贝尔曼方程和更新规则的用武之地。您引用的那些具有内置的所有内容来进行表格更新。TD目标是这部分:

r+γmaxaAQ(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 框架将主要支持输入/输出对的训练,而不是在反向传播期间调整内部步骤。