1.render()无法弹出游戏窗口的原因

你使用的代码可能与你的gym版本不符 在我目前的测试看来,gym 0.23的版本,在初始化env的时候只需要游戏名称这一个实参,然后在需要渲染的时候主动调用render()去渲染游戏窗口,比如:

env = gym.make("CartPole-v1")

obs = env.reset()

for _ in range(1000):

env.render()

obs, reward, done, info = env.step(env.action_space.sample()) # 以action随机抽样为例

if done:

break

env.close()

而在gym0.26的版本,在初始化env的时候你需要加入另一个实参:render_mode,如:

env = gym.make("CartPole-v1", render_mode="human")

具体参数参考官方文档:https://www.gymlibrary.dev/ 并且,你在reset时需要设置seed参数,并且还要用二项元组接收数据,而且step时需要用五项元组接收数据,否则会报错 就模仿官方文档的入门教程这样写:

import gym

env = gym.make("LunarLander-v2", render_mode="human")

observation, info = env.reset(seed=42)

for _ in range(1000):

action = policy(observation) # User-defined policy function

observation, reward, terminated, truncated, info = env.step(action)

if terminated or truncated:

observation, info = env.reset()

env.close()

2.在设置好 render_mode 后,调用reset()即会自动开始渲染

看了一下gym0.26的reset方法代码,它会根据你初始化env时传入的render_mode参数去决定它要不要渲染,并且,在gym0.26主动调用render是无效的 CartPole游戏的reset源码如下:

def reset(

self,

*,

seed: Optional[int] = None,

options: Optional[dict] = None,

):

super().reset(seed=seed)

# Note that if you use custom reset bounds, it may lead to out-of-bound

# state/observations.

low, high = utils.maybe_parse_reset_bounds(

options, -0.05, 0.05 # default low

) # default high

self.state = self.np_random.uniform(low=low, high=high, size=(4,))

self.steps_beyond_terminated = None

if self.render_mode == "human":

self.render()

return np.array(self.state, dtype=np.float32), {}

可以看到,在最后,如果render_mode设置为"human",那么render方法将被调用。

3.在gym 0.26如何实现训练时不渲染,而测试时再渲染

在gym0.23版本,可以主动调用render来决定渲不渲染,而在gym0.26版本,只要reset就渲染,所以如果你刚开始就设定render_mode="human"的话,那么你将会看到整个训练过程,且动画渲染结束之后才会开始下一个episode的训练,所以训练时长会比不渲染时更长。

解决方案:

最初,我以为动态地去修改env.render_mode即可,但我发现env初始化之后这个就是一个无法修改的参数

所以,你可以在初始化训练的env_train时,不添加render_mode参数(或添加除human之外的参数),然后在测试的时候,新创建一个与之前一样的env:env_test

env_test = gym.make("CartPole-v1", render_mode='human')

用新的env_test去测试就好

好文推荐

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。