将训练数据传递到自定义openai-gym环境中的正确方法是什么?

时间:2019-11-21 18:46:56

标签: python reinforcement-learning openai-gym

我正在创建自定义DeMorgan's laws,类似于gym environmentthis trading one。正在设置自定义环境,以使用this soccer one来训练PPO强化学习模型。

我的问题是,批量更新之间的时间(逐步通过环境和收集奖励所花费的时间)花费的时间越来越长,并且每次更新线性扩展大约1-5秒。刚开始时,这是有道理的,因为未经训练的特工很快就会“死亡”(done=True,所以这一集结束了)。随着特工训练,它应该生存更长的时间,直到它开始生存整个情节,并且两次更新之间的时间应该达到稳定。但是,即使经过数百次更新(数百集,环境中成千上万个连续步骤),两次更新之间的时间仍在增加。我已经监视了培训,可以看到该代理在大约50次更新中幸存下来。

起初,我认为环境中的某些变量可能会持续存在并且在两次更新之间变得非常大,从而减慢了计算时间。但是,当我在训练期间监视内存使用情况时,它在整个过程中保持不变。考虑到环境应该重置每个情节(并将所有列表变量初始化为空),从理论上讲,增加变量的大小不是问题。

已经说过,也许我没有将数据正确地传递到MyCustomEnv中。当我将整个训练数据集读入内存(1e6个样本)时,我希望每次发作只将一批stable-baselines传递给环境,但是我可能是错的(我已经设定了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))

我在这里做错什么会导致两次更新之间的时间永远增加吗?自定义n_steps环境似乎不会将数据传递到该环境中,因此也许有一种更好的方法可以让代理逐步通过静态训练数据环境。

0 个答案:

没有答案