Double Deep Q-Network (Double DQN)¶
论文链接:
AAAI,
ArXiv,
Double Q-learning
双重深度 Q 网络(Double Deep Q-Network,Double DQN)是对原始深度 Q 网络(Deep Q-Network,DQN)算法的改进, 旨在解决基于 Q-learning 的方法中常见的 Q 值高估问题。 当 Q-learning 算法根据最大 Q 值选择动作时,由于噪声或近似误差,该最大 Q 值可能被高估,从而产生高估问题。 这可能导致次优策略以及训练过程不稳定。
下表列出了 Double DQN 算法的一些基本特征:
Double DQN 的特征 |
是否支持 |
说明 |
|---|---|---|
同策略(On-policy) |
❌ |
评估策略与目标策略相同。 |
异策略(Off-policy) |
✅ |
评估策略与目标策略不同。 |
无模型(Model-free) |
✅ |
无需预先构建环境动力学模型。 |
基于模型(Model-based) |
❌ |
需要环境模型来训练策略。 |
离散动作 |
✅ |
可处理离散动作空间。 |
连续动作 |
❌ |
可处理连续动作空间。 |
高估的风险¶
在标准 DQN 中,由于动作选择和动作评估均使用同一个 Q 网络,因此会产生高估问题。
如前文所述,DQN 使用下一状态的最大 Q 值 \(\max_{a'}Q(s', a')\) 作为目标值的一部分,从而更新状态—动作对的 Q 值 \(Q(s, a)\)。
当 Q 网络高估了一个或多个状态—动作对的价值时,这种高估会随着时间传播并不断累积。 其结果是 Q 值变得过于乐观,不仅可能造成训练不稳定,还会使策略倾向于选择次优动作。
高估会使智能体偏向那些看起来比实际情况更优的动作, 进而可能在复杂环境中导致错误决策和性能下降。
此外,如果高估现象过于严重,还可能破坏训练过程的稳定性,导致 Q 值发散。
核心思想¶
Double DQN 的核心思想是将动作选择与动作评估过程解耦, 从而降低 Q 值被高估的风险。 具体而言,它通过两个相互分离的 Q 值估计步骤实现这一目标:
动作选择:使用当前 Q 网络为给定状态选择最优动作。
动作评估:使用目标 Q 网络评估所选动作的价值。
随后,通过最小化以下损失函数来更新 Q 网络:
最后,不要忘记更新目标网络:\(\theta^{-} \leftarrow \theta\)。
与 DQN 的比较¶
为了更清楚地说明 DQN 与 Double DQN 之间的区别, 可以分别改写二者在 DQN 中的 目标值计算方式, 并对比以下公式:
可以看出,DQN 与 Double DQN 的主要区别,在于由目标 Q 网络负责评估的贪心动作是如何确定的。 DQN 根据目标 Q 网络本身选择贪心动作, 而 Double DQN 则根据在线 Q 网络选择贪心动作,再由目标 Q 网络对其进行评估。
框架¶
XuanCe 中实现的 Double DQN,其智能体与环境之间的整体交互过程如下图所示。
在 XuanCe 中运行 Double DQN¶
在 XuanCe 中运行 Double DQN 之前,需要先准备 conda 环境,并按照
安装步骤安装 xuance。
运行内置示例¶
完成安装后,可以打开 Python 控制台,并使用以下命令直接运行 Double DQN:
import xuance
runner = xuance.get_runner(algo='ddqn',
env='classic_control', # 可选项:classic_control、box2d、atari。
env_id='CartPole-v1', # 可选项:CartPole-v1、LunarLander-v3、ALE/Breakout-v5 等。
)
runner.run() # 也可以使用 runner.benchmark()
使用自定义配置运行¶
如果希望使用不同的配置运行 Double DQN,可以新建一个 .yaml 文件,例如 my_config.yaml。
然后,通过以下代码运行 Double DQN:
import xuance
runner = xuance.get_runner(algo='ddqn',
env='classic_control', # 可选项:classic_control、box2d、atari。
env_id='CartPole-v1', # 可选项:CartPole-v1、LunarLander-v3、ALE/Breakout-v5 等。
config_path="my_config.yaml", # 请确保 my_config.yaml 文件的路径正确。
)
runner.run() # 也可以使用 runner.benchmark()
要进一步了解配置方法,请参阅 配置教程。
在自定义环境中运行¶
如果希望在 XuanCe 尚未内置的自定义环境中运行 Double DQN,
需要按照
新环境教程中的步骤定义新环境。
随后,准备配置文件
ddqn_myenv.yaml。
完成上述操作后,可以使用以下代码在自定义环境中运行 Double DQN:
import argparse
from xuance.common import load_yaml
from xuance.environment import REGISTRY_ENV
from xuance.environment import make_envs
from xuance.torch.agents import DDQN_Agent
configs_dict = load_yaml(file_dir="dqn_myenv.yaml")
configs = argparse.Namespace(**configs_dict)
REGISTRY_ENV[configs.env_name] = MyNewEnv
envs = make_envs(configs) # 创建并行环境。
Agent = DDQN_Agent(config=configs, envs=envs) # 创建 XuanCe 的 DDQN 智能体。
Agent.train(configs.running_steps // configs.parallels) # 训练模型若干步。
Agent.save_model("final_train_model.pth") # 将模型保存至 model_dir。
Agent.finish() # 结束训练并释放相关资源。
引用文献¶
@article{hasselt2010double,
title={Double Q-learning},
author={Hasselt, Hado},
journal={Advances in neural information processing systems},
volume={23},
year={2010}
}
@inproceedings{van2016deep,
title={Deep reinforcement learning with double q-learning},
author={Van Hasselt, Hado and Guez, Arthur and Silver, David},
booktitle={Proceedings of the AAAI conference on artificial intelligence},
volume={30},
number={1},
year={2016}
}