1 DQN 的简单原理

近来我一直在研究强化学习,特别而言,是 DQN 方面的内容。原理方面倒是不复杂,其核心是下面的迭代方程

Sutton 的书 6.5 章节: Q-Learning: 离散策略TD控制

平稳状态下,箭头变成等于号,因此

其中除了 之外的其他变量就构成了一个 Trajectory ()。而 则是我们需要学习的深度模型参数。

2 代码体现

我用了 Tensorflow 的团队出的 tf_agent 这个库来进行 DQN 的模型学习。这里涉及的一个核心类是 DqnAgent。DQN 的核心训练过程实现在 _loss 函数中。

注意 _train 函数只是对 _loss 构建起来的损失函数利用 Tensorflow 的 API 来进行梯度计算而已。关注 DQN 模型需要查看 _loss 函数。

3 理论分析

3.1 场景描述

我在着手研究我的复杂场景的之前我首先针对一个非常简单的问题进行研究。这个简单问题是这样的:假设有 12 个通信节点,有 12 个信道可供选择。初始时刻每个节点的初始选择都是 0。我们定义一个全局的资源调度者,它使用一个 Agent 逐个对每个节点进行信道选择。Agent 观察到的状态包括当前节点的 ID,以及其他所有节点的信道占用状态。那么初始状态下,Agent 看到的状态是:

1
0 | 0 0 0 0 0 0 0 0 0 0 0 0

若 Agent 决定分配信道 5 给节点 0,那么下一个时刻 Agent 观察到的状态变成了

1
1 | 5 0 0 0 0 0 0 0 0 0 0 0

效用的定义也非常简单,如果在某一个步骤 Agent 选择的信道不和别的节点冲突,那么获得效用 16,否则获得 0 效用。显然,若节点做出了

1
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 0

的决策顺序,Agent 可以在一个轮次里面拿到 的最大效用。在每个 Episode 中,我们固定运行两个轮次,那么理论上每个 Episode 得到的最大效用应该是 。然而在实际仿真中,模型能够收敛到的水平远远低于这个数字。

3.2 收敛问题

下图展示了在一次训练过程中的总效用变化(没有进行 Discount)

图 1: 左图是平均 Return,右图则是最大 Return。
图 2: 误差曲线

进一步查看 Debug 信息(通过在构建 DqnAgent 时传入 debug_summaries=True 可以在输出的 Tensorboard 数据中显示调试信息)

图 3: (a) diff_q_values (q_values - next_q_values),(b) next_q_values(\max_a Q^*(S_{t+1}, a)),(c) q_values (Q(S_t, A_t)), (d) td_error(R_{t+1} + \gamma \max_a Q^*(S_{t+1}, a) - Q(S_t, A_t)), (e) td_loss

由于 DQN 是 Off-Policy 的,这里的 表示 Model,而 表示 Target Model

观察上面的图分析可以看到,尽管误差还比较高,但是实际上 td_error 已经在 0 左右徘徊了。不过波动范围比较大。另一个比较重要的发现是,图 3 (a)中的 有逐渐扩大的趋势,这意味着模型不稳定了。

3.3 理论 Return

假设每个 Episode 的长度是无限的,那么对于一个理想策略 (即每一步都能拿到 16),其在任何状态下的理论 Return 值都应该是

,那么任意状态的理论 Return 值都应该是 ,也即 。这里 代表了最优 Action。类似的,

事实上,由于 DQN 模型看到的只是的 组成的 Trajectory,由于外部规则导致的 Step 数量限制对于 Agent 来说是完全无感的。这里的分析对于是否存在 Episode 内部的步骤数量限制的情况都是适用的。