Понимание настройки openAI тренажерного зала и гиперпараметра Optuna с помощью многопроцессорной обработки на GPU - PullRequest
0 голосов
/ 13 июня 2019

Я обучаю агента обучения подкреплению, используя openAI stable-baselines . Я также оптимизирую гиперпараметры агентов, используя optuna .

Чтобы ускорить процесс, я использую многопроцессорность в различных вызовах функций. В частности, в SubprocVecEnv и study.optimize, как указано в документах здесь (в соответствии с 1.15.3 и 1.10.4 соответственно).

import numpy as np
from stable_baselines.common.vec_env import SubprocVecEnv
from stable_baselines import PPO2
from stable_baselines.common.policies import MlpLnLstmPolicy
import optuna

n_cpu = 4


def optimize_ppo2(trial):
    """ Learning hyperparamters we want to optimise"""
    return {
        'n_steps': int(trial.suggest_loguniform('n_steps', 16, 2048)),
        'gamma': trial.suggest_loguniform('gamma', 0.9, 0.9999),
        'learning_rate': trial.suggest_loguniform('learning_rate', 1e-5, 1.),
        'ent_coef': trial.suggest_loguniform('ent_coef', 1e-8, 1e-1),
        'cliprange': trial.suggest_uniform('cliprange', 0.1, 0.4),
        'noptepochs': int(trial.suggest_loguniform('noptepochs', 1, 48)),
        'lam': trial.suggest_uniform('lam', 0.8, 1.)
    }


def optimize_agent(trial):
    """ Train the model and optimise
        Optuna maximises the negative log likelihood, so we
        need to negate the reward here
    """
    model_params = optimize_ppo2(trial)
    env = SubprocVecEnv([lambda: gym.make('CartPole-v1') for i in range(n_cpu)])
    model = PPO2(MlpLnLstmPolicy, env, verbose=0, nminibatches=1, **model_params)
    model.learn(10000)

    rewards = []
    n_episodes, reward_sum = 0, 0.0

    obs = env.reset()
    while n_episodes < 4:
        action, _ = model.predict(obs)
        obs, reward, done, _ = env.step(action)
        reward_sum += reward

        if done:
            rewards.append(reward_sum)
            reward_sum = 0.0
            n_episodes += 1
            obs = env.reset()

    last_reward = np.mean(rewards)
    trial.report(-1 * last_reward)

    return -1 * last_reward


if __name__ == '__main__':
    study = optuna.create_study(study_name='cartpol_optuna', storage='sqlite:///params.db', load_if_exists=True)
    study.optimize(optimize_agent, n_trials=1000, n_jobs=4)

Я использую графический процессор в среде Google Colab. Мой вопрос заключается в том, чтобы, используя многопроцессорную обработку в методах SubprocVecEnv и study.optimize, как я могу быть уверен, что настройка гиперпараметра выполняется правильно в бэкэнде? Другими словами, откуда мне знать, что результаты не перезаписываются?

Кроме того, есть ли лучший способ использовать многопроцессорную обработку графических процессоров в этом конкретном случае, когда и SubprocVecEnv, и study.optimize могут работать на нескольких ядрах? (Я не уверен, что создание слишком большого количества потоков в одном и том же процессоре на самом деле замедлит процесс, создавая больше накладных расходов, чем выполнение с меньшим количеством потоков).

1 Ответ

2 голосов
/ 17 июня 2019

Я полагаю, что ваш код имеет ту же проблему, о которой сообщалось здесь . Библиотека stable-baselines использует Tensorflow в качестве основы глубокого обучения, и это может привести к непреднамеренному разделению сеанса Tensorflow между несколькими испытаниями. Испытания пытаются обновить один вычислительный граф одновременно, и они уничтожат граф.

Я думаю, вы можете распараллелить испытания, если вы измените свой код, чтобы использовать отдельные сеансы для испытаний. Или вы можете просто удалить опцию n_jobs из study.optimize.

...