Python 将训练数据传递到自定义openai健身房环境的正确方法是什么?
我正在创建一个自定义,类似于或。正在设置自定义环境,以使用来训练强化学习模型 我的问题是,批量更新之间所花的时间(通过环境和收集奖励所花的时间)越来越长,并且每次更新都会线性扩展1-5秒。开始时,这是有意义的,因为未经培训的代理很快“死亡”(Python 将训练数据传递到自定义openai健身房环境的正确方法是什么?,python,reinforcement-learning,openai-gym,Python,Reinforcement Learning,Openai Gym,我正在创建一个自定义,类似于或。正在设置自定义环境,以使用来训练强化学习模型 我的问题是,批量更新之间所花的时间(通过环境和收集奖励所花的时间)越来越长,并且每次更新都会线性扩展1-5秒。开始时,这是有意义的,因为未经培训的代理很快“死亡”(done=True所以这一集就结束了)。随着代理的训练,它应该可以存活更长的时间,直到它开始存活整个集,更新之间的时间应该稳定下来。但即使在数百次更新之后,更新之间的时间也会继续增加(数百次,环境中的数万个连续步骤).我已经监控了培训,可以看到该代理在整个剧
done=True
所以这一集就结束了)。随着代理的训练,它应该可以存活更长的时间,直到它开始存活整个集,更新之间的时间应该稳定下来。但即使在数百次更新之后,更新之间的时间也会继续增加(数百次,环境中的数万个连续步骤).我已经监控了培训,可以看到该代理在整个剧集中存活了大约50次更新
起初,我认为环境中的某些变量可能在更新之间持续存在并变得非常大,从而降低了计算时间。但当我在培训期间监控内存使用情况时,它在整个时间内保持不变。考虑到环境应该重置每一集(并将我的所有列表变量初始化为空)理论上,增加可变大小不应该是一个问题
话虽如此,也许我没有将数据正确地传递到MyCustomEnv
。当我将整个训练数据集读入内存(1e6
samples)时,我希望在每一集中只向环境传递一批数据,但我可能错了(我已经设置了n_steps=1024
,这是一批/一集中的步骤数)。下面是一个最小代码示例
# myenv.py
import gym
from gym import spaces
import numpy as np
from sklearn.preprocessing import MinMaxScaler
class MyCustomEnv(gym.Env):
def __init__(self, data):
super().__init__()
self.data = data # numpy array, shape = (1e6, 5)
self.observation_space = spaces.Box(low=0., high=1., shape=(1, self.data.shape[1]), dtype=np.float32)
self.action_space = spaces.Discrete(4) # 4 actions - see ACTION_LOOKUP below
def _take_action(self, action):
my_action = ACTION_LOOKUP[action]
tmp = do_action(my_action) # this is a simple function not shown, it returns a float
self.my_list.append(tmp)
def _done(self):
if current_step = self.data.shape[1] - 1:
return True
if died(): # another simple function not shown that just checks a running variable
return True
return False
def _next_observation(self):
obs = MinMaxScaler().fit_transform(self.data)[-1] # last row of numpy array data, scaled
return obs
def _reward(self):
reward = get_reward(self.my_list)
return reward
def step(self, action):
self._take_action(action)
self.current_step += 1
obs = self._next_observation()
reward = self._reward()
done = self._done()
return obs, reward, done, {}
def reset(self):
self.current_step = 0
self.my_list = []
ACTION_LOOKUP = {
0 : "LEFT"
1 : "RIGHT"
2 : "UP"
3 : "DOWN"
}
然后在我的main
脚本中实例化环境时
# main.py
import pandas as pd
from stable_baselines.common.vec_env import DummyVecEnv
from stable_baselines.common.policies import MlpLstmPolicy
from stable_baselines import PPO2
from myenv import MyCustomEnv
if __name__ == "__main__":
data = pd.read_csv("my_data.csv").values # numpy array
train_env = DummyVecEnv([lambda: MyCustomEnv(data)])
model = PPO2(MlpLstmPolicy, train_env, verbose=1)
model.learn(total_timesteps=int(1e6))
我是否在这里做了一些错误的事情,这会导致更新之间的时间永远增加?自定义环境似乎不会将数据传递到环境中,因此可能有更好的方法让代理逐步通过静态训练数据环境