如何设置 openai-gym 环境以特定状态而不是 `env.reset()` 开始?
How to set a openai-gym environment start with a specific state not the `env.reset()`?
今天尝试在openai-gym环境下实现rl-agent时,发现一个问题,好像所有的agent都是从最初始的状态开始训练的:env.reset()
,即
import gym
env = gym.make("CartPole-v0")
initial_observation = env.reset() # <-- Note
done = False
while not done:
action = env.action_space.sample()
next_observation, reward, done, info = env.step(action)
env.close() # close the environment
所以agent自然可以顺着路线行事env.reset() -(action)-> next_state -(action)-> next_state -(action)-> ... -(action)-> done
,这是一个小插曲。但是代理如何从特定状态(如中间状态)开始,然后从该状态采取行动?例如,我从重播缓冲区中抽取一个经验,即 (s, a, r, ns, done)
,如果我想训练代理直接从状态 ns
开始,然后用 Q-Network
获得一个动作,那么向前 n-step
步。类似的东西:
import gym
env = gym.make("CartPole-v0")
initial_observation = ns # not env.reset()
done = False
while not done:
action = DQN(ns)
next_observation, reward, done, info = env.step(action)
# n-step later or done is true, break
env.close() # close the environment
但即使我将变量 initial_observation
设置为 ns
,我认为代理或 env
根本不会意识到这一点。我如何告诉 gym.env
我想将初始观察设置为 ns
并让代理知道特定的开始状态,直接从该特定观察(从该特定环境开始)继续训练?
AFAIK,大多数 OpenAI 健身房环境的当前实现(包括您在问题中使用的 CartPole-v0)没有实现任何机制来初始化环境给定的状态。
但是,修改 CartPoleEnv.reset()
方法以接受充当初始状态的可选参数应该不会太复杂。
我尝试通过在调用 'env.step()' 之前简单地将 'env.state' 设置为我想要的来解决这个问题。如果我使用 'gym.make()' 初始化环境,这将不起作用。但是,我将环境的源代码复制到另一个文件,从中导入它,然后就可以简单地设置 'env.state'。您只需确保没有将其设置为允许值之外的值。
import numpy as np
from continuous_mountain_car import Continuous_MountainCarEnv
env = Continuous_MountainCarEnv()
env.reset()
print(env.state) # Random value generated by reset
env.state = np.array([-0.53, 0]) # Set it to my own value
print(env.state) # It worked
next_state, reward, done, _ = env.step(np.array([0]))
print(next_state) # The next state should be close to my value not the random one
我从 https://github.com/openai/gym/blob/master/gym/envs/classic_control/continuous_mountain_car.py
复制了 continuous_mountain_car 文件
我建议您使用并根据您的需要调整以下代码,它运行良好,我在我的 AlphaZero 实现中使用了它。
此示例适用于 CartPole,但您应该能够轻松地将其适应其他环境。
from copy import deepcopy
import gym
import numpy as np
from gym.spaces import Discrete, Dict, Box
class CartPole:
def __init__(self, config=None):
self.env = gym.make("CartPole-v0")
self.action_space = Discrete(2)
self.observation_space = self.env.observation_space
def reset(self):
return self.env.reset()
def step(self, action):
obs, rew, done, info = self.env.step(action)
return obs, rew, done, info
def set_state(self, state):
self.env = deepcopy(state)
obs = np.array(list(self.env.unwrapped.state))
return obs
def get_state(self):
return deepcopy(self.env)
def render(self):
self.env.render()
def close(self):
self.env.close()
直接分配给 env.state
的原因是因为生成的 gym 环境实际上是一个 gym.wrappers.TimeLimit
对象。
为了实现您的预期,您还必须将 ns
值分配给展开的环境。所以,像这样的事情应该可以解决问题:
env.reset()
env.state = env.unwrapped.state = ns
我建议您扩展 CartPole 环境,以便重置方法可以满足您的需要。然后自己包装你的环境。例如
from gym.envs.classic_control import CartPoleEnv
class ExtendedCartPoleEnv(CartPoleEnv):
def reset(self):
self.state = your_very_special_method()
self.steps_beyond_done = None
return np.array(self.state, dtype=np.float32)
max_episode_steps = 200
env = ExtendedCartPoleEnv()
env = TimeLimit(env, max_episode_steps)
我刚刚调整了找到的原始方法 here。
您还可以扩展原始环境来更改 self.reset
的行为以获取参数,但这不是标准。包装环境不会接受参数,然后您需要直接调用 env.unwrapped.reset
。这变得很难看,因为 env.step
会抱怨 env.reset
没有被调用。等等。有很多方法可以实现它,但话又说回来,这与常规健身房环境应该看起来的样子不同。
今天尝试在openai-gym环境下实现rl-agent时,发现一个问题,好像所有的agent都是从最初始的状态开始训练的:env.reset()
,即
import gym
env = gym.make("CartPole-v0")
initial_observation = env.reset() # <-- Note
done = False
while not done:
action = env.action_space.sample()
next_observation, reward, done, info = env.step(action)
env.close() # close the environment
所以agent自然可以顺着路线行事env.reset() -(action)-> next_state -(action)-> next_state -(action)-> ... -(action)-> done
,这是一个小插曲。但是代理如何从特定状态(如中间状态)开始,然后从该状态采取行动?例如,我从重播缓冲区中抽取一个经验,即 (s, a, r, ns, done)
,如果我想训练代理直接从状态 ns
开始,然后用 Q-Network
获得一个动作,那么向前 n-step
步。类似的东西:
import gym
env = gym.make("CartPole-v0")
initial_observation = ns # not env.reset()
done = False
while not done:
action = DQN(ns)
next_observation, reward, done, info = env.step(action)
# n-step later or done is true, break
env.close() # close the environment
但即使我将变量 initial_observation
设置为 ns
,我认为代理或 env
根本不会意识到这一点。我如何告诉 gym.env
我想将初始观察设置为 ns
并让代理知道特定的开始状态,直接从该特定观察(从该特定环境开始)继续训练?
AFAIK,大多数 OpenAI 健身房环境的当前实现(包括您在问题中使用的 CartPole-v0)没有实现任何机制来初始化环境给定的状态。
但是,修改 CartPoleEnv.reset()
方法以接受充当初始状态的可选参数应该不会太复杂。
我尝试通过在调用 'env.step()' 之前简单地将 'env.state' 设置为我想要的来解决这个问题。如果我使用 'gym.make()' 初始化环境,这将不起作用。但是,我将环境的源代码复制到另一个文件,从中导入它,然后就可以简单地设置 'env.state'。您只需确保没有将其设置为允许值之外的值。
import numpy as np
from continuous_mountain_car import Continuous_MountainCarEnv
env = Continuous_MountainCarEnv()
env.reset()
print(env.state) # Random value generated by reset
env.state = np.array([-0.53, 0]) # Set it to my own value
print(env.state) # It worked
next_state, reward, done, _ = env.step(np.array([0]))
print(next_state) # The next state should be close to my value not the random one
我从 https://github.com/openai/gym/blob/master/gym/envs/classic_control/continuous_mountain_car.py
复制了 continuous_mountain_car 文件我建议您使用并根据您的需要调整以下代码,它运行良好,我在我的 AlphaZero 实现中使用了它。
此示例适用于 CartPole,但您应该能够轻松地将其适应其他环境。
from copy import deepcopy
import gym
import numpy as np
from gym.spaces import Discrete, Dict, Box
class CartPole:
def __init__(self, config=None):
self.env = gym.make("CartPole-v0")
self.action_space = Discrete(2)
self.observation_space = self.env.observation_space
def reset(self):
return self.env.reset()
def step(self, action):
obs, rew, done, info = self.env.step(action)
return obs, rew, done, info
def set_state(self, state):
self.env = deepcopy(state)
obs = np.array(list(self.env.unwrapped.state))
return obs
def get_state(self):
return deepcopy(self.env)
def render(self):
self.env.render()
def close(self):
self.env.close()
直接分配给 env.state
的原因是因为生成的 gym 环境实际上是一个 gym.wrappers.TimeLimit
对象。
为了实现您的预期,您还必须将 ns
值分配给展开的环境。所以,像这样的事情应该可以解决问题:
env.reset()
env.state = env.unwrapped.state = ns
我建议您扩展 CartPole 环境,以便重置方法可以满足您的需要。然后自己包装你的环境。例如
from gym.envs.classic_control import CartPoleEnv
class ExtendedCartPoleEnv(CartPoleEnv):
def reset(self):
self.state = your_very_special_method()
self.steps_beyond_done = None
return np.array(self.state, dtype=np.float32)
max_episode_steps = 200
env = ExtendedCartPoleEnv()
env = TimeLimit(env, max_episode_steps)
我刚刚调整了找到的原始方法 here。
您还可以扩展原始环境来更改 self.reset
的行为以获取参数,但这不是标准。包装环境不会接受参数,然后您需要直接调用 env.unwrapped.reset
。这变得很难看,因为 env.step
会抱怨 env.reset
没有被调用。等等。有很多方法可以实现它,但话又说回来,这与常规健身房环境应该看起来的样子不同。