更多强化学习项目 (定制化环境)¶
任天堂系统(NES)上的 超级马里奥兄弟 & 超级马里奥兄弟2 是1980年代最受欢迎的游戏之一。 来设计一个基于 DRL 的 AI 来探索这款经典游戏怎么样? 在本教程中,我们将在 DI-engine 中实现一个由人工智能控制的马里奥(使用 DQN 算法)。
使用配置文件¶
DI-engine 使用全局配置文件来控制环境和策略的所有变量,每个变量都有对应的默认配置可以在 mario_dqn_config 中找到,在本次教程中我们直接使用默认配置:
from dizoo.mario.mario_dqn_config import main_config, create_config
from ding.config import compile_config
cfg = compile_config(main_config, create_cfg=create_config, auto=True)
初始化环境¶
超级马里奥兄弟
是一个 图像输入 观察环境, 所以我们不只是通过 DingEnvWrapper
封装原始的 gym 环境,而是需要添加一些额外的 Wrapper 在发送给 DQN Policy 之前对观测进行预处理。
在本教程中,我们使用以下5个 Wrapper 来预处理数据并转换为 DI-engine 的环境格式,下列是一些基本描述,你可以在这里找到 完整代码实现和注释
MaxAndSkipWrapper
: 由于连续帧变化不大,我们可以跳过n个中间帧来简化它而不会损失太多信息。
WarpFrameWrapper
: 将原始 RGB 图像转换为灰度图,并将其调整为标准大小以进行 DRL 训练。
ScaledFloatFrameWrapper
: 将原始图像从[0-255]归一化到[0-1],有利于神经网络训练。
FrameStackWrapper
: 堆叠连续的帧。由于我们无法从单帧推断方向、速度等信息,堆叠帧可以提供更多的必要信息。
EvalEpisodeReturnWrapper
: 记录最终的 evaluation reward(即马里奥中的 episode return),适配 DI-engine 的环境格式。
Note
如果找不到合适的 Env Wrapper, 您可以按照 gym.Wrapper
格式定义自己的 Wrapper ,也可以根据 Customized Env doc 实现符合 DI-engine 的环境格式
# use subprocess env manager to speed up collecting
from ding.envs import DingEnvWrapper, SubprocessEnvManagerV2
from ding.envs.env_wrappers import MaxAndSkipWrapper, WarpFrameWrapper, ScaledFloatFrameWrapper, FrameStackWrapper, \
EvalEpisodeReturnWrapper
import gym_super_mario_bros
from nes_py.wrappers import JoypadSpace
def wrapped_mario_env():
return DingEnvWrapper(
# Limit the action-space to 2 dim: 0. walk right, 1. jump right
JoypadSpace(gym_super_mario_bros.make("SuperMarioBros-1-1-v0"), [["right"], ["right", "A"]]),
cfg={
'env_wrapper': [
lambda env: MaxAndSkipWrapper(env, skip=4),
lambda env: WarpFrameWrapper(env, size=84),
lambda env: ScaledFloatFrameWrapper(env),
lambda env: FrameStackWrapper(env, n_frames=4),
lambda env: EvalEpisodeReturnWrapper(env),
]
}
)
collector_env_num, evaluator_env_num = cfg.env.collector_env_num, cfg.env.evaluator_env_num
collector_env = SubprocessEnvManagerV2(
env_fn=[wrapped_mario_env for _ in range(collector_env_num)], cfg=cfg.env.manager
)
evaluator_env = SubprocessEnvManagerV2(
env_fn=[wrapped_mario_env for _ in range(evaluator_env_num)], cfg=cfg.env.manager
)
Note
以下内容与 CartPole + DQN
示例相同, 只需要选择策略并搭建整个训练管线
选择策略¶
DI-engine 涵盖了大部分强化学习策略,使用它们只需要选择正确的策略和模型。由于 DQN 是 Off-Policy 类型算法,我们还需要实例化一个缓冲区模块。
from ding.model import DQN
from ding.policy import DQNPolicy
from ding.data import DequeBuffer
model = DQN(**cfg.policy.model)
buffer_ = DequeBuffer(size=cfg.policy.other.replay_buffer.replay_buffer_size)
policy = DQNPolicy(cfg.policy, model=model)
构建管线¶
借助 DI-engine 提供的各种中间件,我们可以轻松构建整个训练管线:
from ding.framework import task
from ding.framework.context import OnlineRLContext
from ding.framework.middleware import OffPolicyLearner, StepCollector, interaction_evaluator, data_pusher, eps_greedy_handler, CkptSaver, nstep_reward_enhancer
with task.start(async_mode=False, ctx=OnlineRLContext()):
# Evaluating, we place it on the first place to get the score of the random model as a benchmark value
task.use(interaction_evaluator(cfg, policy.eval_mode, evaluator_env))
task.use(eps_greedy_handler(cfg)) # Decay probability of explore-exploit
task.use(StepCollector(cfg, policy.collect_mode, collector_env)) # Collect environmental data
task.use(nstep_reward_enhancer(cfg)) # Prepare nstep reward for training
task.use(data_pusher(cfg, buffer_)) # Push data to buffer
task.use(OffPolicyLearner(cfg, policy.learn_mode, buffer_)) # Train the model
task.use(CkptSaver(policy, cfg.exp_name, train_freq=100)) # Save the model
# In the evaluation process, if the model is found to have exceeded the convergence value, it will end early here
task.run()
运行代码¶
完整的示例可以在 马里奥DQN示例 中找到,并且可以通过 python3 mario_dqn_example.py
运行,
这个示例可以在1~2小时内给出顺利的结果,我们的超级马里奥可以很快地通过1-1关卡且不收到任何伤害,下图是训练好的智能体的回放视频和详细的训练曲线。
现在您已经完成了使用 DI-engine 的 定制化环境示例 , 您可以在 示例目录 中尝试更多算法, 或继续阅读文档以更深入地了解 DI-engine 的 算法, 系统设计 和 最佳实践.