如何在 Ray Tune 中使用 OpenAI Gym 'wrappers'和自定义 Gym 环境?



如何使用OpenAI Gym 'wrapper '与Ray Tune中的自定义Gym环境?

假设我构建了一个名为CustomEnv的Python类(类似于用于创建OpenAI Gym"CartPole-v1"环境的"CartPoleEnv"类)来创建我自己的(自定义)强化学习环境,并且我使用Ray Tune(在Ray 2.1.0中使用Python 3.9.15)中的tune.run()来训练我的环境中的代理使用"PPO"算法:

import ray
from ray import tune
tune.run(
"PPO",                         # 'PPO' algorithm
config={"env": CustomEnv,      # custom class used to create an environment
"framework": "tf2",
"evaluation_interval": 100, 
"evaluation_duration": 100,
},
checkpoint_freq = 100,             # Save checkpoint at every evaluation
local_dir=checkpoint_dir,          # Save results to a local directory
stop{"episode_reward_mean": 250},  # Stopping criterion
)

这很好,我可以使用TensorBoard来监控训练进度等,但事实证明,学习很慢,所以我想尝试使用Gym的"包装器"来扩展观察,奖励和/或行动,限制方差,并加速学习。所以我有一个ObservationWrapper,一个RewardWrapper,和一个ActionWrapper来做到这一点——例如,像这样的东西(缩放的确切性质不是我的问题的中心):

import gym
class ObservationWrapper(gym.ObservationWrapper):
def __init__(self, env):
super().__init__(env)
self.o_min = 0.
self.o_max = 5000.
def observation(self, ob):
# Normalize observations
ob = (ob - self.o_min)/(self.o_max - self.o_min)
return ob
class RewardWrapper(gym.RewardWrapper):
def __init__(self, env):
super().__init__(env)
self.r_min = -500
self.r_max = 100
def reward(self, reward):
# Scale rewards:
reward = reward/(self.r_max - self.r_min)
return reward
class ActionWrapper(gym.ActionWrapper):
def __init__(self, env):
super().__init__(env)
def action(self, action):
# Scale actions
action = action/10
return action
当我在本地机器上创建一个类的实例并在传统的训练循环中使用它时,像这样的包装器可以很好地与我的自定义类一起工作,像这样:
from my_file import CustomEnv
env = CustomEnv()
wrapped_env = ObservationWrapper(RewardWrapper(ActionWrapper(env)))
episodes = 10
for episode in range(1,episodes+1):
obs = wrapped_env.reset()
done = False
score = 0

while not done:
action = wrapped_env.action_space.sample()
obs, reward, done, info = wrapped_env.step(action)
score += reward
print(f'Episode: {episode},  Score: {score:.3f}')

我的问题是:我怎么能使用包装像这些与我的自定义类(CustomEnv)和ray.tune()?这个特殊的方法需要"env"传递(1)作为类(如CustomEnv)或(2)作为与已注册的Gym环境(如"CartPole-v1")相关联的字符串,正如我在尝试各种不正确的方法来传递我的自定义类的包装版本时发现的:

ValueError: >>> is an invalid env specifier. You can specify a custom env as either a class (e.g., YourEnvCls) or a registered env id (e.g., "your_env").

所以我不知道怎么做(假设它是可能的)。我更愿意解决这个问题,而不必注册我的定制Gym环境,但我对任何解决方案都持开放态度。

在学习包装器时,我主要利用了Ayoosh Kathuria的"Getting Started With OpenAI Gym: The Basic Building Blocks"one_answers"TF 2.0 for Reinforcement learning: Gym wrappers"。

我能够回答我自己关于如何让Ray的tune.run()与Gym环境的包装自定义类一起工作的问题。Ray Environments的文档很有帮助。

解决方案是通过Ray注册自定义类。假设您已经如上所述定义了Gym包装器(类),其工作方式如下:

from ray.tune.registry import register_env
from your_file import CustomEnv             # import your custom class
def env_creator(env_config):
# wrap and return an instance of your custom class
return ObservationWrapper(RewardWrapper(ActionWrapper(CustomEnv())))
# Choose a name and register your custom environment
register_env('WrappedCustomEnv-v0', env_creator)

现在,在tune.run()中,您可以像提交任何其他已注册的Gym环境一样提交已注册实例的名称:

import ray
from ray import tune
tune.run(
"PPO",                          # 'PPO' algorithm (for example)
config={"env": "WrappedCustomEnv-v0", # the registered instance
#other options here as desired
},
# other options here as desired
)

tune.run()可以正常工作,没有错误——问题解决了!

相关内容

  • 没有找到相关文章

最新更新