1.render()无法弹出游戏窗口的原因
你使用的代码可能与你的gym版本不符
在我目前的测试看来,gym 0.23的版本,在初始化env的时候只需要游戏名称这一个实参,然后在需要渲染的时候主动调用render()去渲染游戏窗口,比如:
env = gym.make("CartPole-v1")
obs = env.reset()for _ inrange(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 _ inrange(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源码如下:
defreset(
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 =Noneif 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去测试就好
版权归原作者 Jayetchellot 所有, 如有侵权,请联系我们删除。