From 16d8e9b05182bb96c7fd3e46a922cfa1b862705c Mon Sep 17 00:00:00 2001 From: danagi <420147879@qq.com> Date: Sat, 12 Sep 2020 08:44:50 +0800 Subject: [PATCH] SAC implementation update (#212) - replace DiagGuassian with Independent(Normal) (pytorch has already supported this) - detach alpha from autograd - add value/alpha to result (more informational) - revert #204 to fix #211 Co-authored-by: Trinkle23897 <463003665@qq.com> --- examples/box2d/README.md | 5 +- examples/box2d/bipedal_hardcore_sac.py | 10 ++- .../box2d/results/sac/BipedalHardcore.png | Bin 40704 -> 46560 bytes test/continuous/test_ppo.py | 8 ++- tianshou/policy/dist.py | 11 --- tianshou/policy/modelfree/sac.py | 67 +++++++++--------- tianshou/trainer/offpolicy.py | 11 ++- tianshou/trainer/onpolicy.py | 11 ++- 8 files changed, 62 insertions(+), 61 deletions(-) delete mode 100644 tianshou/policy/dist.py diff --git a/examples/box2d/README.md b/examples/box2d/README.md index 0935534..53300dd 100644 --- a/examples/box2d/README.md +++ b/examples/box2d/README.md @@ -1,7 +1,6 @@ # Bipedal-Hardcore-SAC -- Our default choice: remove the done flag penalty, will soon converge to \~250 reward within 100 epochs (10M env steps, 3~4 hours, see the image below) +- Our default choice: remove the done flag penalty, will soon converge to \~270 reward within 100 epochs (10M env steps, 3~4 hours, see the image below) - If the done penalty is not removed, it converges much slower than before, about 200 epochs (20M env steps) to reach the same performance (\~200 reward) -- Action noise is only necessary in the beginning. It is a negative impact at the end of the training. Removing it can reach \~255 (our best result under the original env, no done penalty removed). -![](results/sac/BipedalHardcore.png) \ No newline at end of file +![](results/sac/BipedalHardcore.png) diff --git a/examples/box2d/bipedal_hardcore_sac.py b/examples/box2d/bipedal_hardcore_sac.py index 4e12371..e6e7d73 100644 --- a/examples/box2d/bipedal_hardcore_sac.py +++ b/examples/box2d/bipedal_hardcore_sac.py @@ -24,6 +24,8 @@ def get_args(): 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.1) + parser.add_argument('--auto_alpha', type=int, default=1) + parser.add_argument('--alpha_lr', type=float, default=3e-4) parser.add_argument('--epoch', type=int, default=100) parser.add_argument('--step-per-epoch', type=int, default=10000) parser.add_argument('--collect-per-step', type=int, default=10) @@ -46,7 +48,7 @@ def get_args(): class EnvWrapper(object): """Env wrapper for reward scale, action repeat and action noise""" - def __init__(self, task, action_repeat=3, reward_scale=5, act_noise=0.3): + def __init__(self, task, action_repeat=3, reward_scale=5, act_noise=0.0): self._env = gym.make(task) self.action_repeat = action_repeat self.reward_scale = reward_scale @@ -109,6 +111,12 @@ def test_sac_bipedal(args=get_args()): critic2 = Critic(net_c2, args.device).to(args.device) critic2_optim = torch.optim.Adam(critic2.parameters(), lr=args.critic_lr) + if args.auto_alpha: + target_entropy = -np.prod(env.action_space.shape) + log_alpha = torch.zeros(1, requires_grad=True, device=args.device) + alpha_optim = torch.optim.Adam([log_alpha], lr=args.alpha_lr) + args.alpha = (target_entropy, log_alpha, alpha_optim) + policy = SACPolicy( actor, actor_optim, critic1, critic1_optim, critic2, critic2_optim, args.tau, args.gamma, args.alpha, diff --git a/examples/box2d/results/sac/BipedalHardcore.png b/examples/box2d/results/sac/BipedalHardcore.png index 0b41969558239c056e2122bdc6975257b5572599..86367e591825f7e0388581919ce54bf8d0c97951 100644 GIT binary patch literal 46560 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�iWRrhWcSA(@XeSRVTHR)oVV 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 diff --git a/test/continuous/test_ppo.py b/test/continuous/test_ppo.py index 5019f5b..bee5af4 100644 --- a/test/continuous/test_ppo.py +++ b/test/continuous/test_ppo.py @@ -5,11 +5,11 @@ import pprint import argparse import numpy as np from torch.utils.tensorboard import SummaryWriter +from torch.distributions import Independent, Normal from tianshou.policy import PPOPolicy from tianshou.env import DummyVectorEnv from tianshou.utils.net.common import Net -from tianshou.policy.dist import DiagGaussian from tianshou.trainer import onpolicy_trainer from tianshou.data import Collector, ReplayBuffer from tianshou.utils.net.continuous import ActorProb, Critic @@ -84,7 +84,11 @@ def test_ppo(args=get_args()): torch.nn.init.zeros_(m.bias) optim = torch.optim.Adam(list( actor.parameters()) + list(critic.parameters()), lr=args.lr) - dist = DiagGaussian + + # replace DiagGuassian with Independent(Normal) which is equivalent + # pass *logits to be consistent with policy.forward + def dist(*logits): + return Independent(Normal(*logits), 1) policy = PPOPolicy( actor, critic, optim, dist, args.gamma, max_grad_norm=args.max_grad_norm, diff --git a/tianshou/policy/dist.py b/tianshou/policy/dist.py deleted file mode 100644 index f1792e4..0000000 --- a/tianshou/policy/dist.py +++ /dev/null @@ -1,11 +0,0 @@ -import torch - - -class DiagGaussian(torch.distributions.Normal): - """Diagonal Gaussian distribution.""" - - def log_prob(self, actions): - return super().log_prob(actions).sum(-1, keepdim=True) - - def entropy(self): - return super().entropy().sum(-1) diff --git a/tianshou/policy/modelfree/sac.py b/tianshou/policy/modelfree/sac.py index 920bfb1..47823c6 100644 --- a/tianshou/policy/modelfree/sac.py +++ b/tianshou/policy/modelfree/sac.py @@ -2,9 +2,9 @@ import torch import numpy as np from copy import deepcopy from typing import Dict, Tuple, Union, Optional +from torch.distributions import Normal, Independent from tianshou.policy import DDPGPolicy -from tianshou.policy.dist import DiagGaussian from tianshou.data import Batch, to_torch_as, ReplayBuffer from tianshou.exploration import BaseNoise @@ -47,23 +47,26 @@ class SACPolicy(DDPGPolicy): explanation. """ - def __init__(self, - actor: torch.nn.Module, - actor_optim: torch.optim.Optimizer, - critic1: torch.nn.Module, - critic1_optim: torch.optim.Optimizer, - critic2: torch.nn.Module, - critic2_optim: torch.optim.Optimizer, - tau: float = 0.005, - gamma: float = 0.99, - alpha: Tuple[float, torch.Tensor, torch.optim.Optimizer] - or float = 0.2, - action_range: Optional[Tuple[float, float]] = None, - reward_normalization: bool = False, - ignore_done: bool = False, - estimation_step: int = 1, - exploration_noise: Optional[BaseNoise] = None, - **kwargs) -> None: + def __init__( + self, + actor: torch.nn.Module, + actor_optim: torch.optim.Optimizer, + critic1: torch.nn.Module, + critic1_optim: torch.optim.Optimizer, + critic2: torch.nn.Module, + critic2_optim: torch.optim.Optimizer, + tau: float = 0.005, + gamma: float = 0.99, + alpha: Union[ + float, Tuple[float, torch.Tensor, torch.optim.Optimizer] + ] = 0.2, + action_range: Optional[Tuple[float, float]] = None, + reward_normalization: bool = False, + ignore_done: bool = False, + estimation_step: int = 1, + exploration_noise: Optional[BaseNoise] = None, + **kwargs + ) -> None: super().__init__(None, None, None, None, tau, gamma, exploration_noise, action_range, reward_normalization, ignore_done, estimation_step, **kwargs) @@ -75,14 +78,12 @@ class SACPolicy(DDPGPolicy): self.critic2_old.eval() self.critic2_optim = critic2_optim - self._automatic_alpha_tuning = not isinstance(alpha, float) - if self._automatic_alpha_tuning: - self._target_entropy = alpha[0] - assert(alpha[1].shape == torch.Size([1]) - and alpha[1].requires_grad) - self._log_alpha = alpha[1] - self._alpha_optim = alpha[2] - self._alpha = self._log_alpha.exp() + self._is_auto_alpha = False + if isinstance(alpha, tuple): + self._is_auto_alpha = True + self._target_entropy, self._log_alpha, self._alpha_optim = alpha + assert alpha[1].shape == torch.Size([1]) and alpha[1].requires_grad + self._alpha = self._log_alpha.detach().exp() else: self._alpha = alpha @@ -111,12 +112,13 @@ class SACPolicy(DDPGPolicy): obs = getattr(batch, input) logits, h = self.actor(obs, state=state, info=batch.info) assert isinstance(logits, tuple) - dist = DiagGaussian(*logits) + dist = Independent(Normal(*logits), 1) x = dist.rsample() y = torch.tanh(x) act = y * self._action_scale + self._action_bias y = self._action_scale * (1 - y.pow(2)) + self.__eps - log_prob = dist.log_prob(x) - torch.log(y).sum(-1, keepdim=True) + log_prob = dist.log_prob(x).unsqueeze(-1) + log_prob = log_prob - torch.log(y).sum(-1, keepdim=True) if self._noise is not None and self.training and explorating: act += to_torch_as(self._noise(act.shape), act) act = act.clamp(self._range[0], self._range[1]) @@ -167,13 +169,13 @@ class SACPolicy(DDPGPolicy): actor_loss.backward() self.actor_optim.step() - if self._automatic_alpha_tuning: - log_prob = (obs_result.log_prob + self._target_entropy).detach() + if self._is_auto_alpha: + log_prob = obs_result.log_prob.detach() + self._target_entropy alpha_loss = -(self._log_alpha * log_prob).mean() self._alpha_optim.zero_grad() alpha_loss.backward() self._alpha_optim.step() - self._alpha = self._log_alpha.exp() + self._alpha = self._log_alpha.detach().exp() self.sync_weight() @@ -182,6 +184,7 @@ class SACPolicy(DDPGPolicy): 'loss/critic1': critic1_loss.item(), 'loss/critic2': critic2_loss.item(), } - if self._automatic_alpha_tuning: + if self._is_auto_alpha: result['loss/alpha'] = alpha_loss.item() + result['v/alpha'] = self._alpha.item() return result diff --git a/tianshou/trainer/offpolicy.py b/tianshou/trainer/offpolicy.py index c04a4b5..be52c54 100644 --- a/tianshou/trainer/offpolicy.py +++ b/tianshou/trainer/offpolicy.py @@ -77,13 +77,13 @@ def offpolicy_trainer( start_time = time.time() test_in_train = test_in_train and train_collector.policy == policy for epoch in range(1, 1 + max_epoch): + # train + policy.train() + if train_fn: + train_fn(epoch) with tqdm.tqdm(total=step_per_epoch, desc=f'Epoch #{epoch}', **tqdm_config) as t: while t.n < t.total: - # collect - if train_fn: - train_fn(epoch) - policy.eval() result = train_collector.collect(n_step=collect_per_step) data = {} if test_in_train and stop_fn and stop_fn(result['rew']): @@ -100,10 +100,9 @@ def offpolicy_trainer( start_time, train_collector, test_collector, test_result['rew']) else: + policy.train() if train_fn: train_fn(epoch) - # train - policy.train() for i in range(update_per_step * min( result['n/st'] // collect_per_step, t.total - t.n)): global_step += collect_per_step diff --git a/tianshou/trainer/onpolicy.py b/tianshou/trainer/onpolicy.py index 6af4317..db13d06 100644 --- a/tianshou/trainer/onpolicy.py +++ b/tianshou/trainer/onpolicy.py @@ -77,13 +77,13 @@ def onpolicy_trainer( start_time = time.time() test_in_train = test_in_train and train_collector.policy == policy for epoch in range(1, 1 + max_epoch): + # train + policy.train() + if train_fn: + train_fn(epoch) with tqdm.tqdm(total=step_per_epoch, desc=f'Epoch #{epoch}', **tqdm_config) as t: while t.n < t.total: - # collect - if train_fn: - train_fn(epoch) - policy.eval() result = train_collector.collect(n_episode=collect_per_step) data = {} if test_in_train and stop_fn and stop_fn(result['rew']): @@ -100,10 +100,9 @@ def onpolicy_trainer( start_time, train_collector, test_collector, test_result['rew']) else: + policy.train() if train_fn: train_fn(epoch) - # train - policy.train() losses = policy.update( 0, train_collector.buffer, batch_size, repeat_per_collect) train_collector.reset_buffer()