From f8de849bc8206ecdc919d1a140e306384a5e568f Mon Sep 17 00:00:00 2001 From: Hongsheng Zeng Date: Fri, 4 Jan 2019 10:47:06 +0800 Subject: [PATCH] add PPO example (#39) * add PPO example * Update Readme * Update Readme * fix codestyle * Update Readme * refine action mapping * add more unitest case * remove unnecessary params initialize, add more comments, add benchmark result * rename * remove PARL dependence in readme of examples --- README.md | 4 +- examples/DDPG/README.md | 1 - examples/DDPG/mujoco_model.py | 9 +- examples/DDPG/train.py | 18 +- examples/DQN/README.md | 1 - .../README.md | 1 - .../PPO/.benchmark/PPO_HalfCheetah-v2.png | Bin 0 -> 117718 bytes examples/PPO/README.md | 31 +++ examples/PPO/mujoco_agent.py | 194 ++++++++++++++++++ examples/PPO/mujoco_model.py | 96 +++++++++ examples/PPO/train.py | 191 +++++++++++++++++ examples/PPO/utils.py | 88 ++++++++ examples/QuickStart/README.md | 1 - parl/algorithms/__init__.py | 3 +- parl/algorithms/ppo.py | 154 ++++++++++++++ parl/utils/tests/utils_test.py | 35 ++++ parl/utils/utils.py | 20 +- 17 files changed, 827 insertions(+), 20 deletions(-) create mode 100644 examples/PPO/.benchmark/PPO_HalfCheetah-v2.png create mode 100644 examples/PPO/README.md create mode 100644 examples/PPO/mujoco_agent.py create mode 100644 examples/PPO/mujoco_model.py create mode 100755 examples/PPO/train.py create mode 100644 examples/PPO/utils.py create mode 100644 parl/algorithms/ppo.py create mode 100644 parl/utils/tests/utils_test.py diff --git a/README.md b/README.md index 5285edd..35190df 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ PARL

+> PARL is a flexible and high-efficient reinforcement learning framework based on [PaddlePaddle](https://github.com/PaddlePaddle/Paddle). + # Features **Reproducible**. We provide algorithms that stably reproduce the result of many influential reinforcement learning algorithms @@ -76,5 +78,5 @@ pip install --upgrade git+https://github.com/PaddlePaddle/PARL.git - [QuickStart](examples/QuickStart/) - [DQN](examples/DQN/) - [DDPG](examples/DDPG/) -- PPO +- [PPO](examples/PPO/) - [Winning Solution for NIPS2018: AI for Prosthetics Challenge](examples/NeurIPS2018-AI-for-Prosthetics-Challenge/) diff --git a/examples/DDPG/README.md b/examples/DDPG/README.md index 61d3240..3f59971 100644 --- a/examples/DDPG/README.md +++ b/examples/DDPG/README.md @@ -11,7 +11,6 @@ Please see [here](https://github.com/openai/mujoco-py) to know more about Mujoco ## How to use ### Dependencies: + python2.7 or python3.5+ -+ [PARL](https://github.com/PaddlePaddle/PARL) + [paddlepaddle>=1.0.0](https://github.com/PaddlePaddle/Paddle) + gym + tqdm diff --git a/examples/DDPG/mujoco_model.py b/examples/DDPG/mujoco_model.py index 991842d..ae7477b 100644 --- a/examples/DDPG/mujoco_model.py +++ b/examples/DDPG/mujoco_model.py @@ -18,8 +18,8 @@ from parl.framework.model_base import Model class MujocoModel(Model): - def __init__(self, act_dim, act_bound): - self.actor_model = ActorModel(act_dim, act_bound) + def __init__(self, act_dim): + self.actor_model = ActorModel(act_dim) self.critic_model = CriticModel() def policy(self, obs): @@ -33,8 +33,7 @@ class MujocoModel(Model): class ActorModel(Model): - def __init__(self, act_dim, act_bound): - self.act_bound = act_bound + def __init__(self, act_dim): hid1_size = 400 hid2_size = 300 @@ -46,7 +45,7 @@ class ActorModel(Model): hid1 = self.fc1(obs) hid2 = self.fc2(hid1) means = self.fc3(hid2) - means = means * self.act_bound + means = means return means diff --git a/examples/DDPG/train.py b/examples/DDPG/train.py index 4220e05..ba1a826 100644 --- a/examples/DDPG/train.py +++ b/examples/DDPG/train.py @@ -19,7 +19,7 @@ import time from mujoco_agent import MujocoAgent from mujoco_model import MujocoModel from parl.algorithms import DDPG -from parl.utils import logger +from parl.utils import logger, action_mapping from replay_memory import ReplayMemory MAX_EPISODES = 5000 @@ -36,7 +36,7 @@ REWARD_SCALE = 0.1 ENV_SEED = 1 -def run_train_episode(env, agent, rpm, act_bound): +def run_train_episode(env, agent, rpm): obs = env.reset() total_reward = 0 for j in range(MAX_STEPS_EACH_EPISODE): @@ -44,9 +44,10 @@ def run_train_episode(env, agent, rpm, act_bound): action = agent.predict(batch_obs.astype('float32')) action = np.squeeze(action) - # Add exploration noise - action = np.clip( - np.random.normal(action, act_bound), -act_bound, act_bound) + # Add exploration noise, and clip to [-1.0, 1.0] + action = np.clip(np.random.normal(action, 1.0), -1.0, 1.0) + action = action_mapping(action, env.action_space.low[0], + env.action_space.high[0]) next_obs, reward, done, info = env.step(action) @@ -73,6 +74,8 @@ def run_evaluate_episode(env, agent): batch_obs = np.expand_dims(obs, axis=0) action = agent.predict(batch_obs.astype('float32')) action = np.squeeze(action) + action = action_mapping(action, env.action_space.low[0], + env.action_space.high[0]) next_obs, reward, done, info = env.step(action) @@ -90,9 +93,8 @@ def main(): obs_dim = env.observation_space.shape[0] act_dim = env.action_space.shape[0] - act_bound = env.action_space.high[0] - model = MujocoModel(act_dim, act_bound) + model = MujocoModel(act_dim) algorithm = DDPG( model, hyperparas={ @@ -106,7 +108,7 @@ def main(): rpm = ReplayMemory(MEMORY_SIZE, obs_dim, act_dim) for i in range(MAX_EPISODES): - train_reward = run_train_episode(env, agent, rpm, act_bound) + train_reward = run_train_episode(env, agent, rpm) logger.info('Episode: {} Reward: {}'.format(i, train_reward)) if (i + 1) % TEST_EVERY_EPISODES == 0: evaluate_reward = run_evaluate_episode(env, agent) diff --git a/examples/DQN/README.md b/examples/DQN/README.md index 2901737..3bf36b0 100644 --- a/examples/DQN/README.md +++ b/examples/DQN/README.md @@ -11,7 +11,6 @@ Please see [here](https://gym.openai.com/envs/#atari) to know more about Atari g ## How to use ### Dependencies: + python2.7 or python3.5+ -+ [PARL](https://github.com/PaddlePaddle/PARL) + [paddlepaddle>=1.0.0](https://github.com/PaddlePaddle/Paddle) + gym + tqdm diff --git a/examples/NeurIPS2018-AI-for-Prosthetics-Challenge/README.md b/examples/NeurIPS2018-AI-for-Prosthetics-Challenge/README.md index 3f76e55..d7b1c9d 100644 --- a/examples/NeurIPS2018-AI-for-Prosthetics-Challenge/README.md +++ b/examples/NeurIPS2018-AI-for-Prosthetics-Challenge/README.md @@ -5,7 +5,6 @@ This folder will contains the code used to train the winning models for the [Neu ### Dependencies - python3.6 - [paddlepaddle>=1.2.0](https://github.com/PaddlePaddle/Paddle) -- [PARL](https://github.com/PaddlePaddle/PARL) - [osim-rl](https://github.com/stanfordnmbl/osim-rl) ### Start Testing best models diff --git a/examples/PPO/.benchmark/PPO_HalfCheetah-v2.png b/examples/PPO/.benchmark/PPO_HalfCheetah-v2.png new file mode 100644 index 0000000000000000000000000000000000000000..7d0c031367fbb25e14f6ca0eb67bd4606a55ff67 GIT binary patch literal 117718 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

nO|v2>V*%b6>Al; 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

    dn5Vm1kRBlzyzOs{ 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 literal 0 HcmV?d00001 diff --git a/examples/PPO/README.md b/examples/PPO/README.md new file mode 100644 index 0000000..6190f71 --- /dev/null +++ b/examples/PPO/README.md @@ -0,0 +1,31 @@ +## Reproduce PPO with PARL +Based on PARL, the PPO model of deep reinforcement learning is reproduced, and the same level of indicators of the paper is reproduced in the classic Mujoco game. +Include following approach: ++ Clipped Surrogate Objective ++ Adaptive KL Penalty Coefficient + +> PPO in +[Proximal Policy Optimization Algorithms](https://arxiv.org/abs/1707.06347) + +### Mujoco games introduction +Please see [here](https://github.com/openai/mujoco-py) to know more about Mujoco game. + +### Benchmark result +- HalfCheetah-v2 + + +## How to use +### Dependencies: ++ python2.7 or python3.5+ ++ [paddlepaddle>=1.0.0](https://github.com/PaddlePaddle/Paddle) ++ gym ++ tqdm ++ mujoco-py>=1.50.1.0 + +### Start Training: +``` +# To train an agent for HalfCheetah-v2 game (default: CLIP loss) +python train.py + +# To train for different game and different loss type +# python train.py --env [ENV_NAME] --loss_type [CLIP|KLPEN] diff --git a/examples/PPO/mujoco_agent.py b/examples/PPO/mujoco_agent.py new file mode 100644 index 0000000..a1221c6 --- /dev/null +++ b/examples/PPO/mujoco_agent.py @@ -0,0 +1,194 @@ +# Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +import parl.layers as layers +from paddle import fluid +from sklearn.utils import shuffle +from parl.framework.agent_base import Agent +from parl.utils import logger + + +class MujocoAgent(Agent): + def __init__(self, + algorithm, + obs_dim, + act_dim, + kl_targ, + loss_type, + beta=1.0, + epsilon=0.2, + policy_learn_times=20, + value_learn_times=10, + value_batch_size=256): + self.alg = algorithm + self.obs_dim = obs_dim + self.act_dim = act_dim + assert loss_type == 'CLIP' or loss_type == 'KLPEN' + self.loss_type = loss_type + super(MujocoAgent, self).__init__(algorithm) + + self.policy_learn_times = policy_learn_times + # Adaptive kl penalty coefficient + self.beta = beta + self.kl_targ = kl_targ + + self.value_learn_times = value_learn_times + self.value_batch_size = value_batch_size + self.value_learn_buffer = None + + def build_program(self): + self.policy_predict_program = fluid.Program() + self.policy_sample_program = fluid.Program() + self.policy_learn_program = fluid.Program() + self.value_predict_program = fluid.Program() + self.value_learn_program = fluid.Program() + + with fluid.program_guard(self.policy_sample_program): + obs = layers.data( + name='obs', shape=[self.obs_dim], dtype='float32') + sampled_act = self.alg.define_sample(obs) + self.policy_sample_output = [sampled_act] + + with fluid.program_guard(self.policy_predict_program): + obs = layers.data( + name='obs', shape=[self.obs_dim], dtype='float32') + means = self.alg.define_predict(obs) + self.policy_predict_output = [means] + + with fluid.program_guard(self.policy_learn_program): + obs = layers.data( + name='obs', shape=[self.obs_dim], dtype='float32') + actions = layers.data( + name='actions', shape=[self.act_dim], dtype='float32') + advantages = layers.data( + name='advantages', shape=[1], dtype='float32') + if self.loss_type == 'KLPEN': + beta = layers.data(name='beta', shape=[], dtype='float32') + loss, kl = self.alg.define_policy_learn( + obs, actions, advantages, beta) + else: + loss, kl = self.alg.define_policy_learn( + obs, actions, advantages) + + self.policy_learn_output = [loss, kl] + + with fluid.program_guard(self.value_predict_program): + obs = layers.data( + name='obs', shape=[self.obs_dim], dtype='float32') + value = self.alg.define_value_predict(obs) + self.value_predict_output = [value] + + with fluid.program_guard(self.value_learn_program): + obs = layers.data( + name='obs', shape=[self.obs_dim], dtype='float32') + val = layers.data(name='val', shape=[], dtype='float32') + value_loss = self.alg.define_value_learn(obs, val) + self.value_learn_output = [value_loss] + + def policy_sample(self, obs): + feed = {'obs': obs} + sampled_act = self.fluid_executor.run( + self.policy_sample_program, + feed=feed, + fetch_list=self.policy_sample_output)[0] + return sampled_act + + def policy_predict(self, obs): + feed = {'obs': obs} + means = self.fluid_executor.run( + self.policy_predict_program, + feed=feed, + fetch_list=self.policy_predict_output)[0] + return means + + def value_predict(self, obs): + feed = {'obs': obs} + value = self.fluid_executor.run( + self.value_predict_program, + feed=feed, + fetch_list=self.value_predict_output)[0] + return value + + def _batch_policy_learn(self, obs, actions, advantages): + if self.loss_type == 'KLPEN': + feed = { + 'obs': obs, + 'actions': actions, + 'advantages': advantages, + 'beta': self.beta + } + else: + feed = {'obs': obs, 'actions': actions, 'advantages': advantages} + [loss, kl] = self.fluid_executor.run( + self.policy_learn_program, + feed=feed, + fetch_list=self.policy_learn_output) + return loss, kl + + def _batch_value_learn(self, obs, val): + feed = {'obs': obs, 'val': val} + value_loss = self.fluid_executor.run( + self.value_learn_program, + feed=feed, + fetch_list=self.value_learn_output)[0] + return value_loss + + def policy_learn(self, obs, actions, advantages): + """ Learn policy: + + 1. Sync parameters of policy model to old policy model + 2. Fix old policy model, and learn policy model multi times + 3. if use KLPEN loss, Adjust kl loss coefficient: beta + """ + self.alg.sync_old_policy(self.gpu_id) + + all_loss, all_kl = [], [] + for _ in range(self.policy_learn_times): + loss, kl = self._batch_policy_learn(obs, actions, advantages) + all_loss.append(loss) + all_kl.append(kl) + + if self.loss_type == 'KLPEN': + # Adative KL penalty coefficient + if kl > self.kl_targ * 2: + self.beta = 1.5 * self.beta + elif kl < self.kl_targ / 2: + self.beta = self.beta / 1.5 + + return np.mean(all_loss), np.mean(all_kl) + + def value_learn(self, obs, value): + """ Fit model to current data batch + previous data batch + """ + data_size = obs.shape[0] + + if self.value_learn_buffer is None: + obs_train, value_train = obs, value + else: + obs_train = np.concatenate([obs, self.value_learn_buffer[0]]) + value_train = np.concatenate([value, self.value_learn_buffer[1]]) + self.value_learn_buffer = (obs, value) + + all_loss = [] + for _ in range(self.value_learn_times): + obs_train, value_train = shuffle(obs_train, value_train) + start = 0 + while start < data_size: + end = start + self.value_batch_size + value_loss = self._batch_value_learn(obs_train[start:end, :], + value_train[start:end]) + all_loss.append(value_loss) + start += self.value_batch_size + return np.mean(all_loss) diff --git a/examples/PPO/mujoco_model.py b/examples/PPO/mujoco_model.py new file mode 100644 index 0000000..9c97525 --- /dev/null +++ b/examples/PPO/mujoco_model.py @@ -0,0 +1,96 @@ +# Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +import parl.layers as layers +from paddle import fluid +from paddle.fluid.param_attr import ParamAttr +from parl.framework.model_base import Model + + +class MujocoModel(Model): + def __init__(self, obs_dim, act_dim, init_logvar=-1.0): + self.policy_model = PolicyModel(obs_dim, act_dim, init_logvar) + self.value_model = ValueModel(obs_dim, act_dim) + self.policy_lr = self.policy_model.lr + self.value_lr = self.value_model.lr + + def policy(self, obs): + return self.policy_model.policy(obs) + + def policy_sample(self, obs): + return self.policy_model.sample(obs) + + def value(self, obs): + return self.value_model.value(obs) + + +class PolicyModel(Model): + def __init__(self, obs_dim, act_dim, init_logvar): + self.obs_dim = obs_dim + self.act_dim = act_dim + hid1_size = obs_dim * 10 + hid3_size = act_dim * 10 + hid2_size = int(np.sqrt(hid1_size * hid3_size)) + + self.lr = 9e-4 / np.sqrt(hid2_size) + + self.fc1 = layers.fc(size=hid1_size, act='tanh') + self.fc2 = layers.fc(size=hid2_size, act='tanh') + self.fc3 = layers.fc(size=hid3_size, act='tanh') + self.fc4 = layers.fc(size=act_dim, act='tanh') + + self.logvars = layers.create_parameter( + shape=[act_dim], + dtype='float32', + default_initializer=fluid.initializer.ConstantInitializer( + init_logvar)) + + def policy(self, obs): + hid1 = self.fc1(obs) + hid2 = self.fc2(hid1) + hid3 = self.fc3(hid2) + means = self.fc4(hid3) + logvars = self.logvars() + return means, logvars + + def sample(self, obs): + means, logvars = self.policy(obs) + sampled_act = means + ( + layers.exp(logvars / 2.0) * # stddev + layers.gaussian_random(shape=(self.act_dim, ), dtype='float32')) + return sampled_act + + +class ValueModel(Model): + def __init__(self, obs_dim, act_dim): + super(ValueModel, self).__init__() + hid1_size = obs_dim * 10 + hid3_size = 5 + hid2_size = int(np.sqrt(hid1_size * hid3_size)) + + self.lr = 1e-2 / np.sqrt(hid2_size) + + self.fc1 = layers.fc(size=hid1_size, act='tanh') + self.fc2 = layers.fc(size=hid2_size, act='tanh') + self.fc3 = layers.fc(size=hid3_size, act='tanh') + self.fc4 = layers.fc(size=1) + + def value(self, obs): + hid1 = self.fc1(obs) + hid2 = self.fc2(hid1) + hid3 = self.fc3(hid2) + V = self.fc4(hid3) + V = layers.squeeze(V, axes=[]) + return V diff --git a/examples/PPO/train.py b/examples/PPO/train.py new file mode 100755 index 0000000..35d9aa7 --- /dev/null +++ b/examples/PPO/train.py @@ -0,0 +1,191 @@ +# Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import argparse +import gym +import numpy as np +from mujoco_agent import MujocoAgent +from mujoco_model import MujocoModel +from parl.algorithms import PPO +from parl.utils import logger, action_mapping +from utils import * + + +def run_train_episode(env, agent, scaler): + obs = env.reset() + observes, actions, rewards, unscaled_obs = [], [], [], [] + done = False + step = 0.0 + scale, offset = scaler.get() + scale[-1] = 1.0 # don't scale time step feature + offset[-1] = 0.0 # don't offset time step feature + while not done: + obs = obs.reshape((1, -1)) + obs = np.append(obs, [[step]], axis=1) # add time step feature + unscaled_obs.append(obs) + obs = (obs - offset) * scale # center and scale observations + obs = obs.astype('float32') + observes.append(obs) + + action = agent.policy_sample(obs) + action = np.clip(action, -1.0, 1.0) + action = action_mapping(action, env.action_space.low[0], + env.action_space.high[0]) + + action = action.reshape((1, -1)).astype('float32') + actions.append(action) + + obs, reward, done, _ = env.step(np.squeeze(action)) + rewards.append(reward) + step += 1e-3 # increment time step feature + + return (np.concatenate(observes), np.concatenate(actions), + np.array(rewards, dtype='float32'), np.concatenate(unscaled_obs)) + + +def run_evaluate_episode(env, agent, scaler): + obs = env.reset() + rewards = [] + step = 0.0 + scale, offset = scaler.get() + scale[-1] = 1.0 # don't scale time step feature + offset[-1] = 0.0 # don't offset time step feature + while True: + obs = obs.reshape((1, -1)) + obs = np.append(obs, [[step]], axis=1) # add time step feature + obs = (obs - offset) * scale # center and scale observations + obs = obs.astype('float32') + + action = agent.policy_predict(obs) + action = action_mapping(action, env.action_space.low[0], + env.action_space.high[0]) + + obs, reward, done, _ = env.step(np.squeeze(action)) + rewards.append(reward) + + step += 1e-3 # increment time step feature + if done: + break + return np.sum(rewards) + + +def collect_trajectories(env, agent, scaler, episodes): + all_obs, all_actions, all_rewards, all_unscaled_obs = [], [], [], [] + for e in range(episodes): + obs, actions, rewards, unscaled_obs = run_train_episode( + env, agent, scaler) + all_obs.append(obs) + all_actions.append(actions) + all_rewards.append(rewards) + all_unscaled_obs.append(unscaled_obs) + scaler.update(np.concatenate(all_unscaled_obs) + ) # update running statistics for scaling observations + return np.concatenate(all_obs), np.concatenate( + all_actions), np.concatenate(all_rewards) + + +def main(): + env = gym.make(args.env) + + obs_dim = env.observation_space.shape[0] + act_dim = env.action_space.shape[0] + obs_dim += 1 # add 1 to obs dim for time step feature + + scaler = Scaler(obs_dim) + + model = MujocoModel(obs_dim, act_dim) + hyperparas = { + 'act_dim': act_dim, + 'policy_lr': model.policy_lr, + 'value_lr': model.value_lr + } + alg = PPO(model, hyperparas) + agent = MujocoAgent( + alg, obs_dim, act_dim, args.kl_targ, loss_type=args.loss_type) + + # run a few episodes to initialize scaler + collect_trajectories(env, agent, scaler, episodes=5) + + episode = 0 + while episode < args.num_episodes: + obs, actions, rewards = collect_trajectories( + env, agent, scaler, episodes=args.episodes_per_batch) + episode += args.episodes_per_batch + + pred_values = agent.value_predict(obs) + + # scale rewards + scale_rewards = rewards * (1 - args.gamma) + + discount_sum_rewards = calc_discount_sum_rewards( + scale_rewards, args.gamma) + discount_sum_rewards = discount_sum_rewards.astype('float32') + + advantages = calc_gae(scale_rewards, pred_values, args.gamma, args.lam) + # normalize advantages + advantages = (advantages - advantages.mean()) / ( + advantages.std() + 1e-6) + advantages = advantages.astype('float32') + + policy_loss, kl = agent.policy_learn(obs, actions, advantages) + value_loss = agent.value_learn(obs, discount_sum_rewards) + + logger.info( + 'Episode {}, Train reward: {}, Policy loss: {}, KL: {}, Value loss: {}' + .format(episode, + np.sum(rewards) / args.episodes_per_batch, policy_loss, kl, + value_loss)) + if episode % (args.episodes_per_batch * 5) == 0: + eval_reward = run_evaluate_episode(env, agent, scaler) + logger.info('Episode {}, Evaluate reward: {}'.format( + episode, eval_reward)) + + +if __name__ == "__main__": + + parser = argparse.ArgumentParser() + parser.add_argument( + '--env', + type=str, + help='Mujoco environment name', + default='HalfCheetah-v2') + parser.add_argument( + '--num_episodes', + type=int, + help='Number of episodes to run', + default=10000) + parser.add_argument( + '--gamma', type=float, help='Discount factor', default=0.995) + parser.add_argument( + '--lam', + type=float, + help='Lambda for Generalized Advantage Estimation', + default=0.98) + parser.add_argument( + '--kl_targ', type=float, help='D_KL target value', default=0.003) + parser.add_argument( + '--episodes_per_batch', + type=int, + help='Number of episodes per training batch', + default=5) + parser.add_argument( + '--loss_type', + type=str, + help="Choose loss type of PPO algorithm, 'CLIP' or 'KLPEN'", + default='CLIP') + + args = parser.parse_args() + import time + logger.set_dir('./log_dir/{}_{}'.format(args.loss_type, time.time())) + main() diff --git a/examples/PPO/utils.py b/examples/PPO/utils.py new file mode 100644 index 0000000..48de072 --- /dev/null +++ b/examples/PPO/utils.py @@ -0,0 +1,88 @@ +# Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +import scipy.signal + +__all__ = ['calc_discount_sum_rewards', 'calc_gae', 'Scaler'] +""" +The following code are copied or modified from: + https://github.com/pat-coady/trpo + Written by Patrick Coady (pat-coady.github.io) +""" + + +def calc_discount_sum_rewards(rewards, gamma): + """ Calculate discounted forward sum of a sequence at each point """ + return scipy.signal.lfilter([1.0], [1.0, -gamma], rewards[::-1])[::-1] + + +def calc_gae(rewards, values, gamma, lam): + """ Calculate generalized advantage estimator. + See: https://arxiv.org/pdf/1506.02438.pdf + """ + # temporal differences + tds = rewards - values + np.append(values[1:] * gamma, 0) + advantages = calc_discount_sum_rewards(tds, gamma * lam) + return advantages + + +class Scaler(object): + """ Generate scale and offset based on running mean and stddev along axis=0 + + offset = running mean + scale = 1 / (stddev + 0.1) / 3 (i.e. 3x stddev = +/- 1.0) + """ + + def __init__(self, obs_dim): + """ + Args: + obs_dim: dimension of axis=1 + """ + self.vars = np.zeros(obs_dim) + self.means = np.zeros(obs_dim) + self.cnt = 0 + self.first_pass = True + + def update(self, x): + """ Update running mean and variance (this is an exact method) + Args: + x: NumPy array, shape = (N, obs_dim) + + see: https://stats.stackexchange.com/questions/43159/how-to-calculate-pooled- + variance-of-two-groups-given-known-group-variances-mean + """ + if self.first_pass: + self.means = np.mean(x, axis=0) + self.vars = np.var(x, axis=0) + self.cnt = x.shape[0] + self.first_pass = False + else: + n = x.shape[0] + new_data_var = np.var(x, axis=0) + new_data_mean = np.mean(x, axis=0) + new_data_mean_sq = np.square(new_data_mean) + new_means = ( + (self.means * self.cnt) + (new_data_mean * n)) / (self.cnt + n) + self.vars = (((self.cnt * (self.vars + np.square(self.means))) + + (n * (new_data_var + new_data_mean_sq))) / + (self.cnt + n) - np.square(new_means)) + self.vars = np.maximum( + 0.0, self.vars) # occasionally goes negative, clip + self.means = new_means + self.cnt += n + + def get(self): + """ returns 2-tuple: (scale, offset) """ + return 1 / (np.sqrt(self.vars) + 0.1) / 3, self.means diff --git a/examples/QuickStart/README.md b/examples/QuickStart/README.md index c3558e4..39cdd8c 100644 --- a/examples/QuickStart/README.md +++ b/examples/QuickStart/README.md @@ -5,7 +5,6 @@ Based on PARL, train a agent to play CartPole game with policy gradient algorith ### Dependencies: + python2.7 or python3.5+ -+ [PARL](https://github.com/PaddlePaddle/PARL) + [paddlepaddle>=1.0.0](https://github.com/PaddlePaddle/Paddle) + gym diff --git a/parl/algorithms/__init__.py b/parl/algorithms/__init__.py index 182e401..16f032e 100644 --- a/parl/algorithms/__init__.py +++ b/parl/algorithms/__init__.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from parl.algorithms.ddpg import * from parl.algorithms.dqn import * from parl.algorithms.policy_gradient import * -from parl.algorithms.ddpg import * +from parl.algorithms.ppo import * diff --git a/parl/algorithms/ppo.py b/parl/algorithms/ppo.py new file mode 100644 index 0000000..cf7b403 --- /dev/null +++ b/parl/algorithms/ppo.py @@ -0,0 +1,154 @@ +# Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +import parl.layers as layers +from copy import deepcopy +from paddle import fluid +from parl.framework.algorithm_base import Algorithm + +__all__ = ['PPO'] + + +class PPO(Algorithm): + def __init__(self, model, hyperparas): + Algorithm.__init__(self, model, hyperparas) + # Used to calculate probability of action in old policy + self.old_policy_model = deepcopy(model.policy_model) + + # fetch hyper parameters + self.act_dim = hyperparas['act_dim'] + self.policy_lr = hyperparas['policy_lr'] + self.value_lr = hyperparas['value_lr'] + if 'epsilon' in hyperparas: + self.epsilon = hyperparas['epsilon'] + else: + self.epsilon = 0.2 # default + + def _calc_logprob(self, actions, means, logvars): + """ Calculate log probabilities of actions, when given means and logvars + of normal distribution. + The constant sqrt(2 * pi) is omitted, which will be eliminated in later. + + Args: + actions: shape (batch_size, act_dim) + means: shape (batch_size, act_dim) + logvars: shape (act_dim) + + Returns: + logprob: shape (batch_size) + """ + exp_item = layers.elementwise_div( + layers.square(actions - means), layers.exp(logvars), axis=1) + exp_item = -0.5 * layers.reduce_sum(exp_item, dim=1) + + vars_item = -0.5 * layers.reduce_sum(logvars) + logprob = exp_item + vars_item + return logprob + + def _calc_kl(self, means, logvars, old_means, old_logvars): + """ Calculate KL divergence between old and new distributions + See: https://en.wikipedia.org/wiki/Multivariate_normal_distribution#Kullback.E2.80.93Leibler_divergence + + Args: + means: shape (batch_size, act_dim) + logvars: shape (act_dim) + old_means: shape (batch_size, act_dim) + old_logvars: shape (act_dim) + + Returns: + kl: shape (batch_size) + """ + log_det_cov_old = layers.reduce_sum(old_logvars) + log_det_cov_new = layers.reduce_sum(logvars) + tr_old_new = layers.reduce_sum(layers.exp(old_logvars - logvars)) + kl = 0.5 * (layers.reduce_sum( + layers.square(means - old_means) / layers.exp(logvars), dim=1) + ( + log_det_cov_new - log_det_cov_old) + tr_old_new - self.act_dim) + return kl + + def define_predict(self, obs): + """ Use policy model of self.model to predict means and logvars of actions + """ + means, logvars = self.model.policy(obs) + return means + + def define_sample(self, obs): + """ Use policy model of self.model to sample actions + """ + sampled_act = self.model.policy_sample(obs) + return sampled_act + + def define_policy_learn(self, obs, actions, advantages, beta=None): + """ Learn policy model with: + 1. CLIP loss: Clipped Surrogate Objective + 2. KLPEN loss: Adaptive KL Penalty Objective + See: https://arxiv.org/pdf/1707.02286.pdf + + Args: + obs: Tensor, (batch_size, obs_dim) + actions: Tensor, (batch_size, act_dim) + advantages: Tensor (batch_size, ) + beta: Tensor (1) or None + if None, use CLIP Loss; else, use KLPEN loss. + """ + old_means, old_logvars = self.old_policy_model.policy(obs) + old_means.stop_gradient = True + old_logvars.stop_gradient = True + old_logprob = self._calc_logprob(actions, old_means, old_logvars) + + means, logvars = self.model.policy(obs) + logprob = self._calc_logprob(actions, means, logvars) + + kl = self._calc_kl(means, logvars, old_means, old_logvars) + kl = layers.reduce_mean(kl) + + if beta is None: # Clipped Surrogate Objective + pg_ratio = layers.exp(logprob - old_logprob) + clipped_pg_ratio = layers.clip(pg_ratio, 1 - self.epsilon, + 1 + self.epsilon) + surrogate_loss = layers.elementwise_min( + advantages * pg_ratio, advantages * clipped_pg_ratio) + loss = 0 - layers.reduce_mean(surrogate_loss) + else: # Adaptive KL Penalty Objective + # policy gradient loss + loss1 = 0 - layers.reduce_mean( + advantages * layers.exp(logprob - old_logprob)) + # adaptive kl loss + loss2 = kl * beta + loss = loss1 + loss2 + optimizer = fluid.optimizer.AdamOptimizer(self.policy_lr) + optimizer.minimize(loss) + return loss, kl + + def define_value_predict(self, obs): + """ Use value model of self.model to predict value of obs + """ + return self.model.value(obs) + + def define_value_learn(self, obs, val): + """ Learn value model with square error cost + """ + predict_val = self.model.value(obs) + loss = layers.square_error_cost(predict_val, val) + loss = layers.reduce_mean(loss) + optimizer = fluid.optimizer.AdamOptimizer(self.value_lr) + optimizer.minimize(loss) + return loss + + def sync_old_policy(self, gpu_id): + """ Synchronize parameters of self.model.policy_model to self.old_policy_model + """ + self.model.policy_model.sync_params_to( + self.old_policy_model, gpu_id=gpu_id) diff --git a/parl/utils/tests/utils_test.py b/parl/utils/tests/utils_test.py new file mode 100644 index 0000000..d5811b2 --- /dev/null +++ b/parl/utils/tests/utils_test.py @@ -0,0 +1,35 @@ +# Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import numpy as np +import unittest +from parl.utils import action_mapping + + +class TestUtils(unittest.TestCase): + def test_action_mapping(self): + origin_act = np.array([-1.0, 0.0, 1.0]) + + mapped_act = action_mapping(origin_act, 0.0, 1.0) + self.assertListEqual(list(mapped_act), [0.0, 0.5, 1.0]) + + mapped_act = action_mapping(origin_act, -2.0, 2.0) + self.assertListEqual(list(mapped_act), [-2.0, 0.0, 2.0]) + + mapped_act = action_mapping(origin_act, -5.0, 10.0) + self.assertListEqual(list(mapped_act), [-5.0, 2.5, 10.0]) + + +if __name__ == '__main__': + unittest.main() diff --git a/parl/utils/utils.py b/parl/utils/utils.py index b9e5026..94e1ab6 100644 --- a/parl/utils/utils.py +++ b/parl/utils/utils.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -__all__ = ['has_func'] +__all__ = ['has_func', 'action_mapping'] def has_func(obj, fun): @@ -26,3 +26,21 @@ def has_func(obj, fun): """ check_fun = getattr(obj, fun, None) return callable(check_fun) + + +def action_mapping(model_output_act, low_bound, high_bound): + """ mapping action space [-1, 1] of model output + to new action space [low_bound, high_bound]. + + Args: + model_output_act: np.array, which value is in [-1, 1] + low_bound: float, low bound of env action space + high_bound: float, high bound of env action space + + Returns: + action: np.array, which value is in [low_bound, high_bound] + """ + assert high_bound > low_bound + action = low_bound + (model_output_act - (-1.0)) * ( + (high_bound - low_bound) / 2.0) + return action -- GitLab