Gym v0.26.0自定义迷宫环境reset()报TypeError:意外'seed'参数
Gym v0.26.0自定义环境reset()报错:
got an unexpected keyword argument 'seed' 我基于OpenAI Gym v0.26.0开发了自定义迷宫环境MazeEnv,测试时触发TypeError,提示reset() got an unexpected keyword argument 'seed'。我已经按照Gym官方文档编写代码,以下是环境类代码、测试代码和完整报错栈:
自定义环境类代码
import gym from gym import spaces import pygame import numpy as np import math import random class MazeEnv(gym.Env): metadata = {"render_modes": ["human", "rgb_array"], "render_fps": 4} def __init__(self, render_mode=None, size=10.0): self.size = size self.window_size = 512 self.observation_space = spaces.Dict( { "agent": spaces.Box(low=0.0, high=10.0, shape=(2,), dtype=np.float32), "target": spaces.Box(low=0.0, high=10.0, shape=(2,), dtype=np.float32) } ) self.action_space = spaces.Box(low=-math.pi, high=math.pi, shape = (1,)) assert render_mode is None or render_mode in self.metadata["render_modes"] self.render_mode = render_mode self.window = None self.clock = None def _get_obs(self): return {"agent": self._agent_location, "target": self._target_location} def _get_info(self): return {"distance": np.linalg.norm(self._agent_location - self._target_location, ord=2)} def reset(self, seed=None, options=None): super().reset(seed=seed) # agents starting location self._agent_location = [0.0, 10.0] self._target_location = [10.0, 0.0] observation = self._get_obs() info = self._get_info() if self.render_mode == "human": self._render_frame() return observation, info def step(self, action): terminated = False angle = random.gauss(action, math.pi/6) direction = [math.cos(angle)/2, math.sin(angle)/2] if self._agent_location[0] + direction[0] < 0.0 or self._agent_location[1] + direction[1] < 0.0 or self._agent_location[0] + direction[0] > 10.0 or self._agent_location[1] + direction[1] > 10.0: self._agent_location = [0.0, 10.0] ######### POSSIBLY RESET HERE? else: self._agent_location = self._agent_location + direction observation = self._get_obs() info = self._get_info() if info["distance"] < 0.5: terminated = True reward = 1 if terminated else 0 if self.render_mode == "human": self._render_frame() return observation, reward, terminated, False, info def render(self): if self.render_mode == "rgb_array": return self._render_frame() def _render_frame(self): if self.window is None and self.render_mode == "human": pygame.init() pygame.display.init() self.window = pygame.display.set_mode((self.window_size, self.window_size)) if self.clock is None and self.render_mode == "human": self.clock = pygame.time.Clock() canvas = pygame.Surface((self.window_size, self.window_size)) canvas.fill((255, 255, 255)) pygame.draw.circle(canvas, (255, 0, 0), self._target_location, 0.5, draw_top_left=True) pygame.draw.circle(canvas, (0,0,255), self._agent_location, 0.02) pygame.draw.line(canvas, (0,0,0), (0.0,0.0), (0.0,10.0)) pygame.draw.line(canvas, (0,0,0), (0.0,0.0), (10.0,0.0)) pygame.draw.line(canvas, (0,0,0), (10.0,0.0), (10.0,10.0)) pygame.draw.line(canvas, (0,0,0), (0.0,10.0), (10.0,10.0)) if self.render_mode == "human": # The following line copies our drawings from `canvas` to the visible window self.window.blit(canvas, canvas.get_rect()) pygame.event.pump() pygame.display.update() # We need to ensure that human-rendering occurs at the predefined framerate. # The following line will automatically add a delay to keep the framerate stable. self.clock.tick(self.metadata["render_fps"]) else: # rgb_array return np.transpose( np.array(pygame.surfarray.pixels3d(canvas)), axes=(1, 0, 2) ) def close(self): if self.window is not None: pygame.display.quit() pygame.quit()
测试代码
import gym env = gym.make('MazeEnv-v0') observation, info = env.reset() for _ in range(1000): observation, reward, terminated, truncation, info = env.step(env.action_space.sample()) if terminated: observation, info = env.reset() env.close()
报错信息
Traceback (most recent call last): File ...\Code\Maze Game\test.py:13 in <module> observation, info = env.reset() File E:\anaconda3\lib\site-packages\gym\wrappers\time_limit.py:68 in reset return self.env.reset(**kwargs) File E:\anaconda3\lib\site-packages\gym\envs\classic_control\maze_game.py:48 in reset super().reset(seed=seed) TypeError: reset() got an unexpected keyword argument 'seed'
问题原因及解决办法
问题原因
Gym v0.26.0版本中,基类gym.Env的reset()方法并不接受seed参数,你在自定义reset()方法里调用super().reset(seed=seed)时,给父类方法传入了它不支持的参数,因此触发TypeError。
解决步骤
- 移除父类reset调用的seed参数:直接删掉
super().reset(seed=seed)这行代码(Gym v0.26.0的Env.reset()本身没有实际逻辑,无需调用)。 - 手动处理随机种子:如果你的环境需要设置随机种子,在自定义
reset()里手动初始化种子即可,示例如下:
修改后的reset()方法:
def reset(self, seed=None, options=None): # 手动设置随机种子 if seed is not None: random.seed(seed) np.random.seed(seed) # 初始化位置改为numpy数组,避免后续运算报错 self._agent_location = np.array([0.0, 10.0], dtype=np.float32) self._target_location = np.array([10.0, 0.0], dtype=np.float32) observation = self._get_obs() info = self._get_info() if self.render_mode == "human": self._render_frame() return observation, info
另外补充:你当前代码中self._agent_location用的是普通列表,后续和direction(列表)相加没问题,但如果后续涉及numpy数组运算可能出错,建议统一改为numpy数组。
内容的提问来源于stack exchange,提问作者Daniel Rodriguez
相关产品推荐
相关产品推荐

