看这篇文章之前,建议先了解一下:Q-Learning 算法。
1. 算法介绍
DQN 算法全称为 Deep Q-Network,即深度Q网络。它将 Q-Learning 与 Deep Learning 结合在了一起。
1.1 Q-Network
Q-Learning 是使用 Q-table 才存储决策信息的,那么这就要求 state、action 必须是离散的。但是大部分情况,state 和 action 并不离散,或者不方便例举出所有的可能性。比如说用来打游戏,这时 Q-Learning 就无法使用。
为了应对 state 和 action 是连续的情况,我们可以使用 Q 函数来替代 Q-table,Q 函数依然可以记为 Q(s,a),这样对于任意的 state 和 action,只需要通过函数计算我们就可以得到其所对应的 Q-value 了。
但是强化学习可应用的情况可能非常复杂,比如打游戏,我们知道当前的所有敌人的情况 state 和我们下一步想做的操作 action,我们也是没办法设想一个合理的函数来作为 Q-value 的。
神经网络只要构建的足够大,理论上可以模拟任何函数,那么我们就可以使用神经网络来充当 Q 函数。w是神经网络的参数,那么我们的 Q 函数可以记为 Q(s,a;w)。这个网络也就被成为 Q-Network。
1.2 网络的输入与输出
神经网络的输入输出是什么呢?
输入肯定就是状态的每一项。输出可以有两种选择。一种是让网络输出当前 state 对应每一种 action 的 Q-value,另一种是直接让网络输出最优 action。
两种各有优劣。对第一种来说,由于我们是替代 Q-table 的,那么如果网络输出是 Q-value,我们就可以使用 Q-Learning 或 SARSA 所使用的 Q-value 更新策略来更新网络。但是这样我们就需要列举出所有可行的 action,这样 action 仍需要是离散的,那么之前所说的使用 Q-Network 的初衷就有一部分没能得到满足。相比之下,第二种就允许 action 是连续的,但也就不方便使用 TD 策略来更新网络。
1.3 参数更新
一般我们可以选择第一种方式,因为方便设计网络更新算法。如果我们选择第一种方式的话,如何更新网络呢?
- 首先需要前向传播,得到每个可行的 action 对应的 Q-value,获得一个输出 a = argmax(Q(s,a;w)),同时我们可以观察到下一个 s’,并获得奖励 r。
- 计算 TD Target:y = r + γ max{Q(s’,a’;w)};
- 计算损失函数:loss = 1/2[y - Q(s,a;w)]^2。
这样我们就得到了损失函数,然后就可以使用梯度下降来更新网络中的参数w。
2. 优化
2.1 目标网络
训练过程中将网络复制为两部分 netA 和 netB。每一次训练过程,使用 netA 去做决策,只更新 netB 的参数。等到一轮训练完毕后,将 netB 的参数复制给 netA。
称 netA 为目标网络(target network),在每一轮训练过程中,它的参数是固定死的。
2.2 探索
如果一开始,某个 action 得到了正向的奖励,那么后面就可能会一直采取这个 action。但其实可能别的 action 会比这个要好很多。为了不会陷入局部优化,算法需要具有一定的探索性。
常用的解决方法有两种:ε 贪心(epsilon greedy)和玻尔兹曼探索(Boltzmann exploration)。ε 贪心更常用。
-
ε 贪心
其中 ε 为探索率,其值为 0-1 之间。算法会以 ε 的概率选择随机 action,以 1-ε 的概率使用 Q-Network 选择 action。
-
玻尔兹曼探索
玻尔兹曼探索策略是基于玻尔兹曼分布(Boltzmann Distribution)的概念。在每一步中,智能体会根据每个动作的价值函数估计值和一个称为“温度”的参数 τ 来计算选择该动作的概率。
温度参数 τ 控制了探索和利用之间的平衡:当 τ 较高时,智能体更倾向于探索;当 τ 较低时,智能体更倾向于利用已知信息选择最优动作。
2.3 经验回放
经验回放(Experience Replay)是一种用于存储和回放过去经验(即状态转换)的策略。
该策略需要创建一个经验池(Experience Replay Buffer),通常是一个循环队列或固定大小的列表。每当 agent 选择一个 action 并与环境进行交互时,就会生成一个新的经验(或称为转换),该经验包含当前state、所选 action、获得的 reward 以及下一个state。这个经验会被存储到经验池中。当经验池中的经验数量达到一定的阈值时,算法每次训练会从经验池中随机抽取一批经验作为训练数据。
好处:
- 打破数据相关性:在强化学习中,相邻状态之间通常存在高度相关性。直接使用连续的经验进行训练可能会导致模型对最近的经验产生过度拟合,从而降低其泛化能力。通过经验回放,算法可以从历史经验中随机抽取数据进行训练,从而打破数据之间的相关性,提高模型的泛化能力。
- 提高数据利用效率:在强化学习中,数据的收集往往是非常昂贵的。通过经验回放,算法可以反复利用存储在经验池中的历史经验进行训练,从而提高数据的利用效率。
- 提高训练稳定性:由于经验回放可以打破数据之间的相关性并提高数据利用效率,因此它可以使DQN的训练过程更加稳定。此外,通过随机抽取经验进行训练,算法可以更好地应对非平稳分布的问题,因为历史经验中可能包含不同分布的数据。