在接下来的系列文章中,将把注意力转向OpenAI Gym环境,特别是打砖块游戏。这个游戏包含了一系列的砖块、一个球和一个挡板。当球击中砖块时,将获得一些分数,并且砖块会被移除。必须移动屏幕底部的挡板以防止球飞出屏幕,否则将失去五个生命值中的一个。
发现Atari环境的命名约定有些令人困惑,因此认为在这里简要解释一下是值得的。环境名称包括一个版本和一个后缀。
版本v0有一个重复动作概率为0.25,这意味着四分之一的时间将使用之前的行动而不是选择的行动。这些所谓的“粘性动作”是引入随机性到本来确定性环境中的一种方式,主要是为了基准测试。
版本v4总是执行选择的动作。对于打砖块游戏,没有版本1、2或3。
没有后缀:每次步骤随机跳过2、3或4帧。
Deterministic:每次步骤跳过4帧。
NoFrameskip:每次步骤跳过0帧。
实际上,发现跳帧选项并没有太大的区别。这可能是因为大多数运行使用了带有经验缓冲区的DQN,所以实际上是在向池中注入四个相似的经验,但并没有立即从中学习。使用Deterministic环境可能允许用更小的缓冲区达到相同的结果,但不一定学习得更快。
Atari游戏环境有两种基本不同的版本。标准版本,也是迄今为止最常用的版本,以屏幕上的像素形式提供观测。每一步,观察到一个形状为(210, 160, 3)的uint8值数组,代表每个像素的红色、绿色和蓝色值。第二个版本以计算机内存中发生的事情为观测。Atari 2600,这是为了实现这些环境而模拟的,只有128字节的RAM。不是128K,是128字节!
在本系列中,将尝试解决这两种类型的Atari环境。将从更简单、研究更深入的版本开始:从屏幕上发生的事情中学习。
以下是用于从像素中学习的代码:
import pyvirtualdisplay
_display = pyvirtualdisplay.Display(visible=False, size=(1400, 900))
_ = _display.start()
import ray
from ray import tune
from ray.rllib.agents.dqn import DQNTrainer
ray.shutdown()
ray.init(
include_webui=False, ignore_reinit_error=True,
memory=4000 * 1024 * 1024,
object_store_memory=400 * 1024 * 1024,
driver_object_store_memory=200 * 1024 * 1024
)
ENV = "BreakoutNoFrameskip-v4"
TARGET_REWARD = 200
TRAINER = DQNTrainer
tune.run(
TRAINER,
stop={
"episode_reward_mean": TARGET_REWARD,
config={
"env": ENV,
"num_gpus": 0,
"monitor": True,
"evaluation_num_episodes": 25,
"num_workers": 0,
"double_q": True,
"dueling": True,
"num_atoms": 1,
"noisy": False,
"prioritized_replay": False,
"n_step": 1,
"target_network_update_freq": 8000,
"lr": 0.0000625,
"adam_epsilon": 0.00015,
"hiddens": [512],
"learning_starts": 20000,
"buffer_size": 400_000,
"rollout_fragment_length": 4,
"train_batch_size": 32,
"exploration_config": {
"epsilon_timesteps": 500_000,
"final_epsilon": 0.01,
},
"prioritized_replay_alpha": 0.5,
"final_prioritized_replay_beta": 1.0,
"prioritized_replay_beta_annealing_timesteps": 2_000_000,
"timesteps_per_iteration": 10_000,
}
}
)