背景:
在郭宪老师的《深入浅出强化学习:原理入门》的学习中,在编写机器人找金币环境的最后一步中,出现了这样的问题:AttributeError: 'GridEnv' object has no attribute 'unwrapped'
以下是错误报告:
1 Traceback (most recent call last): 2 File "Z:\DQN\02\ending.py", line 7, in <module> 3 env = gym.make('GridWorld-v0') 4 File "Z:\Anaconda3\envs\my_env\lib\site-packages\gym\envs\registration.py", line 235, in make 5 return registry.make(id, **kwargs) 6 File "Z:\Anaconda3\envs\my_env\lib\site-packages\gym\envs\registration.py", line 129, in make 7 env = spec.make(**kwargs) 8 File "Z:\Anaconda3\envs\my_env\lib\site-packages\gym\envs\registration.py", line 95, in make 9 env.unwrapped.spec = spec 10 AttributeError: 'GridEnv' object has no attribute 'unwrapped' 11 12 Process finished with exit code 1
如何解决:
先说我是怎么解决的,再说解决的思路
问题出在
1 class GridEnv:
这个类的定义处,将他改成
1 class GridEnv(gym.Env):
就可以了
思路:
首先报错的翻译:'GridEnv'类没有对象'unwrapped',这边python太久没有用,很多语法都不记得了。
在看到这个问题的第一反应,是去看出错位置的代码,registration.py的95行定义的是make函数(这里的22行)
1 def make(self, **kwargs): 2 """Instantiates an instance of the environment with appropriate kwargs""" 3 if self.entry_point is None: 4 raise error.Error( 5 "Attempting to make deprecated env {}. (HINT: is there a newer registered version of this env?)".format( 6 self.id 7 ) 8 ) 9 10 _kwargs = self._kwargs.copy() 11 _kwargs.update(kwargs) 12 13 if callable(self.entry_point): 14 env = self.entry_point(**_kwargs) 15 else: 16 cls = load(self.entry_point) 17 env = cls(**_kwargs) 18 19 # Make the environment aware of which spec it came from. 20 spec = copy.deepcopy(self) 21 spec._kwargs = _kwargs 22 env.unwrapped.spec = spec#这里是95行 23 if env.spec.max_episode_steps is not None: 24 from gym.wrappers.time_limit import TimeLimit 25 26 env = TimeLimit(env, max_episode_steps=env.spec.max_episode_steps) 27 else: 28 if self.order_enforce: 29 from gym.wrappers.order_enforcing import OrderEnforcing 30 31 env = OrderEnforcing(env) 32 return env
从上往下看到95行,发现这是make函数第一次调用env.unwrapped,而这也是整个程序第一次调用env。那么问题来了,是env没有这个对象还是说有其他问题呢?于是我去看了env的定义:
1 @property 2 def unwrapped(self): 3 return self.env.unwrapped
在三百多行代码中,我找到了这个,env是有unwrapped这个对象的,那么就不是这个问题了,那其他问题从哪里找起呢?陷入了僵局。
灵机一动,还有其他样例代码,去看看其他环境是如何写出来的不就知道了吗?然后我发现了这个
1 class CartPoleEnv(gym.Env):
原来是我自己定义错了,在狠狠的抽了自己两巴掌之后,结束了这次的debug,之后虽然有一些小bug,但都很快解决了。
后记:
除了这个bug,还有一些配置环境的时候出现的问题,但是在足够多的网页的查找下,最终还是找到了解决方案,总结主要有三点:
1、书上参考的资料(GitHub)一定要去看,看了很快就能知道问题所在。
2、各种步骤要循规蹈矩的来,最好不要跳步骤或和在其他教程一起串着看,早晚出问题。
3、外网解决资源很丰富,可以尝试在*上寻找答案(中间有一个很重要的启发点就是来自*)
看了gym的一些东西的内部实现之后,感觉功力大涨,下次也可以试试看一些东西的内部实现。