Почему средняя награда за эпизод во время тренировки остается на уровне +100?
Я хочу создать класс обратного вызова, который проверяет каждые 200 шагов обучения, увеличилось ли среднее вознаграждение за эпизод модели, и если да, то сохраняет его. Я знаю, что уже существуетEvalCallback()
класс в stable-baselines
библиотека, но я пытаюсь закодировать свой обратный вызов.
Я застрял на этом этапе, и мои результаты показывают, что средняя награда за эпизод модели не превышает 100. Почему это так? Это происходит при каждом запуске.
Это мой код:
class EvalCallback(BaseCallback):
"""
Callback for evaluating an agent.
:param eval_env: (gym.Env) The environment used for initialization
:param n_eval_episodes: (int) The number of episodes to test the agent
:param eval_freq: (int) Evaluate the agent every eval_freq call of the callback.
"""
def __init__(self, eval_env, n_eval_episodes=5, eval_freq=200, verbose=1):
super(EvalCallback, self).__init__(verbose)
self.eval_env = eval_env
self.n_eval_episodes = n_eval_episodes
self.eval_freq = eval_freq
self.best_mean_reward = -np.inf
self.save_path = os.path.join(log_dir, 'exercise_best_model')
def _on_step(self) -> bool:
"""
This method will be called by the model.
:return: (bool)
"""
# self.n_calls is automatically updated because
# we derive from BaseCallback
if self.n_calls % self.eval_freq == 0:
# Evaluate the agent:
done = False
all_episode_rewards = []
obs = self.eval_env.reset()
for _ in range(self.n_eval_episodes):
episode_rewards = []
while not done:
action, _states = self.model.predict(obs, deterministic=True)
obs, reward, done, info = self.eval_env.step(action)
episode_rewards.append(reward)
all_episode_rewards.append(sum(episode_rewards))
# Save the agent if needed
# and update self.best_mean_reward
mean_reward = np.mean(all_episode_rewards)
if mean_reward > self.best_mean_reward:
self.best_mean_reward = mean_reward
self.model.save(self.save_path)
if self.verbose > 0:
print("Best mean reward: {:.2f}".format(self.best_mean_reward))
print("Saving new best model to {}.zip".format(self.save_path))
print('-' * 30)
# ====================== #
return True
И вот как я инициализирую env и модель:
# Env used for training
env = gym.make("CartPole-v1")
# Env for evaluating the agent
eval_env = gym.make("CartPole-v1")
# Create the callback object
callback = EvalCallback(eval_env, verbose=1)
# Create the RL model
model = PPO2('MlpPolicy', env, verbose=0)
# Train the RL model
model.learn(100000, callback=callback)
Результат такой:
Best mean reward: 13.80
Saving new best model to /tmp/gym/exercise_best_model.zip
------------------------------
Best mean reward: 18.20
Saving new best model to /tmp/gym/exercise_best_model.zip
------------------------------
Best mean reward: 20.80
Saving new best model to /tmp/gym/exercise_best_model.zip
------------------------------
Best mean reward: 100.00
Saving new best model to /tmp/gym/exercise_best_model.zip
------------------------------
<stable_baselines.ppo2.ppo2.PPO2 at 0x7f1c15095438>
РЕДАКТИРОВАТЬ:
Я пробовал другую реализацию. В этом случае модель достигает наилучшего среднего вознаграждения в 500.00. Насколько мне известноevaluate_policy()
функция работает так же, как и моя реализация выше, но, очевидно, это не может быть правдой.
## 2nd IMPLEMENTATION
## -------------------
class EvalCallback(BaseCallback):
"""
Callback for evaluating an agent.
:param eval_env: (gym.Env) The environment used for initialization
:param n_eval_episodes: (int) The number of episodes to test the agent
:param eval_freq: (int) Evaluate the agent every eval_freq call of the callback.
"""
def __init__(self, eval_env, n_eval_episodes=5, eval_freq=200, verbose=1):
super(EvalCallback, self).__init__(verbose)
self.eval_env = eval_env
self.n_eval_episodes = n_eval_episodes
self.eval_freq = eval_freq
self.best_mean_reward = -np.inf
self.save_path = os.path.join(log_dir, 'exercise_best_model')
def _on_step(self) -> bool:
"""
This method will be called by the model.
:return: (bool)
"""
# self.n_calls is automatically updated because
# we derive from BaseCallback
if self.n_calls % self.eval_freq == 0:
episode_rewards, episode_lengths = evaluate_policy(self.model, self.eval_env,
n_eval_episodes=self.n_eval_episodes,
deterministic=True,
return_episode_rewards=True)
mean_reward = np.mean(episode_rewards)
# Save the agent if needed
# and update self.best_mean_reward
if mean_reward > self.best_mean_reward:
self.best_mean_reward = mean_reward
self.model.save(self.save_path)
if self.verbose > 0:
print("Best mean reward: {:.2f}".format(self.best_mean_reward))
print("Saving new best model to {}.zip".format(self.save_path))
print('-' * 30)
return True