Categorical 51 DQN¶
论文链接: https://proceedings.mlr.press/v70/bellemare17a.html。
C51 算法(Categorical DQN)是 DQN 的一种变体, 它将分布式强化学习方法引入 DQN。 与仅为 Q 函数预测单个标量值(即未来回报的期望)不同, C51 会在一组离散的可能回报上预测概率分布, 使智能体不仅能够学习期望回报,还能够刻画回报的不确定性。
下表列出了 C51 算法的一些基本特征:
C51 的特征 |
是否具备 |
说明 |
|---|---|---|
同策略(On-policy) |
❌ |
评估策略与目标策略相同。 |
异策略(Off-policy) |
✅ |
评估策略与目标策略不同。 |
无模型(Model-free) |
✅ |
无须预先构建环境动力学模型。 |
基于模型(Model-based) |
❌ |
需要使用环境模型训练策略。 |
离散动作 |
✅ |
可处理离散动作空间。 |
连续动作 |
❌ |
可处理连续动作空间。 |
方法¶
DQN 存在的问题¶
在传统 DQN 中,目标是学习给定状态下每个动作对应的期望回报:
其中,
C51 不再只学习一个标量 \(Q(s, a)\), 而是学习每个动作对应的完整回报分布,记为 \(Z(s, a)\)。
C51 将可能的回报范围(例如从 -1 到 1)划分为固定数量的离散区间或支撑点, 这些离散支撑点被称为原子(atoms)。 对于每个原子,算法预测回报落在该原子上的概率。
因此,智能体可以同时根据期望回报及其不确定性进行决策。
类别分布表示¶
为了近似 \(Z(s, a)\),C51 在预先定义的取值范围 \([v_{min}, v_{max}]\) 内,使用由 \(N\) 个离散原子构成的类别分布来表示它。 这些原子定义为:
每个原子 \(z_i\) 都对应一个概率 \(p_i\),从而构成类别分布:
分布式 Bellman 方程¶
回报分布对应的 Bellman 方程为:
该方程表示,当前状态—动作对的回报分布由即时奖励 \(R\) 以及下一状态 \(S'\) 对应回报分布的折扣结果共同决定。
在实际计算中,为了保持表示的一致性, 下一状态的回报分布 \(Z(S', A')\) 会被投影回固定的原子集合 \(z_i\) 上。
算法¶
训练 C51 的完整算法如算法 1 所示。
备注
算法 1 能够以关于 N 的线性时间复杂度计算该投影。
在 XuanCe 中运行 C51¶
在 XuanCe 中运行 C51 之前,需要先准备一个 conda 环境,并按照
安装步骤安装 xuance。
运行内置示例¶
完成安装后,可以打开 Python 控制台,并使用以下命令直接运行 C51:
import xuance
runner = xuance.get_runner(method='c51',
env='classic_control', # 可选项:claasi_control、box2d、atari。
env_id='CartPole-v1', # 可选项:CartPole-v1、LunarLander-v2、ALE/Breakout-v5 等。
is_test=False)
runner.run() # 也可以使用 runner.benchmark()
使用自定义配置运行¶
如需使用不同配置运行 C51,可以新建一个 .yaml 文件,例如 my_config.yaml。
然后使用以下代码运行 C51:
import xuance as xp
runner = xp.get_runner(method='c51',
env='classic_control', # 可选项:claasi_control、box2d、atari。
env_id='CartPole-v1', # 可选项:CartPole-v1、LunarLander-v2、ALE/Breakout-v5 等。
config_path="my_config.yaml", # 请确保 my_config.yaml 文件的路径正确。
is_test=False)
runner.run() # 也可以使用 runner.benchmark()
如需进一步了解配置方法,请参阅 配置教程。
在自定义环境中运行¶
如需在 XuanCe 尚未包含的自定义环境中运行 C51,
需要按照 新环境教程
中的步骤定义新环境。
然后,准备配置文件
c51_myenv.yaml。
完成上述操作后,可以使用以下代码在自定义环境中运行 C51:
import argparse
from xuance.common import get_configs
from xuance.environment import REGISTRY_ENV
from xuance.environment import make_envs
from xuance.torch.agents import C51_Agent
configs_dict = get_configs(file_dir="c51_myenv.yaml")
configs = argparse.Namespace(**configs_dict)
REGISTRY_ENV[configs.env_name] = MyNewEnv
envs = make_envs(configs) # 创建并行环境。
Agent = C51_Agent(config=configs, envs=envs) # 创建一个来自 XuanCe 的 C51 智能体。
Agent.train(configs.running_steps // configs.parallels) # 对模型进行多个步骤的训练。
Agent.save_model("final_train_model.pth") # 将模型保存到 model_dir。
Agent.finish() # 结束训练。
参考文献¶
@inproceedings{bellemare2017distributional,
title={A distributional perspective on reinforcement learning},
author={Bellemare, Marc G and Dabney, Will and Munos, R{\'e}mi},
booktitle={International conference on machine learning},
pages={449--458},
year={2017},
organization={PMLR}
}