From 77068af526e109298d3e7b245f6a9a8904c52b8a Mon Sep 17 00:00:00 2001 From: Minghao Zhang <37171450+Mehooz@users.noreply.github.com> Date: Sat, 28 Mar 2020 07:27:18 +0800 Subject: [PATCH] add examples, fix some bugs (#5) * update atari.py * fix setup.py pass the pytest * fix setup.py pass the pytest * add args "render" * change the tensorboard writter * change the tensorboard writter * change device, render, tensorboard log location * change device, render, tensorboard log location * remove some wrong local files * fix some tab mistakes and the envs name in continuous/test_xx.py * add examples and point robot maze environment * fix some bugs during testing examples * add dqn network and fix some args * change back the tensorboard writter's frequency to ensure ppo and a2c can write things normally * add a warning to collector * rm some unrelated files * reformat * fix a bug in test_dqn due to the model wrong selection --- docs/_static/images/Ant-v2.png | Bin 0 -> 187260 bytes examples/ant_v2_ddpg.py | 105 +++++++++++++++++++++++++++++ examples/ant_v2_sac.py | 110 ++++++++++++++++++++++++++++++ examples/ant_v2_td3.py | 114 +++++++++++++++++++++++++++++++ examples/continuous_net.py | 79 ++++++++++++++++++++++ examples/discrete_net.py | 81 ++++++++++++++++++++++ examples/point_maze_td3.py | 119 +++++++++++++++++++++++++++++++++ examples/pong_a2c.py | 108 ++++++++++++++++++++++++++++++ examples/pong_dqn.py | 112 +++++++++++++++++++++++++++++++ examples/pong_ppo.py | 112 +++++++++++++++++++++++++++++++ setup.py | 1 + test/continuous/test_ddpg.py | 7 +- test/continuous/test_ppo.py | 7 +- test/continuous/test_sac.py | 7 +- test/continuous/test_td3.py | 7 +- test/discrete/net.py | 30 +++++++++ test/discrete/test_a2c.py | 8 ++- test/discrete/test_dqn.py | 7 +- test/discrete/test_pg.py | 7 +- test/discrete/test_ppo.py | 7 +- tianshou/data/batch.py | 2 +- tianshou/data/collector.py | 10 ++- tianshou/exploration/random.py | 2 +- tianshou/policy/a2c.py | 1 + tianshou/policy/pg.py | 3 + tianshou/policy/ppo.py | 6 +- tianshou/trainer/offpolicy.py | 6 +- tianshou/trainer/onpolicy.py | 8 +-- 28 files changed, 1031 insertions(+), 35 deletions(-) create mode 100644 docs/_static/images/Ant-v2.png create mode 100644 examples/ant_v2_ddpg.py create mode 100644 examples/ant_v2_sac.py create mode 100644 examples/ant_v2_td3.py create mode 100644 examples/continuous_net.py create mode 100644 examples/discrete_net.py create mode 100644 examples/point_maze_td3.py create mode 100644 examples/pong_a2c.py create mode 100644 examples/pong_dqn.py create mode 100644 examples/pong_ppo.py diff --git a/docs/_static/images/Ant-v2.png b/docs/_static/images/Ant-v2.png new file mode 100644 index 0000000000000000000000000000000000000000..b5497592a3b01223e72f552d7665dcd07b6e11d9 GIT binary patch literal 187260 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%0Dy_n@4s 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 Q>et*=*S%eG%R1!$09c=SUH||9 literal 0 HcmV?d00001 diff --git a/examples/ant_v2_ddpg.py b/examples/ant_v2_ddpg.py new file mode 100644 index 0000000..93f2d98 --- /dev/null +++ b/examples/ant_v2_ddpg.py @@ -0,0 +1,105 @@ +import gym +import torch +import pprint +import argparse +import numpy as np +from torch.utils.tensorboard import SummaryWriter + +from tianshou.policy import DDPGPolicy +from tianshou.trainer import offpolicy_trainer +from tianshou.data import Collector, ReplayBuffer +from tianshou.env import VectorEnv, SubprocVectorEnv + +if __name__ == '__main__': + from continuous_net import Actor, Critic +else: # pytest + from test.continuous.net import Actor, Critic + + +def get_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--task', type=str, default='Ant-v2') + parser.add_argument('--seed', type=int, default=1626) + parser.add_argument('--buffer-size', type=int, default=20000) + parser.add_argument('--actor-lr', type=float, default=1e-4) + parser.add_argument('--critic-lr', type=float, default=1e-3) + parser.add_argument('--gamma', type=float, default=0.99) + parser.add_argument('--tau', type=float, default=0.005) + parser.add_argument('--exploration-noise', type=float, default=0.1) + parser.add_argument('--epoch', type=int, default=100) + parser.add_argument('--step-per-epoch', type=int, default=2400) + parser.add_argument('--collect-per-step', type=int, default=4) + parser.add_argument('--batch-size', type=int, default=128) + parser.add_argument('--layer-num', type=int, default=1) + parser.add_argument('--training-num', type=int, default=8) + parser.add_argument('--test-num', type=int, default=100) + parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) + parser.add_argument( + '--device', type=str, + default='cuda' if torch.cuda.is_available() else 'cpu') + args = parser.parse_known_args()[0] + return args + + +def test_ddpg(args=get_args()): + env = gym.make(args.task) + args.state_shape = env.observation_space.shape or env.observation_space.n + args.action_shape = env.action_space.shape or env.action_space.n + args.max_action = env.action_space.high[0] + # train_envs = gym.make(args.task) + train_envs = VectorEnv( + [lambda: gym.make(args.task) for _ in range(args.training_num)]) + # test_envs = gym.make(args.task) + test_envs = SubprocVectorEnv( + [lambda: gym.make(args.task) for _ in range(args.test_num)]) + # seed + np.random.seed(args.seed) + torch.manual_seed(args.seed) + train_envs.seed(args.seed) + test_envs.seed(args.seed) + # model + actor = Actor( + args.layer_num, args.state_shape, args.action_shape, + args.max_action, args.device + ).to(args.device) + actor_optim = torch.optim.Adam(actor.parameters(), lr=args.actor_lr) + critic = Critic( + args.layer_num, args.state_shape, args.action_shape, args.device + ).to(args.device) + critic_optim = torch.optim.Adam(critic.parameters(), lr=args.critic_lr) + policy = DDPGPolicy( + actor, actor_optim, critic, critic_optim, + args.tau, args.gamma, args.exploration_noise, + [env.action_space.low[0], env.action_space.high[0]], + reward_normalization=True, ignore_done=True) + # collector + train_collector = Collector( + policy, train_envs, ReplayBuffer(args.buffer_size)) + test_collector = Collector(policy, test_envs) + # log + writer = SummaryWriter(args.logdir + '/' + 'ddpg') + + def stop_fn(x): + return x >= env.spec.reward_threshold + + # trainer + result = offpolicy_trainer( + policy, train_collector, test_collector, args.epoch, + args.step_per_epoch, args.collect_per_step, args.test_num, + args.batch_size, stop_fn=stop_fn, writer=writer, task=args.task) + assert stop_fn(result['best_reward']) + train_collector.close() + test_collector.close() + if __name__ == '__main__': + pprint.pprint(result) + # Let's watch its performance! + env = gym.make(args.task) + collector = Collector(policy, env) + result = collector.collect(n_episode=1, render=args.render) + print(f'Final reward: {result["rew"]}, length: {result["len"]}') + collector.close() + + +if __name__ == '__main__': + test_ddpg() diff --git a/examples/ant_v2_sac.py b/examples/ant_v2_sac.py new file mode 100644 index 0000000..9768474 --- /dev/null +++ b/examples/ant_v2_sac.py @@ -0,0 +1,110 @@ +import gym +import torch +import pprint +import argparse +import numpy as np +from torch.utils.tensorboard import SummaryWriter + +from tianshou.policy import SACPolicy +from tianshou.trainer import offpolicy_trainer +from tianshou.data import Collector, ReplayBuffer +from tianshou.env import VectorEnv, SubprocVectorEnv + +if __name__ == '__main__': + from continuous_net import ActorProb, Critic +else: # pytest + from test.continuous.net import ActorProb, Critic + + +def get_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--task', type=str, default='Ant-v2') + parser.add_argument('--seed', type=int, default=1626) + parser.add_argument('--buffer-size', type=int, default=20000) + parser.add_argument('--actor-lr', type=float, default=3e-4) + parser.add_argument('--critic-lr', type=float, default=1e-3) + parser.add_argument('--gamma', type=float, default=0.99) + parser.add_argument('--tau', type=float, default=0.005) + parser.add_argument('--alpha', type=float, default=0.2) + parser.add_argument('--epoch', type=int, default=100) + parser.add_argument('--step-per-epoch', type=int, default=2400) + parser.add_argument('--collect-per-step', type=int, default=10) + parser.add_argument('--batch-size', type=int, default=128) + parser.add_argument('--layer-num', type=int, default=1) + parser.add_argument('--training-num', type=int, default=8) + parser.add_argument('--test-num', type=int, default=100) + parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) + parser.add_argument( + '--device', type=str, + default='cuda' if torch.cuda.is_available() else 'cpu') + args = parser.parse_known_args()[0] + return args + + +def test_sac(args=get_args()): + env = gym.make(args.task) + args.state_shape = env.observation_space.shape or env.observation_space.n + args.action_shape = env.action_space.shape or env.action_space.n + args.max_action = env.action_space.high[0] + # train_envs = gym.make(args.task) + train_envs = VectorEnv( + [lambda: gym.make(args.task) for _ in range(args.training_num)]) + # test_envs = gym.make(args.task) + test_envs = SubprocVectorEnv( + [lambda: gym.make(args.task) for _ in range(args.test_num)]) + # seed + np.random.seed(args.seed) + torch.manual_seed(args.seed) + train_envs.seed(args.seed) + test_envs.seed(args.seed) + # model + actor = ActorProb( + args.layer_num, args.state_shape, args.action_shape, + args.max_action, args.device + ).to(args.device) + actor_optim = torch.optim.Adam(actor.parameters(), lr=args.actor_lr) + critic1 = Critic( + args.layer_num, args.state_shape, args.action_shape, args.device + ).to(args.device) + critic1_optim = torch.optim.Adam(critic1.parameters(), lr=args.critic_lr) + critic2 = Critic( + args.layer_num, args.state_shape, args.action_shape, args.device + ).to(args.device) + critic2_optim = torch.optim.Adam(critic2.parameters(), lr=args.critic_lr) + policy = SACPolicy( + actor, actor_optim, critic1, critic1_optim, critic2, critic2_optim, + args.tau, args.gamma, args.alpha, + [env.action_space.low[0], env.action_space.high[0]], + reward_normalization=True, ignore_done=True) + # collector + train_collector = Collector( + policy, train_envs, ReplayBuffer(args.buffer_size)) + test_collector = Collector(policy, test_envs) + # train_collector.collect(n_step=args.buffer_size) + # log + writer = SummaryWriter(args.logdir + '/' + 'sac') + + def stop_fn(x): + return x >= env.spec.reward_threshold + + # trainer + result = offpolicy_trainer( + policy, train_collector, test_collector, args.epoch, + args.step_per_epoch, args.collect_per_step, args.test_num, + args.batch_size, stop_fn=stop_fn, writer=writer, task=args.task) + assert stop_fn(result['best_reward']) + train_collector.close() + test_collector.close() + if __name__ == '__main__': + pprint.pprint(result) + # Let's watch its performance! + env = gym.make(args.task) + collector = Collector(policy, env) + result = collector.collect(n_episode=1, render=args.render) + print(f'Final reward: {result["rew"]}, length: {result["len"]}') + collector.close() + + +if __name__ == '__main__': + test_sac() diff --git a/examples/ant_v2_td3.py b/examples/ant_v2_td3.py new file mode 100644 index 0000000..bd581c6 --- /dev/null +++ b/examples/ant_v2_td3.py @@ -0,0 +1,114 @@ +import gym +import torch +import pprint +import argparse +import numpy as np +from torch.utils.tensorboard import SummaryWriter + +from tianshou.policy import TD3Policy +from tianshou.trainer import offpolicy_trainer +from tianshou.data import Collector, ReplayBuffer +from tianshou.env import VectorEnv, SubprocVectorEnv + +if __name__ == '__main__': + from continuous_net import Actor, Critic +else: # pytest + from test.continuous.net import Actor, Critic + + +def get_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--task', type=str, default='Ant-v2') + parser.add_argument('--seed', type=int, default=1626) + parser.add_argument('--buffer-size', type=int, default=20000) + parser.add_argument('--actor-lr', type=float, default=3e-4) + parser.add_argument('--critic-lr', type=float, default=1e-3) + parser.add_argument('--gamma', type=float, default=0.99) + parser.add_argument('--tau', type=float, default=0.005) + parser.add_argument('--exploration-noise', type=float, default=0.1) + parser.add_argument('--policy-noise', type=float, default=0.2) + parser.add_argument('--noise-clip', type=float, default=0.5) + parser.add_argument('--update-actor-freq', type=int, default=2) + parser.add_argument('--epoch', type=int, default=100) + parser.add_argument('--step-per-epoch', type=int, default=2400) + parser.add_argument('--collect-per-step', type=int, default=10) + parser.add_argument('--batch-size', type=int, default=128) + parser.add_argument('--layer-num', type=int, default=1) + parser.add_argument('--training-num', type=int, default=8) + parser.add_argument('--test-num', type=int, default=100) + parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) + parser.add_argument( + '--device', type=str, + default='cuda' if torch.cuda.is_available() else 'cpu') + args = parser.parse_known_args()[0] + return args + + +def test_td3(args=get_args()): + env = gym.make(args.task) + args.state_shape = env.observation_space.shape or env.observation_space.n + args.action_shape = env.action_space.shape or env.action_space.n + args.max_action = env.action_space.high[0] + # train_envs = gym.make(args.task) + train_envs = VectorEnv( + [lambda: gym.make(args.task) for _ in range(args.training_num)]) + # test_envs = gym.make(args.task) + test_envs = SubprocVectorEnv( + [lambda: gym.make(args.task) for _ in range(args.test_num)]) + # seed + np.random.seed(args.seed) + torch.manual_seed(args.seed) + train_envs.seed(args.seed) + test_envs.seed(args.seed) + # model + actor = Actor( + args.layer_num, args.state_shape, args.action_shape, + args.max_action, args.device + ).to(args.device) + actor_optim = torch.optim.Adam(actor.parameters(), lr=args.actor_lr) + critic1 = Critic( + args.layer_num, args.state_shape, args.action_shape, args.device + ).to(args.device) + critic1_optim = torch.optim.Adam(critic1.parameters(), lr=args.critic_lr) + critic2 = Critic( + args.layer_num, args.state_shape, args.action_shape, args.device + ).to(args.device) + critic2_optim = torch.optim.Adam(critic2.parameters(), lr=args.critic_lr) + policy = TD3Policy( + actor, actor_optim, critic1, critic1_optim, critic2, critic2_optim, + args.tau, args.gamma, args.exploration_noise, args.policy_noise, + args.update_actor_freq, args.noise_clip, + [env.action_space.low[0], env.action_space.high[0]], + reward_normalization=True, ignore_done=True) + # collector + train_collector = Collector( + policy, train_envs, ReplayBuffer(args.buffer_size)) + test_collector = Collector(policy, test_envs) + # train_collector.collect(n_step=args.buffer_size) + # log + writer = SummaryWriter(args.logdir + '/' + 'td3') + + def stop_fn(x): + return x >= env.spec.reward_threshold + + # trainer + result = offpolicy_trainer( + policy, train_collector, test_collector, args.epoch, + args.step_per_epoch, args.collect_per_step, args.test_num, + args.batch_size, stop_fn=stop_fn, writer=writer, task=args.task) + assert stop_fn(result['best_reward']) + train_collector.close() + test_collector.close() + if __name__ == '__main__': + pprint.pprint(result) + # Let's watch its performance! + env = gym.make(args.task) + collector = Collector(policy, env) + result = collector.collect(n_episode=1, render=args.render) + print(f'Final reward: {result["rew"]}, length: {result["len"]}') + collector.close() + + +if __name__ == '__main__': + test_td3() diff --git a/examples/continuous_net.py b/examples/continuous_net.py new file mode 100644 index 0000000..1598a1f --- /dev/null +++ b/examples/continuous_net.py @@ -0,0 +1,79 @@ +import torch +import numpy as np +from torch import nn + + +class Actor(nn.Module): + def __init__(self, layer_num, state_shape, action_shape, + max_action, device='cpu'): + super().__init__() + self.device = device + self.model = [ + nn.Linear(np.prod(state_shape), 128), + nn.ReLU(inplace=True)] + for i in range(layer_num): + self.model += [nn.Linear(128, 128), nn.ReLU(inplace=True)] + self.model += [nn.Linear(128, np.prod(action_shape))] + self.model = nn.Sequential(*self.model) + self._max = max_action + + def forward(self, s, **kwargs): + s = torch.tensor(s, device=self.device, dtype=torch.float) + batch = s.shape[0] + s = s.view(batch, -1) + logits = self.model(s) + logits = self._max * torch.tanh(logits) + return logits, None + + +class ActorProb(nn.Module): + def __init__(self, layer_num, state_shape, action_shape, + max_action, device='cpu'): + super().__init__() + self.device = device + self.model = [ + nn.Linear(np.prod(state_shape), 128), + nn.ReLU(inplace=True)] + for i in range(layer_num): + self.model += [nn.Linear(128, 128), nn.ReLU(inplace=True)] + self.model = nn.Sequential(*self.model) + self.mu = nn.Linear(128, np.prod(action_shape)) + self.sigma = nn.Linear(128, np.prod(action_shape)) + self._max = max_action + + def forward(self, s, **kwargs): + if not isinstance(s, torch.Tensor): + s = torch.tensor(s, device=self.device, dtype=torch.float) + batch = s.shape[0] + s = s.view(batch, -1) + logits = self.model(s) + mu = self._max * torch.tanh(self.mu(logits)) + sigma = torch.exp(self.sigma(logits)) + return (mu, sigma), None + + +class Critic(nn.Module): + def __init__(self, layer_num, state_shape, action_shape=0, device='cpu'): + super().__init__() + self.device = device + self.model = [ + nn.Linear(np.prod(state_shape) + np.prod(action_shape), 128), + nn.ReLU(inplace=True)] + for i in range(layer_num): + self.model += [nn.Linear(128, 128), nn.ReLU(inplace=True)] + self.model += [nn.Linear(128, 1)] + self.model = nn.Sequential(*self.model) + + def forward(self, s, a=None): + if not isinstance(s, torch.Tensor): + s = torch.tensor(s, device=self.device, dtype=torch.float) + if a is not None and not isinstance(a, torch.Tensor): + a = torch.tensor(a, device=self.device, dtype=torch.float) + batch = s.shape[0] + s = s.view(batch, -1) + if a is None: + logits = self.model(s) + else: + a = a.view(batch, -1) + logits = self.model(torch.cat([s, a], dim=1)) + return logits diff --git a/examples/discrete_net.py b/examples/discrete_net.py new file mode 100644 index 0000000..14d2c6e --- /dev/null +++ b/examples/discrete_net.py @@ -0,0 +1,81 @@ +import torch +import numpy as np +from torch import nn +import torch.nn.functional as F + + +class Net(nn.Module): + def __init__(self, layer_num, state_shape, action_shape=0, device='cpu'): + super().__init__() + self.device = device + self.model = [ + nn.Linear(np.prod(state_shape), 128), + nn.ReLU(inplace=True)] + for i in range(layer_num): + self.model += [nn.Linear(128, 128), nn.ReLU(inplace=True)] + if action_shape: + self.model += [nn.Linear(128, np.prod(action_shape))] + self.model = nn.Sequential(*self.model) + + def forward(self, s, state=None, info={}): + if not isinstance(s, torch.Tensor): + s = torch.tensor(s, device=self.device, dtype=torch.float) + batch = s.shape[0] + s = s.view(batch, -1) + logits = self.model(s) + return logits, state + + +class Actor(nn.Module): + def __init__(self, preprocess_net, action_shape): + super().__init__() + self.preprocess = preprocess_net + self.last = nn.Linear(128, np.prod(action_shape)) + + def forward(self, s, state=None, info={}): + logits, h = self.preprocess(s, state) + logits = F.softmax(self.last(logits), dim=-1) + return logits, h + + +class Critic(nn.Module): + def __init__(self, preprocess_net): + super().__init__() + self.preprocess = preprocess_net + self.last = nn.Linear(128, 1) + + def forward(self, s): + logits, h = self.preprocess(s, None) + logits = self.last(logits) + return logits + + +class DQN(nn.Module): + + def __init__(self, h, w, action_shape, device='cpu'): + super(DQN, self).__init__() + self.device = device + + self.conv1 = nn.Conv2d(1, 16, kernel_size=5, stride=2) + self.bn1 = nn.BatchNorm2d(16) + self.conv2 = nn.Conv2d(16, 32, kernel_size=5, stride=2) + self.bn2 = nn.BatchNorm2d(32) + self.conv3 = nn.Conv2d(32, 32, kernel_size=5, stride=2) + self.bn3 = nn.BatchNorm2d(32) + + def conv2d_size_out(size, kernel_size=5, stride=2): + return (size - (kernel_size - 1) - 1) // stride + 1 + + convw = conv2d_size_out(conv2d_size_out(conv2d_size_out(w))) + convh = conv2d_size_out(conv2d_size_out(conv2d_size_out(h))) + linear_input_size = convw * convh * 32 + self.head = nn.Linear(linear_input_size, action_shape) + + def forward(self, x, state=None, info={}): + if not isinstance(x, torch.Tensor): + x = torch.tensor(x, device=self.device, dtype=torch.float) + x = x.permute(0, 3, 1, 2) + x = F.relu(self.bn1(self.conv1(x))) + x = F.relu(self.bn2(self.conv2(x))) + x = F.relu(self.bn3(self.conv3(x))) + return self.head(x.view(x.size(0), -1)), state diff --git a/examples/point_maze_td3.py b/examples/point_maze_td3.py new file mode 100644 index 0000000..5632ee4 --- /dev/null +++ b/examples/point_maze_td3.py @@ -0,0 +1,119 @@ +import gym +import torch +import pprint +import argparse +import numpy as np +from torch.utils.tensorboard import SummaryWriter + +from tianshou.policy import TD3Policy +from tianshou.trainer import offpolicy_trainer +from tianshou.data import Collector, ReplayBuffer +from tianshou.env import VectorEnv, SubprocVectorEnv + +if __name__ == '__main__': + from continuous_net import Actor, Critic +else: # pytest + from test.continuous.net import Actor, Critic + + +def get_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--task', type=str, default='PointMaze-v0') + parser.add_argument('--seed', type=int, default=1626) + parser.add_argument('--buffer-size', type=int, default=20000) + parser.add_argument('--actor-lr', type=float, default=3e-5) + parser.add_argument('--critic-lr', type=float, default=1e-4) + parser.add_argument('--gamma', type=float, default=0.99) + parser.add_argument('--tau', type=float, default=0.005) + parser.add_argument('--exploration-noise', type=float, default=0.1) + parser.add_argument('--policy-noise', type=float, default=0.2) + parser.add_argument('--noise-clip', type=float, default=0.5) + parser.add_argument('--update-actor-freq', type=int, default=2) + parser.add_argument('--epoch', type=int, default=100) + parser.add_argument('--step-per-epoch', type=int, default=2400) + parser.add_argument('--collect-per-step', type=int, default=10) + parser.add_argument('--batch-size', type=int, default=128) + parser.add_argument('--layer-num', type=int, default=1) + parser.add_argument('--training-num', type=int, default=8) + parser.add_argument('--test-num', type=int, default=100) + parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) + parser.add_argument( + '--device', type=str, + default='cuda' if torch.cuda.is_available() else 'cpu') + parser.add_argument('--max_episode_steps', type=int, default=2000) + + args = parser.parse_known_args()[0] + return args + + +def test_td3(args=get_args()): + env = gym.make(args.task) + args.state_shape = env.observation_space.shape or env.observation_space.n + args.action_shape = env.action_space.shape or env.action_space.n + args.max_action = env.action_space.high[0] + # train_envs = gym.make(args.task) + train_envs = VectorEnv( + [lambda: gym.make(args.task) for _ in range(args.training_num)]) + # test_envs = gym.make(args.task) + test_envs = SubprocVectorEnv( + [lambda: gym.make(args.task) for _ in range(args.test_num)]) + # seed + np.random.seed(args.seed) + torch.manual_seed(args.seed) + train_envs.seed(args.seed) + test_envs.seed(args.seed) + # model + actor = Actor( + args.layer_num, args.state_shape, args.action_shape, + args.max_action, args.device + ).to(args.device) + actor_optim = torch.optim.Adam(actor.parameters(), lr=args.actor_lr) + critic1 = Critic( + args.layer_num, args.state_shape, args.action_shape, args.device + ).to(args.device) + critic1_optim = torch.optim.Adam(critic1.parameters(), lr=args.critic_lr) + critic2 = Critic( + args.layer_num, args.state_shape, args.action_shape, args.device + ).to(args.device) + critic2_optim = torch.optim.Adam(critic2.parameters(), lr=args.critic_lr) + policy = TD3Policy( + actor, actor_optim, critic1, critic1_optim, critic2, critic2_optim, + args.tau, args.gamma, args.exploration_noise, args.policy_noise, + args.update_actor_freq, args.noise_clip, + [env.action_space.low[0], env.action_space.high[0]], + reward_normalization=True, ignore_done=True) + # collector + train_collector = Collector( + policy, train_envs, ReplayBuffer(args.buffer_size)) + test_collector = Collector(policy, test_envs) + # train_collector.collect(n_step=args.buffer_size) + # log + writer = SummaryWriter(args.logdir + '/' + 'td3') + + def stop_fn(x): + if env.spec.reward_threshold: + return x >= env.spec.reward_threshold + else: + return False + + # trainer + result = offpolicy_trainer( + policy, train_collector, test_collector, args.epoch, + args.step_per_epoch, args.collect_per_step, args.test_num, + args.batch_size, stop_fn=stop_fn, writer=writer, task=args.task) + assert stop_fn(result['best_reward']) + train_collector.close() + test_collector.close() + if __name__ == '__main__': + pprint.pprint(result) + # Let's watch its performance! + env = gym.make(args.task) + collector = Collector(policy, env) + result = collector.collect(n_step=1000, render=args.render) + print(f'Final reward: {result["rew"]}, length: {result["len"]}') + collector.close() + + +if __name__ == '__main__': + test_td3() diff --git a/examples/pong_a2c.py b/examples/pong_a2c.py new file mode 100644 index 0000000..ce55584 --- /dev/null +++ b/examples/pong_a2c.py @@ -0,0 +1,108 @@ +import gym +import torch +import pprint +import argparse +import numpy as np +from torch.utils.tensorboard import SummaryWriter + +from tianshou.policy import A2CPolicy +from tianshou.env import SubprocVectorEnv +from tianshou.trainer import onpolicy_trainer +from tianshou.data import Collector, ReplayBuffer +from tianshou.env.atari import create_atari_environment + +if __name__ == '__main__': + from discrete_net import Net, Actor, Critic +else: # pytest + from test.discrete.net import Net, Actor, Critic + + +def get_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--task', type=str, default='Pong') + parser.add_argument('--seed', type=int, default=1626) + parser.add_argument('--buffer-size', type=int, default=20000) + parser.add_argument('--lr', type=float, default=3e-4) + parser.add_argument('--gamma', type=float, default=0.9) + parser.add_argument('--epoch', type=int, default=100) + parser.add_argument('--step-per-epoch', type=int, default=1000) + parser.add_argument('--collect-per-step', type=int, default=100) + parser.add_argument('--repeat-per-collect', type=int, default=1) + parser.add_argument('--batch-size', type=int, default=64) + parser.add_argument('--layer-num', type=int, default=2) + parser.add_argument('--training-num', type=int, default=8) + parser.add_argument('--test-num', type=int, default=8) + parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) + + parser.add_argument( + '--device', type=str, + default='cuda' if torch.cuda.is_available() else 'cpu') + # a2c special + parser.add_argument('--vf-coef', type=float, default=0.5) + parser.add_argument('--ent-coef', type=float, default=0.001) + parser.add_argument('--max-grad-norm', type=float, default=None) + parser.add_argument('--max_episode_steps', type=int, default=2000) + args = parser.parse_known_args()[0] + return args + + +def test_a2c(args=get_args()): + env = create_atari_environment(args.task, max_episode_steps=args.max_episode_steps) + args.state_shape = env.observation_space.shape or env.observation_space.n + args.action_shape = env.env.action_space.shape or env.env.action_space.n + # train_envs = gym.make(args.task) + train_envs = SubprocVectorEnv( + [lambda: create_atari_environment(args.task, max_episode_steps=args.max_episode_steps) for _ in + range(args.training_num)]) + # test_envs = gym.make(args.task) + test_envs = SubprocVectorEnv( + [lambda: create_atari_environment(args.task, max_episode_steps=args.max_episode_steps) for _ in + range(args.test_num)]) + # seed + np.random.seed(args.seed) + torch.manual_seed(args.seed) + train_envs.seed(args.seed) + test_envs.seed(args.seed) + # model + net = Net(args.layer_num, args.state_shape, device=args.device) + actor = Actor(net, args.action_shape).to(args.device) + critic = Critic(net).to(args.device) + optim = torch.optim.Adam(list( + actor.parameters()) + list(critic.parameters()), lr=args.lr) + dist = torch.distributions.Categorical + policy = A2CPolicy( + actor, critic, optim, dist, args.gamma, vf_coef=args.vf_coef, + ent_coef=args.ent_coef, max_grad_norm=args.max_grad_norm) + # collector + train_collector = Collector( + policy, train_envs, ReplayBuffer(args.buffer_size)) + test_collector = Collector(policy, test_envs) + # log + writer = SummaryWriter(args.logdir + '/' + 'a2c') + + def stop_fn(x): + if env.env.spec.reward_threshold: + return x >= env.spec.reward_threshold + else: + return False + + # trainer + result = onpolicy_trainer( + policy, train_collector, test_collector, args.epoch, + args.step_per_epoch, args.collect_per_step, args.repeat_per_collect, + args.test_num, args.batch_size, stop_fn=stop_fn, writer=writer, task=args.task) + train_collector.close() + test_collector.close() + if __name__ == '__main__': + pprint.pprint(result) + # Let's watch its performance! + env = create_atari_environment(args.task) + collector = Collector(policy, env) + result = collector.collect(n_episode=1, render=args.render) + print(f'Final reward: {result["rew"]}, length: {result["len"]}') + collector.close() + + +if __name__ == '__main__': + test_a2c() diff --git a/examples/pong_dqn.py b/examples/pong_dqn.py new file mode 100644 index 0000000..d32233b --- /dev/null +++ b/examples/pong_dqn.py @@ -0,0 +1,112 @@ +import gym +import torch +import pprint +import argparse +import numpy as np +from torch.utils.tensorboard import SummaryWriter + +from tianshou.policy import DQNPolicy +from tianshou.env import SubprocVectorEnv +from tianshou.trainer import offpolicy_trainer +from tianshou.data import Collector, ReplayBuffer +from tianshou.env.atari import create_atari_environment + +if __name__ == '__main__': + from discrete_net import DQN +else: # pytest + from test.discrete.net import DQN + + +def get_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--task', type=str, default='Pong') + parser.add_argument('--seed', type=int, default=1626) + parser.add_argument('--eps-test', type=float, default=0.05) + parser.add_argument('--eps-train', type=float, default=0.1) + parser.add_argument('--buffer-size', type=int, default=20000) + parser.add_argument('--lr', type=float, default=1e-3) + parser.add_argument('--gamma', type=float, default=0.9) + parser.add_argument('--n-step', type=int, default=1) + parser.add_argument('--target-update-freq', type=int, default=320) + parser.add_argument('--epoch', type=int, default=100) + parser.add_argument('--step-per-epoch', type=int, default=1000) + parser.add_argument('--collect-per-step', type=int, default=10) + parser.add_argument('--batch-size', type=int, default=64) + parser.add_argument('--layer-num', type=int, default=3) + parser.add_argument('--training-num', type=int, default=8) + parser.add_argument('--test-num', type=int, default=8) + parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) + parser.add_argument( + '--device', type=str, + default='cuda' if torch.cuda.is_available() else 'cpu') + args = parser.parse_known_args()[0] + return args + + +def test_dqn(args=get_args()): + env = create_atari_environment(args.task) + args.state_shape = env.observation_space.shape or env.observation_space.n + args.action_shape = env.env.action_space.shape or env.env.action_space.n + # train_envs = gym.make(args.task) + train_envs = SubprocVectorEnv( + [lambda: create_atari_environment(args.task) for _ in range(args.training_num)]) + # test_envs = gym.make(args.task) + test_envs = SubprocVectorEnv( + [lambda: create_atari_environment(args.task) for _ in range(args.test_num)]) + # seed + np.random.seed(args.seed) + torch.manual_seed(args.seed) + train_envs.seed(args.seed) + test_envs.seed(args.seed) + # model + net = DQN(args.state_shape[0], args.state_shape[1], args.action_shape, args.device) + net = net.to(args.device) + optim = torch.optim.Adam(net.parameters(), lr=args.lr) + policy = DQNPolicy( + net, optim, args.gamma, args.n_step, + use_target_network=args.target_update_freq > 0, + target_update_freq=args.target_update_freq) + # collector + train_collector = Collector( + policy, train_envs, ReplayBuffer(args.buffer_size)) + test_collector = Collector(policy, test_envs) + # policy.set_eps(1) + train_collector.collect(n_step=args.batch_size * 4) + print(len(train_collector.buffer)) + # log + writer = SummaryWriter(args.logdir + '/' + 'dqn') + + def stop_fn(x): + if env.env.spec.reward_threshold: + return x >= env.spec.reward_threshold + else: + return False + + def train_fn(x): + policy.set_eps(args.eps_train) + + def test_fn(x): + policy.set_eps(args.eps_test) + + # trainer + result = offpolicy_trainer( + policy, train_collector, test_collector, args.epoch, + args.step_per_epoch, args.collect_per_step, args.test_num, + args.batch_size, train_fn=train_fn, test_fn=test_fn, + stop_fn=stop_fn, writer=writer, task=args.task) + + train_collector.close() + test_collector.close() + if __name__ == '__main__': + pprint.pprint(result) + # Let's watch its performance! + env = create_atari_environment(args.task) + collector = Collector(policy, env) + result = collector.collect(n_episode=1, render=args.render) + print(f'Final reward: {result["rew"]}, length: {result["len"]}') + collector.close() + + +if __name__ == '__main__': + test_dqn(get_args()) diff --git a/examples/pong_ppo.py b/examples/pong_ppo.py new file mode 100644 index 0000000..8374b9a --- /dev/null +++ b/examples/pong_ppo.py @@ -0,0 +1,112 @@ +import gym +import torch +import pprint +import argparse +import numpy as np +from torch.utils.tensorboard import SummaryWriter + +from tianshou.policy import PPOPolicy +from tianshou.env import SubprocVectorEnv +from tianshou.trainer import onpolicy_trainer +from tianshou.data import Collector, ReplayBuffer +from tianshou.env.atari import create_atari_environment + +if __name__ == '__main__': + from discrete_net import Net, Actor, Critic +else: # pytest + from test.discrete.net import Net, Actor, Critic + + +def get_args(): + parser = argparse.ArgumentParser() + parser.add_argument('--task', type=str, default='Pong') + parser.add_argument('--seed', type=int, default=1626) + parser.add_argument('--buffer-size', type=int, default=20000) + parser.add_argument('--lr', type=float, default=1e-3) + parser.add_argument('--gamma', type=float, default=0.99) + parser.add_argument('--epoch', type=int, default=100) + parser.add_argument('--step-per-epoch', type=int, default=1000) + parser.add_argument('--collect-per-step', type=int, default=100) + parser.add_argument('--repeat-per-collect', type=int, default=2) + parser.add_argument('--batch-size', type=int, default=64) + parser.add_argument('--layer-num', type=int, default=1) + parser.add_argument('--training-num', type=int, default=8) + parser.add_argument('--test-num', type=int, default=8) + parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) + parser.add_argument( + '--device', type=str, + default='cuda' if torch.cuda.is_available() else 'cpu') + # ppo special + parser.add_argument('--vf-coef', type=float, default=0.5) + parser.add_argument('--ent-coef', type=float, default=0.0) + parser.add_argument('--eps-clip', type=float, default=0.2) + parser.add_argument('--max-grad-norm', type=float, default=0.5) + parser.add_argument('--max_episode_steps', type=int, default=2000) + args = parser.parse_known_args()[0] + return args + + +def test_ppo(args=get_args()): + env = create_atari_environment(args.task, max_episode_steps=args.max_episode_steps) + args.state_shape = env.observation_space.shape or env.observation_space.n + args.action_shape = env.action_space().shape or env.action_space().n + # train_envs = gym.make(args.task) + train_envs = SubprocVectorEnv( + [lambda: create_atari_environment(args.task, max_episode_steps=args.max_episode_steps) for _ in + range(args.training_num)]) + # test_envs = gym.make(args.task) + test_envs = SubprocVectorEnv( + [lambda: create_atari_environment(args.task, max_episode_steps=args.max_episode_steps) for _ in + range(args.test_num)]) + # seed + np.random.seed(args.seed) + torch.manual_seed(args.seed) + train_envs.seed(args.seed) + test_envs.seed(args.seed) + # model + net = Net(args.layer_num, args.state_shape, device=args.device) + actor = Actor(net, args.action_shape).to(args.device) + critic = Critic(net).to(args.device) + optim = torch.optim.Adam(list( + actor.parameters()) + list(critic.parameters()), lr=args.lr) + dist = torch.distributions.Categorical + policy = PPOPolicy( + actor, critic, optim, dist, args.gamma, + max_grad_norm=args.max_grad_norm, + eps_clip=args.eps_clip, + vf_coef=args.vf_coef, + ent_coef=args.ent_coef, + action_range=None) + # collector + train_collector = Collector( + policy, train_envs, ReplayBuffer(args.buffer_size)) + test_collector = Collector(policy, test_envs) + # log + writer = SummaryWriter(args.logdir + '/' + 'ppo') + + def stop_fn(x): + if env.env.spec.reward_threshold: + return x >= env.spec.reward_threshold + else: + return False + + # trainer + result = onpolicy_trainer( + policy, train_collector, test_collector, args.epoch, + args.step_per_epoch, args.collect_per_step, args.repeat_per_collect, + args.test_num, args.batch_size, stop_fn=stop_fn, writer=writer, task=args.task) + train_collector.close() + test_collector.close() + if __name__ == '__main__': + pprint.pprint(result) + # Let's watch its performance! + env = create_atari_environment(args.task) + collector = Collector(policy, env) + result = collector.collect(n_step=2000, render=args.render) + print(f'Final reward: {result["rew"]}, length: {result["len"]}') + collector.close() + + +if __name__ == '__main__': + test_ppo() diff --git a/setup.py b/setup.py index 545171a..37ac7c4 100644 --- a/setup.py +++ b/setup.py @@ -55,6 +55,7 @@ setup( ], 'atari': [ 'atari_py', + 'cv2' ], 'mujoco': [ 'mujoco_py', diff --git a/test/continuous/test_ddpg.py b/test/continuous/test_ddpg.py index cb100da..a1ac3ab 100644 --- a/test/continuous/test_ddpg.py +++ b/test/continuous/test_ddpg.py @@ -34,6 +34,7 @@ def get_args(): parser.add_argument('--training-num', type=int, default=8) parser.add_argument('--test-num', type=int, default=100) parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) parser.add_argument( '--device', type=str, default='cuda' if torch.cuda.is_available() else 'cpu') @@ -79,7 +80,7 @@ def test_ddpg(args=get_args()): policy, train_envs, ReplayBuffer(args.buffer_size)) test_collector = Collector(policy, test_envs) # log - writer = SummaryWriter(args.logdir) + writer = SummaryWriter(args.logdir + '/' + 'ddpg') def stop_fn(x): return x >= env.spec.reward_threshold @@ -88,7 +89,7 @@ def test_ddpg(args=get_args()): result = offpolicy_trainer( policy, train_collector, test_collector, args.epoch, args.step_per_epoch, args.collect_per_step, args.test_num, - args.batch_size, stop_fn=stop_fn, writer=writer) + args.batch_size, stop_fn=stop_fn, writer=writer, task=args.task) assert stop_fn(result['best_reward']) train_collector.close() test_collector.close() @@ -97,7 +98,7 @@ def test_ddpg(args=get_args()): # Let's watch its performance! env = gym.make(args.task) collector = Collector(policy, env) - result = collector.collect(n_episode=1, render=1 / 35) + result = collector.collect(n_episode=1, render=args.render) print(f'Final reward: {result["rew"]}, length: {result["len"]}') collector.close() diff --git a/test/continuous/test_ppo.py b/test/continuous/test_ppo.py index 3cfb9f2..c447bbd 100644 --- a/test/continuous/test_ppo.py +++ b/test/continuous/test_ppo.py @@ -32,6 +32,7 @@ def get_args(): parser.add_argument('--training-num', type=int, default=16) parser.add_argument('--test-num', type=int, default=100) parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) parser.add_argument( '--device', type=str, default='cuda' if torch.cuda.is_available() else 'cpu') @@ -87,7 +88,7 @@ def _test_ppo(args=get_args()): test_collector = Collector(policy, test_envs) train_collector.collect(n_step=args.step_per_epoch) # log - writer = SummaryWriter(args.logdir) + writer = SummaryWriter(args.logdir + '/' + 'ppo') def stop_fn(x): return x >= env.spec.reward_threshold @@ -96,7 +97,7 @@ def _test_ppo(args=get_args()): result = onpolicy_trainer( policy, train_collector, test_collector, args.epoch, args.step_per_epoch, args.collect_per_step, args.repeat_per_collect, - args.test_num, args.batch_size, stop_fn=stop_fn, writer=writer) + args.test_num, args.batch_size, stop_fn=stop_fn, writer=writer, task=args.task) assert stop_fn(result['best_reward']) train_collector.close() test_collector.close() @@ -105,7 +106,7 @@ def _test_ppo(args=get_args()): # Let's watch its performance! env = gym.make(args.task) collector = Collector(policy, env) - result = collector.collect(n_episode=1, render=1 / 35) + result = collector.collect(n_episode=1, render=args.render) print(f'Final reward: {result["rew"]}, length: {result["len"]}') collector.close() diff --git a/test/continuous/test_sac.py b/test/continuous/test_sac.py index a900940..948b5e3 100644 --- a/test/continuous/test_sac.py +++ b/test/continuous/test_sac.py @@ -34,6 +34,7 @@ def get_args(): parser.add_argument('--training-num', type=int, default=8) parser.add_argument('--test-num', type=int, default=100) parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) parser.add_argument( '--device', type=str, default='cuda' if torch.cuda.is_available() else 'cpu') @@ -84,7 +85,7 @@ def test_sac(args=get_args()): test_collector = Collector(policy, test_envs) # train_collector.collect(n_step=args.buffer_size) # log - writer = SummaryWriter(args.logdir) + writer = SummaryWriter(args.logdir + '/' + 'sac') def stop_fn(x): return x >= env.spec.reward_threshold @@ -93,7 +94,7 @@ def test_sac(args=get_args()): result = offpolicy_trainer( policy, train_collector, test_collector, args.epoch, args.step_per_epoch, args.collect_per_step, args.test_num, - args.batch_size, stop_fn=stop_fn, writer=writer) + args.batch_size, stop_fn=stop_fn, writer=writer, task=args.task) assert stop_fn(result['best_reward']) train_collector.close() test_collector.close() @@ -102,7 +103,7 @@ def test_sac(args=get_args()): # Let's watch its performance! env = gym.make(args.task) collector = Collector(policy, env) - result = collector.collect(n_episode=1, render=1 / 35) + result = collector.collect(n_episode=1, render=args.render) print(f'Final reward: {result["rew"]}, length: {result["len"]}') collector.close() diff --git a/test/continuous/test_td3.py b/test/continuous/test_td3.py index 78db493..fb3dd72 100644 --- a/test/continuous/test_td3.py +++ b/test/continuous/test_td3.py @@ -37,6 +37,7 @@ def get_args(): parser.add_argument('--training-num', type=int, default=8) parser.add_argument('--test-num', type=int, default=100) parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) parser.add_argument( '--device', type=str, default='cuda' if torch.cuda.is_available() else 'cpu') @@ -88,7 +89,7 @@ def test_td3(args=get_args()): test_collector = Collector(policy, test_envs) # train_collector.collect(n_step=args.buffer_size) # log - writer = SummaryWriter(args.logdir) + writer = SummaryWriter(args.logdir + '/' + 'td3') def stop_fn(x): return x >= env.spec.reward_threshold @@ -97,7 +98,7 @@ def test_td3(args=get_args()): result = offpolicy_trainer( policy, train_collector, test_collector, args.epoch, args.step_per_epoch, args.collect_per_step, args.test_num, - args.batch_size, stop_fn=stop_fn, writer=writer) + args.batch_size, stop_fn=stop_fn, writer=writer, task=args.task) assert stop_fn(result['best_reward']) train_collector.close() test_collector.close() @@ -106,7 +107,7 @@ def test_td3(args=get_args()): # Let's watch its performance! env = gym.make(args.task) collector = Collector(policy, env) - result = collector.collect(n_episode=1, render=1 / 35) + result = collector.collect(n_episode=1, render=args.render) print(f'Final reward: {result["rew"]}, length: {result["len"]}') collector.close() diff --git a/test/discrete/net.py b/test/discrete/net.py index 71c7272..7f62c8d 100644 --- a/test/discrete/net.py +++ b/test/discrete/net.py @@ -48,3 +48,33 @@ class Critic(nn.Module): logits, h = self.preprocess(s, None) logits = self.last(logits) return logits + + +class DQN(nn.Module): + + def __init__(self, h, w, action_shape, device='cpu'): + super(DQN, self).__init__() + self.device = device + + self.conv1 = nn.Conv2d(3, 16, kernel_size=5, stride=2) + self.bn1 = nn.BatchNorm2d(16) + self.conv2 = nn.Conv2d(16, 32, kernel_size=5, stride=2) + self.bn2 = nn.BatchNorm2d(32) + self.conv3 = nn.Conv2d(32, 32, kernel_size=5, stride=2) + self.bn3 = nn.BatchNorm2d(32) + + def conv2d_size_out(size, kernel_size=5, stride=2): + return (size - (kernel_size - 1) - 1) // stride + 1 + + convw = conv2d_size_out(conv2d_size_out(conv2d_size_out(w))) + convh = conv2d_size_out(conv2d_size_out(conv2d_size_out(h))) + linear_input_size = convw * convh * 32 + self.head = nn.Linear(linear_input_size, action_shape) + + def forward(self, x, state=None, info={}): + if not isinstance(x, torch.Tensor): + s = torch.tensor(x, device=self.device, dtype=torch.float) + x = F.relu(self.bn1(self.conv1(x))) + x = F.relu(self.bn2(self.conv2(x))) + x = F.relu(self.bn3(self.conv3(x))) + return self.head(x.view(x.size(0), -1)), state diff --git a/test/discrete/test_a2c.py b/test/discrete/test_a2c.py index 20ef0ef..5c9269c 100644 --- a/test/discrete/test_a2c.py +++ b/test/discrete/test_a2c.py @@ -32,6 +32,8 @@ def get_args(): parser.add_argument('--training-num', type=int, default=32) parser.add_argument('--test-num', type=int, default=100) parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) + parser.add_argument( '--device', type=str, default='cuda' if torch.cuda.is_available() else 'cpu') @@ -73,7 +75,7 @@ def test_a2c(args=get_args()): policy, train_envs, ReplayBuffer(args.buffer_size)) test_collector = Collector(policy, test_envs) # log - writer = SummaryWriter(args.logdir) + writer = SummaryWriter(args.logdir + '/' + 'ppo') def stop_fn(x): return x >= env.spec.reward_threshold @@ -82,7 +84,7 @@ def test_a2c(args=get_args()): result = onpolicy_trainer( policy, train_collector, test_collector, args.epoch, args.step_per_epoch, args.collect_per_step, args.repeat_per_collect, - args.test_num, args.batch_size, stop_fn=stop_fn, writer=writer) + args.test_num, args.batch_size, stop_fn=stop_fn, writer=writer, task=args.task) assert stop_fn(result['best_reward']) train_collector.close() test_collector.close() @@ -91,7 +93,7 @@ def test_a2c(args=get_args()): # Let's watch its performance! env = gym.make(args.task) collector = Collector(policy, env) - result = collector.collect(n_episode=1, render=1 / 35) + result = collector.collect(n_episode=1, render=args.render) print(f'Final reward: {result["rew"]}, length: {result["len"]}') collector.close() diff --git a/test/discrete/test_dqn.py b/test/discrete/test_dqn.py index 3a11993..118adcb 100644 --- a/test/discrete/test_dqn.py +++ b/test/discrete/test_dqn.py @@ -35,6 +35,7 @@ def get_args(): parser.add_argument('--training-num', type=int, default=8) parser.add_argument('--test-num', type=int, default=100) parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) parser.add_argument( '--device', type=str, default='cuda' if torch.cuda.is_available() else 'cpu') @@ -73,7 +74,7 @@ def test_dqn(args=get_args()): train_collector.collect(n_step=args.batch_size) print(len(train_collector.buffer)) # log - writer = SummaryWriter(args.logdir) + writer = SummaryWriter(args.logdir + '/' + 'ppo') def stop_fn(x): return x >= env.spec.reward_threshold @@ -89,7 +90,7 @@ def test_dqn(args=get_args()): policy, train_collector, test_collector, args.epoch, args.step_per_epoch, args.collect_per_step, args.test_num, args.batch_size, train_fn=train_fn, test_fn=test_fn, - stop_fn=stop_fn, writer=writer) + stop_fn=stop_fn, writer=writer, task=args.task) assert stop_fn(result['best_reward']) train_collector.close() @@ -99,7 +100,7 @@ def test_dqn(args=get_args()): # Let's watch its performance! env = gym.make(args.task) collector = Collector(policy, env) - result = collector.collect(n_episode=1, render=1 / 35) + result = collector.collect(n_episode=1, render=args.render) print(f'Final reward: {result["rew"]}, length: {result["len"]}') collector.close() diff --git a/test/discrete/test_pg.py b/test/discrete/test_pg.py index e0f4a08..b00896c 100644 --- a/test/discrete/test_pg.py +++ b/test/discrete/test_pg.py @@ -86,6 +86,7 @@ def get_args(): parser.add_argument('--training-num', type=int, default=8) parser.add_argument('--test-num', type=int, default=100) parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) parser.add_argument( '--device', type=str, default='cuda' if torch.cuda.is_available() else 'cpu') @@ -121,7 +122,7 @@ def test_pg(args=get_args()): policy, train_envs, ReplayBuffer(args.buffer_size)) test_collector = Collector(policy, test_envs) # log - writer = SummaryWriter(args.logdir) + writer = SummaryWriter(args.logdir + '/' + 'ppo') def stop_fn(x): return x >= env.spec.reward_threshold @@ -130,7 +131,7 @@ def test_pg(args=get_args()): result = onpolicy_trainer( policy, train_collector, test_collector, args.epoch, args.step_per_epoch, args.collect_per_step, args.repeat_per_collect, - args.test_num, args.batch_size, stop_fn=stop_fn, writer=writer) + args.test_num, args.batch_size, stop_fn=stop_fn, writer=writer, task=args.task) assert stop_fn(result['best_reward']) train_collector.close() test_collector.close() @@ -139,7 +140,7 @@ def test_pg(args=get_args()): # Let's watch its performance! env = gym.make(args.task) collector = Collector(policy, env) - result = collector.collect(n_episode=1, render=1 / 35) + result = collector.collect(n_episode=1, render=args.render) print(f'Final reward: {result["rew"]}, length: {result["len"]}') collector.close() diff --git a/test/discrete/test_ppo.py b/test/discrete/test_ppo.py index d21dd6c..d2b889c 100644 --- a/test/discrete/test_ppo.py +++ b/test/discrete/test_ppo.py @@ -32,6 +32,7 @@ def get_args(): parser.add_argument('--training-num', type=int, default=32) parser.add_argument('--test-num', type=int, default=100) parser.add_argument('--logdir', type=str, default='log') + parser.add_argument('--render', type=float, default=0.) parser.add_argument( '--device', type=str, default='cuda' if torch.cuda.is_available() else 'cpu') @@ -78,7 +79,7 @@ def test_ppo(args=get_args()): policy, train_envs, ReplayBuffer(args.buffer_size)) test_collector = Collector(policy, test_envs) # log - writer = SummaryWriter(args.logdir) + writer = SummaryWriter(args.logdir + '/' + 'ppo') def stop_fn(x): return x >= env.spec.reward_threshold @@ -87,7 +88,7 @@ def test_ppo(args=get_args()): result = onpolicy_trainer( policy, train_collector, test_collector, args.epoch, args.step_per_epoch, args.collect_per_step, args.repeat_per_collect, - args.test_num, args.batch_size, stop_fn=stop_fn, writer=writer) + args.test_num, args.batch_size, stop_fn=stop_fn, writer=writer, task=args.task) assert stop_fn(result['best_reward']) train_collector.close() test_collector.close() @@ -96,7 +97,7 @@ def test_ppo(args=get_args()): # Let's watch its performance! env = gym.make(args.task) collector = Collector(policy, env) - result = collector.collect(n_episode=1, render=1 / 35) + result = collector.collect(n_episode=1, render=args.render) print(f'Final reward: {result["rew"]}, length: {result["len"]}') collector.close() diff --git a/tianshou/data/batch.py b/tianshou/data/batch.py index 13777ab..d2af6b5 100644 --- a/tianshou/data/batch.py +++ b/tianshou/data/batch.py @@ -37,7 +37,7 @@ class Batch(object): else: raise TypeError( 'No support for append with type {} in class Batch.' - .format(type(batch.__dict__[k]))) + .format(type(batch.__dict__[k]))) def split(self, size=None, permute=True): length = min([ diff --git a/tianshou/data/collector.py b/tianshou/data/collector.py index 0673ac7..00b3daf 100644 --- a/tianshou/data/collector.py +++ b/tianshou/data/collector.py @@ -2,7 +2,7 @@ import time import torch import numpy as np from copy import deepcopy - +import warnings from tianshou.env import BaseVectorEnv from tianshou.data import Batch, ReplayBuffer from tianshou.utils import MovAvg @@ -87,6 +87,7 @@ class Collector(object): return np.array([data]) def collect(self, n_step=0, n_episode=0, render=0): + warning_count = 0 if not self._multi_env: n_episode = np.sum(n_episode) start_time = time.time() @@ -97,6 +98,10 @@ class Collector(object): reward_sum = 0 length_sum = 0 while True: + if warning_count >= 100000: + warnings.warn( + 'There are already many steps in an episode. You should add a time limitation to your environment!', + Warning) if self._multi_env: batch_data = Batch( obs=self._obs, act=self._act, rew=self._rew, @@ -131,11 +136,14 @@ class Collector(object): 'rew': self._rew[i], 'done': self._done[i], 'obs_next': obs_next[i], 'info': self._info[i]} if self._cached_buf: + warning_count += 1 self._cached_buf[i].add(**data) elif self._multi_buf: + warning_count += 1 self.buffer[i].add(**data) cur_step += 1 else: + warning_count += 1 self.buffer.add(**data) cur_step += 1 if self._done[i]: diff --git a/tianshou/exploration/random.py b/tianshou/exploration/random.py index 011afbe..12d92ea 100644 --- a/tianshou/exploration/random.py +++ b/tianshou/exploration/random.py @@ -14,7 +14,7 @@ class OUNoise(object): if self.x is None or self.x.shape != size: self.x = 0 self.x = self.x + self.alpha * (mu - self.x) + \ - self.beta * np.random.normal(size=size) + self.beta * np.random.normal(size=size) return self.x def reset(self): diff --git a/tianshou/policy/a2c.py b/tianshou/policy/a2c.py index 93337d4..79601fd 100644 --- a/tianshou/policy/a2c.py +++ b/tianshou/policy/a2c.py @@ -39,6 +39,7 @@ class A2CPolicy(PGPolicy): a_loss = -(dist.log_prob(a) * (r - v).detach()).mean() vf_loss = F.mse_loss(r[:, None], v) ent_loss = dist.entropy().mean() + loss = a_loss + self._w_vf * vf_loss - self._w_ent * ent_loss loss.backward() if self._grad_norm: diff --git a/tianshou/policy/pg.py b/tianshou/policy/pg.py index c5e3b70..33ee273 100644 --- a/tianshou/policy/pg.py +++ b/tianshou/policy/pg.py @@ -34,6 +34,9 @@ class PGPolicy(BasePolicy): def learn(self, batch, batch_size=None, repeat=1): losses = [] + + batch.returns = (batch.returns - batch.returns.mean()) \ + / (batch.returns.std() + self._eps) r = batch.returns batch.returns = (r - r.mean()) / (r.std() + self._eps) for _ in range(repeat): diff --git a/tianshou/policy/ppo.py b/tianshou/policy/ppo.py index 01270ef..53389fe 100644 --- a/tianshou/policy/ppo.py +++ b/tianshou/policy/ppo.py @@ -58,6 +58,9 @@ class PPOPolicy(PGPolicy): def learn(self, batch, batch_size=None, repeat=1): losses, clip_losses, vf_losses, ent_losses = [], [], [], [] + + batch.returns = (batch.returns - batch.returns.mean()) \ + / (batch.returns.std() + self._eps) r = batch.returns batch.returns = (r - r.mean()) / (r.std() + self._eps) batch.act = torch.tensor(batch.act) @@ -79,6 +82,7 @@ class PPOPolicy(PGPolicy): clip_losses.append(clip_loss.detach().cpu().numpy()) vf_loss = F.smooth_l1_loss(self.critic(b.obs), target_v) vf_losses.append(vf_loss.detach().cpu().numpy()) + e_loss = dist.entropy().mean() ent_losses.append(e_loss.detach().cpu().numpy()) loss = clip_loss + self._w_vf * vf_loss - self._w_ent * e_loss @@ -87,7 +91,7 @@ class PPOPolicy(PGPolicy): loss.backward() nn.utils.clip_grad_norm_(list( self.actor.parameters()) + list(self.critic.parameters()), - self._max_grad_norm) + self._max_grad_norm) self.optim.step() self.sync_weight() return { diff --git a/tianshou/trainer/offpolicy.py b/tianshou/trainer/offpolicy.py index a095061..7319108 100644 --- a/tianshou/trainer/offpolicy.py +++ b/tianshou/trainer/offpolicy.py @@ -8,7 +8,7 @@ from tianshou.trainer import test_episode, gather_info def offpolicy_trainer(policy, train_collector, test_collector, max_epoch, step_per_epoch, collect_per_step, episode_per_test, batch_size, train_fn=None, test_fn=None, stop_fn=None, - writer=None, verbose=True): + writer=None, verbose=True, task=''): global_step = 0 best_epoch, best_reward = -1, -1 stat = {} @@ -47,7 +47,7 @@ def offpolicy_trainer(policy, train_collector, test_collector, max_epoch, data[k] = f'{result[k]:.2f}' if writer: writer.add_scalar( - k, result[k], global_step=global_step) + k + '_' + task, result[k], global_step=global_step) for k in losses.keys(): if stat.get(k) is None: stat[k] = MovAvg() @@ -55,7 +55,7 @@ def offpolicy_trainer(policy, train_collector, test_collector, max_epoch, data[k] = f'{stat[k].get():.6f}' if writer: writer.add_scalar( - k, stat[k].get(), global_step=global_step) + k + '_' + task, stat[k].get(), global_step=global_step) t.update(1) t.set_postfix(**data) if t.n <= t.total: diff --git a/tianshou/trainer/onpolicy.py b/tianshou/trainer/onpolicy.py index 79cad82..6548b76 100644 --- a/tianshou/trainer/onpolicy.py +++ b/tianshou/trainer/onpolicy.py @@ -9,7 +9,7 @@ def onpolicy_trainer(policy, train_collector, test_collector, max_epoch, step_per_epoch, collect_per_step, repeat_per_collect, episode_per_test, batch_size, train_fn=None, test_fn=None, stop_fn=None, - writer=None, verbose=True): + writer=None, verbose=True, task=''): global_step = 0 best_epoch, best_reward = -1, -1 stat = {} @@ -52,15 +52,15 @@ def onpolicy_trainer(policy, train_collector, test_collector, max_epoch, data[k] = f'{result[k]:.2f}' if writer: writer.add_scalar( - k, result[k], global_step=global_step) + k + '_' + task, result[k], global_step=global_step) for k in losses.keys(): if stat.get(k) is None: stat[k] = MovAvg() stat[k].add(losses[k]) data[k] = f'{stat[k].get():.6f}' - if writer: + if writer and global_step: writer.add_scalar( - k, stat[k].get(), global_step=global_step) + k + '_' + task, stat[k].get(), global_step=global_step) t.update(step) t.set_postfix(**data) if t.n <= t.total: