如题:
在baselines中对atari游戏环境进行包装的代码在atari_wrappers.py模块中,
def make_atari(env_id, max_episode_steps=None): env = gym.make(env_id) assert 'NoFrameskip' in env.spec.id env = NoopResetEnv(env, noop_max=30) env = MaxAndSkipEnv(env, skip=4) if max_episode_steps is not None: env = TimeLimit(env, max_episode_steps=max_episode_steps) return env def wrap_deepmind(env, episode_life=True, clip_rewards=True, frame_stack=False, scale=False): """Configure environment for DeepMind-style Atari. """ if episode_life: env = EpisodicLifeEnv(env) if 'FIRE' in env.unwrapped.get_action_meanings(): env = FireResetEnv(env) env = WarpFrame(env) if scale: env = ScaledFloatFrame(env) if clip_rewards: env = ClipRewardEnv(env) if frame_stack: env = FrameStack(env, 4) return env
由 baselines库中cmd_util.py模块对atari游戏的包装为什么要分成两部分并在中间加入flatten操作呢? 可以知道在make_atari函数中不对observation进行处理,wrap_deepmind函数对observation进行处理。
WarpFrame, ScaledFloatFrame, FrameStack, 这三个环境包装类是对observation进行处理包装的。
其中,WarpFrame要求observation必须是shape为(height, width, channels)的np.array。
换句话说,warp_deepmind 的observation变量应该为图片类型的np.array 。
还有一个需要注意的是,warp_deepmind中包装类FireResetEnv是否应该在make_atari函数中的NoopResetEnv前面,根据国外的一些相关文章所指出的,认为应该是将FireResetEnv放在NoopResetEnv前面,修改后的代码为:
修改后的代码为:
def make_atari(env_id, max_episode_steps=None): env = gym.make(env_id) assert 'NoFrameskip' in env.spec.id if 'FIRE' in env.unwrapped.get_action_meanings(): env = FireResetEnv(env) env = NoopResetEnv(env, noop_max=30) env = MaxAndSkipEnv(env, skip=4) if max_episode_steps is not None: env = TimeLimit(env, max_episode_steps=max_episode_steps) return env def wrap_deepmind(env, episode_life=True, clip_rewards=True, frame_stack=False, scale=False): """Configure environment for DeepMind-style Atari. """ if episode_life: env = EpisodicLifeEnv(env) env = WarpFrame(env) if scale: env = ScaledFloatFrame(env) if clip_rewards: env = ClipRewardEnv(env) if frame_stack: env = FrameStack(env, 4) return env
这样修改的逻辑是,如果一个环境需要Fire button来启动游戏那么在它之前进行NoopResetEnv是没有意义的。
也就是说,在有fire操作和noop操作同时存在的情况下,最好是先进行fire操作再进行noop操作,在reset过程中fire操作后再进行noop操作。
==================================================