drlab 0.2.2__tar.gz → 0.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {drlab-0.2.2/src/drlab.egg-info → drlab-0.2.4}/PKG-INFO +1 -1
- {drlab-0.2.2 → drlab-0.2.4}/pyproject.toml +1 -1
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/__init__.py +1 -1
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/experiments/off_policy_experiment.py +3 -2
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/experiments/on_policy_experiment.py +1 -1
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/learners/off_policy/base.py +36 -20
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/learners/off_policy/configs.py +6 -3
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/learners/off_policy/dqn.py +7 -4
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/learners/off_policy/sac.py +42 -34
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/learners/on_policy/actor_critic.py +8 -8
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/learners/on_policy/base.py +6 -6
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/learners/on_policy/configs.py +1 -1
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/learners/on_policy/ppo.py +4 -4
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/learners/on_policy/reinforce.py +4 -4
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/replay/replay_buffer.py +18 -8
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/replay/transition_batch.py +6 -3
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/runners/runner.py +29 -16
- {drlab-0.2.2 → drlab-0.2.4/src/drlab.egg-info}/PKG-INFO +1 -1
- {drlab-0.2.2 → drlab-0.2.4}/tests/test_learners.py +134 -21
- {drlab-0.2.2 → drlab-0.2.4}/tests/test_off_policy_experiment.py +3 -2
- {drlab-0.2.2 → drlab-0.2.4}/tests/test_public_api.py +1 -1
- {drlab-0.2.2 → drlab-0.2.4}/tests/test_replay.py +21 -9
- {drlab-0.2.2 → drlab-0.2.4}/tests/test_runner.py +23 -0
- {drlab-0.2.2 → drlab-0.2.4}/LICENSE +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/README.md +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/setup.cfg +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/controllers/__init__.py +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/controllers/base.py +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/controllers/e_greedy.py +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/controllers/gaussian.py +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/controllers/greedy.py +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/controllers/stochastic.py +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/controllers/warmup.py +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/experiments/__init__.py +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/learners/__init__.py +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/learners/off_policy/__init__.py +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/learners/on_policy/__init__.py +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/replay/__init__.py +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab/runners/__init__.py +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab.egg-info/SOURCES.txt +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab.egg-info/dependency_links.txt +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab.egg-info/requires.txt +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/src/drlab.egg-info/top_level.txt +0 -0
- {drlab-0.2.2 → drlab-0.2.4}/tests/test_controllers.py +0 -0
|
@@ -130,7 +130,8 @@ class OffPolicyExperiment:
|
|
|
130
130
|
states=batch.states,
|
|
131
131
|
actions=batch.actions,
|
|
132
132
|
rewards=batch.rewards,
|
|
133
|
-
|
|
133
|
+
terminated=batch.terminated,
|
|
134
|
+
truncated=batch.truncated,
|
|
134
135
|
next_states=batch.next_states,
|
|
135
136
|
returns=batch.returns,
|
|
136
137
|
)
|
|
@@ -142,7 +143,7 @@ class OffPolicyExperiment:
|
|
|
142
143
|
for _ in range(self.grad_repeats):
|
|
143
144
|
mb = self._make_minibatch(batch, last_episode)
|
|
144
145
|
total_loss += self.learner.train(
|
|
145
|
-
mb.rewards, mb.
|
|
146
|
+
mb.rewards, mb.terminated, mb.states, mb.actions, mb.next_states
|
|
146
147
|
)
|
|
147
148
|
|
|
148
149
|
return total_loss / self.grad_repeats
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import torch as th
|
|
2
2
|
from copy import deepcopy
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
|
+
from collections.abc import Iterable
|
|
4
5
|
|
|
5
6
|
from .configs import OffPolicyConfig, TargetUpdate
|
|
6
7
|
|
|
@@ -15,8 +16,7 @@ class OffPolicyLearner(ABC):
|
|
|
15
16
|
self.regularizers = config.regularizers
|
|
16
17
|
self.reg_lams = config.reg_lams
|
|
17
18
|
|
|
18
|
-
self.
|
|
19
|
-
self.grad_norm_clip = config.grad_norm_clip
|
|
19
|
+
self.clipnorm = config.clipnorm
|
|
20
20
|
|
|
21
21
|
self.use_target_model = config.use_target_model
|
|
22
22
|
self.target_update = TargetUpdate(config.target_update)
|
|
@@ -52,25 +52,39 @@ class OffPolicyLearner(ABC):
|
|
|
52
52
|
|
|
53
53
|
return target
|
|
54
54
|
|
|
55
|
-
def
|
|
55
|
+
def _hard_update(self, target: th.nn.Module, source: th.nn.Module):
|
|
56
56
|
target.load_state_dict(source.state_dict())
|
|
57
57
|
target.eval()
|
|
58
58
|
|
|
59
|
-
def
|
|
60
|
-
|
|
59
|
+
def _soft_update(
|
|
60
|
+
self,
|
|
61
|
+
pairs: list[tuple[th.nn.Module, th.nn.Module]],
|
|
62
|
+
) -> None:
|
|
63
|
+
target_parameters = [
|
|
64
|
+
parameter
|
|
65
|
+
for target, _ in pairs
|
|
66
|
+
for parameter in target.parameters()
|
|
67
|
+
]
|
|
68
|
+
source_parameters = [
|
|
69
|
+
parameter
|
|
70
|
+
for _, source in pairs
|
|
71
|
+
for parameter in source.parameters()
|
|
72
|
+
]
|
|
61
73
|
|
|
62
74
|
with th.no_grad():
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
75
|
+
th._foreach_mul_(target_parameters, 1.0 - self.soft_target_update_param)
|
|
76
|
+
scaled_sources = th._foreach_mul(
|
|
77
|
+
source_parameters,
|
|
78
|
+
self.soft_target_update_param,
|
|
79
|
+
)
|
|
80
|
+
th._foreach_add_(target_parameters, scaled_sources)
|
|
66
81
|
|
|
67
82
|
def update_targets(
|
|
68
83
|
self,
|
|
69
84
|
pairs: list[tuple[th.nn.Module, th.nn.Module]],
|
|
70
85
|
):
|
|
71
86
|
if self.target_update == TargetUpdate.SOFT:
|
|
72
|
-
|
|
73
|
-
self.soft_update(target, source)
|
|
87
|
+
self._soft_update(pairs)
|
|
74
88
|
return
|
|
75
89
|
|
|
76
90
|
if self.target_update == TargetUpdate.HARD:
|
|
@@ -78,7 +92,7 @@ class OffPolicyLearner(ABC):
|
|
|
78
92
|
|
|
79
93
|
if self.target_update_calls % self.target_update_interval == 0:
|
|
80
94
|
for target, source in pairs:
|
|
81
|
-
self.
|
|
95
|
+
self._hard_update(target, source)
|
|
82
96
|
|
|
83
97
|
return
|
|
84
98
|
|
|
@@ -88,7 +102,7 @@ class OffPolicyLearner(ABC):
|
|
|
88
102
|
self,
|
|
89
103
|
model: th.nn.Module,
|
|
90
104
|
rewards: th.Tensor,
|
|
91
|
-
|
|
105
|
+
terminated: th.Tensor,
|
|
92
106
|
states: th.Tensor,
|
|
93
107
|
actions: th.Tensor,
|
|
94
108
|
next_states: th.Tensor,
|
|
@@ -102,7 +116,7 @@ class OffPolicyLearner(ABC):
|
|
|
102
116
|
value = regularizer(
|
|
103
117
|
model,
|
|
104
118
|
rewards,
|
|
105
|
-
|
|
119
|
+
terminated,
|
|
106
120
|
states,
|
|
107
121
|
actions,
|
|
108
122
|
next_states,
|
|
@@ -119,15 +133,17 @@ class OffPolicyLearner(ABC):
|
|
|
119
133
|
self,
|
|
120
134
|
loss: th.Tensor,
|
|
121
135
|
optimizer: th.optim.Optimizer,
|
|
122
|
-
parameters:
|
|
123
|
-
|
|
136
|
+
parameters: Iterable[th.nn.Parameter],
|
|
137
|
+
clipnorm: float | None = None,
|
|
138
|
+
) -> None:
|
|
139
|
+
parameters = tuple(parameters)
|
|
124
140
|
optimizer.zero_grad(set_to_none=True)
|
|
125
|
-
loss.backward()
|
|
141
|
+
loss.backward(inputs=parameters)
|
|
126
142
|
|
|
127
|
-
if
|
|
143
|
+
if clipnorm is not None:
|
|
128
144
|
th.nn.utils.clip_grad_norm_(
|
|
129
145
|
parameters,
|
|
130
|
-
|
|
146
|
+
clipnorm,
|
|
131
147
|
)
|
|
132
148
|
|
|
133
149
|
optimizer.step()
|
|
@@ -139,9 +155,9 @@ class OffPolicyLearner(ABC):
|
|
|
139
155
|
def train(
|
|
140
156
|
self,
|
|
141
157
|
rewards: th.Tensor,
|
|
142
|
-
|
|
158
|
+
terminated: th.Tensor,
|
|
143
159
|
states: th.Tensor,
|
|
144
160
|
actions: th.Tensor,
|
|
145
161
|
next_states: th.Tensor,
|
|
146
162
|
) -> float:
|
|
147
|
-
pass
|
|
163
|
+
pass
|
|
@@ -20,8 +20,7 @@ class OffPolicyConfig:
|
|
|
20
20
|
regularizers: list[Callable[..., th.Tensor | float]] = field(default_factory=list)
|
|
21
21
|
reg_lams: list[float] = field(default_factory=list)
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
grad_norm_clip: float = 1.0
|
|
23
|
+
clipnorm: float | None = 1.0
|
|
25
24
|
|
|
26
25
|
use_target_model: bool = True
|
|
27
26
|
target_update: TargetUpdate | str = TargetUpdate.SOFT
|
|
@@ -47,6 +46,7 @@ class SACConfig(OffPolicyConfig):
|
|
|
47
46
|
criterion: th.nn.Module = field(default_factory=th.nn.MSELoss)
|
|
48
47
|
|
|
49
48
|
target_entropy: float | None = None
|
|
49
|
+
initial_alpha: float = 1.0
|
|
50
50
|
alpha_lr: float = 3e-4
|
|
51
51
|
|
|
52
52
|
min_log_std: float = -20.0
|
|
@@ -65,8 +65,11 @@ class SACConfig(OffPolicyConfig):
|
|
|
65
65
|
if self.action_dim <= 0:
|
|
66
66
|
raise ValueError("action_dim must be > 0.")
|
|
67
67
|
|
|
68
|
+
if self.initial_alpha <= 0.0:
|
|
69
|
+
raise ValueError("initial_alpha must be > 0.")
|
|
70
|
+
|
|
68
71
|
if self.alpha_lr <= 0.0:
|
|
69
72
|
raise ValueError("alpha_lr must be > 0.")
|
|
70
73
|
|
|
71
74
|
if self.min_log_std >= self.max_log_std:
|
|
72
|
-
raise ValueError("min_log_std must be < max_log_std.")
|
|
75
|
+
raise ValueError("min_log_std must be < max_log_std.")
|
|
@@ -58,7 +58,7 @@ class DQNLearner(OffPolicyLearner):
|
|
|
58
58
|
def train(
|
|
59
59
|
self,
|
|
60
60
|
rewards: th.Tensor, # float32, [B,1]
|
|
61
|
-
|
|
61
|
+
terminated: th.Tensor, # bool or float(0/1), [B,1]
|
|
62
62
|
states: th.Tensor, # float32, [B, obs_dim] or [B,C,H,W]
|
|
63
63
|
actions: th.Tensor, # int64, [B,1]
|
|
64
64
|
next_states: th.Tensor, # float32, same as states
|
|
@@ -66,8 +66,10 @@ class DQNLearner(OffPolicyLearner):
|
|
|
66
66
|
self.model.train(True)
|
|
67
67
|
|
|
68
68
|
# Compute targets
|
|
69
|
-
|
|
70
|
-
targets = rewards + self.gamma * (
|
|
69
|
+
not_terminated = 1.0 - terminated.float()
|
|
70
|
+
targets = rewards + self.gamma * (
|
|
71
|
+
not_terminated * self.next_values(next_states)
|
|
72
|
+
)
|
|
71
73
|
pred = self.current_values(states, actions)
|
|
72
74
|
|
|
73
75
|
# Compute loss
|
|
@@ -75,7 +77,7 @@ class DQNLearner(OffPolicyLearner):
|
|
|
75
77
|
reg_loss = self.regularization_loss(
|
|
76
78
|
self.model,
|
|
77
79
|
rewards=rewards,
|
|
78
|
-
|
|
80
|
+
terminated=terminated,
|
|
79
81
|
states=states,
|
|
80
82
|
actions=actions,
|
|
81
83
|
next_states=next_states,
|
|
@@ -87,6 +89,7 @@ class DQNLearner(OffPolicyLearner):
|
|
|
87
89
|
loss,
|
|
88
90
|
optimizer=self.optimizer,
|
|
89
91
|
parameters=self.model.parameters(),
|
|
92
|
+
clipnorm=self.clipnorm,
|
|
90
93
|
)
|
|
91
94
|
|
|
92
95
|
if self.target_model is not None:
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
1
3
|
import torch as th
|
|
2
|
-
from torch.distributions import Normal
|
|
3
4
|
|
|
4
5
|
from .base import OffPolicyLearner
|
|
5
6
|
from .configs import SACConfig
|
|
@@ -42,7 +43,7 @@ class SACLearner(OffPolicyLearner):
|
|
|
42
43
|
self.target_entropy = -float(config.action_dim)
|
|
43
44
|
|
|
44
45
|
self.log_alpha = th.nn.Parameter(
|
|
45
|
-
th.tensor(
|
|
46
|
+
th.tensor(math.log(config.initial_alpha), device=self.device)
|
|
46
47
|
)
|
|
47
48
|
|
|
48
49
|
self.alpha_optimizer = th.optim.Adam(
|
|
@@ -54,15 +55,15 @@ class SACLearner(OffPolicyLearner):
|
|
|
54
55
|
def alpha(self) -> th.Tensor:
|
|
55
56
|
return self.log_alpha.exp()
|
|
56
57
|
|
|
57
|
-
def
|
|
58
|
-
for param in model.parameters():
|
|
59
|
-
param.requires_grad_(requires_grad)
|
|
60
|
-
|
|
61
|
-
def get_policy_dist(self, states: th.Tensor):
|
|
58
|
+
def _get_policy_params(self, states: th.Tensor) -> tuple[th.Tensor, th.Tensor]:
|
|
62
59
|
output = self.actor(states)
|
|
63
60
|
mean = output[:, : self.config.action_dim]
|
|
64
61
|
log_std = output[:, self.config.action_dim :]
|
|
65
62
|
log_std = th.clamp(log_std, self.config.min_log_std, self.config.max_log_std)
|
|
63
|
+
return mean, log_std
|
|
64
|
+
|
|
65
|
+
def get_policy_dist(self, states: th.Tensor) -> tuple[th.Tensor, th.Tensor]:
|
|
66
|
+
mean, log_std = self._get_policy_params(states)
|
|
66
67
|
std = th.exp(log_std)
|
|
67
68
|
return mean, std
|
|
68
69
|
|
|
@@ -71,26 +72,30 @@ class SACLearner(OffPolicyLearner):
|
|
|
71
72
|
obs: th.Tensor,
|
|
72
73
|
deterministic: bool = False,
|
|
73
74
|
) -> tuple[th.Tensor, th.Tensor]:
|
|
74
|
-
mean,
|
|
75
|
+
mean, log_std = self._get_policy_params(obs)
|
|
75
76
|
|
|
76
77
|
if deterministic:
|
|
77
78
|
u = mean
|
|
78
79
|
return th.tanh(u), th.zeros(obs.shape[0], 1, device=obs.device)
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
80
|
+
|
|
81
|
+
# Specialized reparameterized Gaussian sampling avoids the generic
|
|
82
|
+
# distribution object's redundant scale and normalized-noise work.
|
|
83
|
+
eps = th.randn_like(mean)
|
|
84
|
+
u = mean + th.exp(log_std) * eps
|
|
82
85
|
action = th.tanh(u)
|
|
83
86
|
|
|
84
|
-
log_prob =
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
log_prob = -0.5 * (
|
|
88
|
+
eps.square() + 2.0 * log_std + math.log(2.0 * math.pi)
|
|
89
|
+
)
|
|
90
|
+
log_prob -= th.log(1.0 - action.pow(2) + 1e-6) # Tanh correction
|
|
91
|
+
log_prob = log_prob.sum(dim=-1, keepdim=True) # Sum over action dimensions
|
|
87
92
|
|
|
88
93
|
return action, log_prob
|
|
89
94
|
|
|
90
95
|
def train(
|
|
91
96
|
self,
|
|
92
97
|
rewards: th.Tensor, # float32, [B,1]
|
|
93
|
-
|
|
98
|
+
terminated: th.Tensor, # bool or float(0/1), [B,1]
|
|
94
99
|
states: th.Tensor, # float32, [B, obs_dim] or [B,C,H,W]
|
|
95
100
|
actions: th.Tensor, # float32, [B, action_dim]
|
|
96
101
|
next_states: th.Tensor, # float32, same as states
|
|
@@ -110,9 +115,9 @@ class SACLearner(OffPolicyLearner):
|
|
|
110
115
|
target_q2 = self.critic2_target(next_action_states)
|
|
111
116
|
target_q = th.min(target_q1, target_q2)
|
|
112
117
|
|
|
113
|
-
|
|
118
|
+
not_terminated = 1.0 - terminated.float()
|
|
114
119
|
targets = rewards + self.config.gamma * (
|
|
115
|
-
|
|
120
|
+
not_terminated * (target_q - self.alpha.detach() * next_log_probs)
|
|
116
121
|
)
|
|
117
122
|
|
|
118
123
|
action_states = th.cat([states, actions], dim=-1)
|
|
@@ -122,23 +127,27 @@ class SACLearner(OffPolicyLearner):
|
|
|
122
127
|
critic1_loss = self.criterion(current_q1, targets)
|
|
123
128
|
critic2_loss = self.criterion(current_q2, targets)
|
|
124
129
|
critic_loss = critic1_loss + critic2_loss
|
|
125
|
-
self.
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
130
|
+
self.critic1_optimizer.zero_grad(set_to_none=True)
|
|
131
|
+
self.critic2_optimizer.zero_grad(set_to_none=True)
|
|
132
|
+
critic_loss.backward()
|
|
133
|
+
|
|
134
|
+
if self.clipnorm is not None:
|
|
135
|
+
# Clip each critic independently to preserve the previous behavior.
|
|
136
|
+
th.nn.utils.clip_grad_norm_(
|
|
137
|
+
self.critic1.parameters(),
|
|
138
|
+
self.clipnorm,
|
|
139
|
+
)
|
|
140
|
+
th.nn.utils.clip_grad_norm_(
|
|
141
|
+
self.critic2.parameters(),
|
|
142
|
+
self.clipnorm,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
self.critic1_optimizer.step()
|
|
146
|
+
self.critic2_optimizer.step()
|
|
135
147
|
|
|
136
148
|
# --------------------------------------------------
|
|
137
149
|
# 2. Update actor
|
|
138
150
|
# --------------------------------------------------
|
|
139
|
-
self._set_requires_grad(self.critic1, False)
|
|
140
|
-
self._set_requires_grad(self.critic2, False)
|
|
141
|
-
|
|
142
151
|
new_actions, log_probs = self.sample_action_and_log_prob(states)
|
|
143
152
|
new_action_states = th.cat([states, new_actions], dim=-1)
|
|
144
153
|
new_q1 = self.critic1(new_action_states)
|
|
@@ -149,7 +158,7 @@ class SACLearner(OffPolicyLearner):
|
|
|
149
158
|
reg_loss = self.regularization_loss(
|
|
150
159
|
self.actor,
|
|
151
160
|
rewards=rewards,
|
|
152
|
-
|
|
161
|
+
terminated=terminated,
|
|
153
162
|
states=states,
|
|
154
163
|
actions=actions,
|
|
155
164
|
next_states=next_states,
|
|
@@ -159,11 +168,9 @@ class SACLearner(OffPolicyLearner):
|
|
|
159
168
|
actor_loss,
|
|
160
169
|
optimizer=self.actor_optimizer,
|
|
161
170
|
parameters=self.actor.parameters(),
|
|
171
|
+
clipnorm=self.clipnorm,
|
|
162
172
|
)
|
|
163
173
|
|
|
164
|
-
self._set_requires_grad(self.critic1, True)
|
|
165
|
-
self._set_requires_grad(self.critic2, True)
|
|
166
|
-
|
|
167
174
|
# --------------------------------------------------
|
|
168
175
|
# 3. Update alpha
|
|
169
176
|
# --------------------------------------------------
|
|
@@ -175,6 +182,7 @@ class SACLearner(OffPolicyLearner):
|
|
|
175
182
|
alpha_loss,
|
|
176
183
|
optimizer=self.alpha_optimizer,
|
|
177
184
|
parameters=[self.log_alpha],
|
|
185
|
+
clipnorm=self.clipnorm,
|
|
178
186
|
)
|
|
179
187
|
|
|
180
188
|
# Update target networks
|
|
@@ -28,14 +28,14 @@ class ActorCriticLearner(OnPolicyLearner):
|
|
|
28
28
|
self,
|
|
29
29
|
returns: th.Tensor,
|
|
30
30
|
rewards: th.Tensor,
|
|
31
|
-
|
|
31
|
+
terminated: th.Tensor,
|
|
32
32
|
values: th.Tensor,
|
|
33
33
|
next_values: th.Tensor,
|
|
34
34
|
) -> th.Tensor:
|
|
35
35
|
if self.config.value_targets == ValueTargets.RETURNS:
|
|
36
36
|
targets = returns
|
|
37
37
|
elif self.config.value_targets == ValueTargets.TD:
|
|
38
|
-
targets = rewards + self.config.gamma * (~
|
|
38
|
+
targets = rewards + self.config.gamma * (~terminated * next_values)
|
|
39
39
|
else:
|
|
40
40
|
raise ValueError(f"Unknown value_targets: {self.config.value_targets}")
|
|
41
41
|
return self.config.value_criterion(values, targets)
|
|
@@ -44,13 +44,13 @@ class ActorCriticLearner(OnPolicyLearner):
|
|
|
44
44
|
self,
|
|
45
45
|
returns: th.Tensor,
|
|
46
46
|
rewards: th.Tensor,
|
|
47
|
-
|
|
47
|
+
terminated: th.Tensor,
|
|
48
48
|
values: th.Tensor,
|
|
49
49
|
next_values: th.Tensor
|
|
50
50
|
) -> th.Tensor:
|
|
51
51
|
advantages = None
|
|
52
52
|
if self.config.advantage_bootstrap:
|
|
53
|
-
advantages = rewards + self.config.gamma * (~
|
|
53
|
+
advantages = rewards + self.config.gamma * (~terminated * next_values)
|
|
54
54
|
else:
|
|
55
55
|
advantages = returns
|
|
56
56
|
if self.config.use_bias:
|
|
@@ -74,7 +74,7 @@ class ActorCriticLearner(OnPolicyLearner):
|
|
|
74
74
|
def train(
|
|
75
75
|
self,
|
|
76
76
|
rewards: th.Tensor,
|
|
77
|
-
|
|
77
|
+
terminated: th.Tensor,
|
|
78
78
|
states: th.Tensor,
|
|
79
79
|
actions: th.Tensor,
|
|
80
80
|
next_states: th.Tensor,
|
|
@@ -106,7 +106,7 @@ class ActorCriticLearner(OnPolicyLearner):
|
|
|
106
106
|
advantages = self._advantages(
|
|
107
107
|
returns=returns,
|
|
108
108
|
rewards=rewards,
|
|
109
|
-
|
|
109
|
+
terminated=terminated,
|
|
110
110
|
values=values,
|
|
111
111
|
next_values=next_values,
|
|
112
112
|
)
|
|
@@ -119,7 +119,7 @@ class ActorCriticLearner(OnPolicyLearner):
|
|
|
119
119
|
value_loss = self.config.value_lambda * self._value_loss(
|
|
120
120
|
returns=returns,
|
|
121
121
|
rewards=rewards,
|
|
122
|
-
|
|
122
|
+
terminated=terminated,
|
|
123
123
|
values=values,
|
|
124
124
|
next_values=next_values,
|
|
125
125
|
)
|
|
@@ -128,7 +128,7 @@ class ActorCriticLearner(OnPolicyLearner):
|
|
|
128
128
|
|
|
129
129
|
reg_loss = self._regularization_loss(
|
|
130
130
|
rewards=rewards,
|
|
131
|
-
|
|
131
|
+
terminated=terminated,
|
|
132
132
|
states=states,
|
|
133
133
|
actions=actions,
|
|
134
134
|
next_states=next_states,
|
|
@@ -50,7 +50,7 @@ class OnPolicyLearner:
|
|
|
50
50
|
def _regularization_loss(
|
|
51
51
|
self,
|
|
52
52
|
rewards: th.Tensor,
|
|
53
|
-
|
|
53
|
+
terminated: th.Tensor,
|
|
54
54
|
states: th.Tensor,
|
|
55
55
|
actions: th.Tensor,
|
|
56
56
|
next_states: th.Tensor,
|
|
@@ -59,7 +59,7 @@ class OnPolicyLearner:
|
|
|
59
59
|
return 0.0
|
|
60
60
|
|
|
61
61
|
return sum(
|
|
62
|
-
lam * reg(self.actor, rewards,
|
|
62
|
+
lam * reg(self.actor, rewards, terminated, states, actions, next_states)
|
|
63
63
|
for reg, lam in zip(self.config.regularizers, self.config.reg_lams)
|
|
64
64
|
)
|
|
65
65
|
|
|
@@ -67,7 +67,7 @@ class OnPolicyLearner:
|
|
|
67
67
|
self,
|
|
68
68
|
returns: th.Tensor,
|
|
69
69
|
rewards: th.Tensor,
|
|
70
|
-
|
|
70
|
+
terminated: th.Tensor,
|
|
71
71
|
values: th.Tensor,
|
|
72
72
|
next_values: th.Tensor,
|
|
73
73
|
) -> th.Tensor:
|
|
@@ -87,7 +87,7 @@ class OnPolicyLearner:
|
|
|
87
87
|
if self.config.clip_grad:
|
|
88
88
|
th.nn.utils.clip_grad_norm_(
|
|
89
89
|
self.parameters,
|
|
90
|
-
self.config.
|
|
90
|
+
self.config.clipnorm,
|
|
91
91
|
)
|
|
92
92
|
self.optimizer.step()
|
|
93
93
|
|
|
@@ -106,7 +106,7 @@ class OnPolicyLearner:
|
|
|
106
106
|
self,
|
|
107
107
|
returns: th.Tensor,
|
|
108
108
|
rewards: th.Tensor,
|
|
109
|
-
|
|
109
|
+
terminated: th.Tensor,
|
|
110
110
|
values: th.Tensor,
|
|
111
111
|
next_values: th.Tensor
|
|
112
112
|
) -> th.Tensor:
|
|
@@ -115,7 +115,7 @@ class OnPolicyLearner:
|
|
|
115
115
|
def train(
|
|
116
116
|
self,
|
|
117
117
|
rewards: th.Tensor, # float32, [B,1]
|
|
118
|
-
|
|
118
|
+
terminated: th.Tensor, # bool or float(0/1), [B,1]
|
|
119
119
|
states: th.Tensor, # float32, [B, obs_dim] or [B,C,H,W]
|
|
120
120
|
actions: th.Tensor, # int64, [B,1]
|
|
121
121
|
next_states: th.Tensor, # float32, same as states
|
|
@@ -38,7 +38,7 @@ class PPOLearner(ActorCriticLearner):
|
|
|
38
38
|
def train(
|
|
39
39
|
self,
|
|
40
40
|
rewards: th.Tensor,
|
|
41
|
-
|
|
41
|
+
terminated: th.Tensor,
|
|
42
42
|
states: th.Tensor,
|
|
43
43
|
actions: th.Tensor,
|
|
44
44
|
next_states: th.Tensor,
|
|
@@ -69,7 +69,7 @@ class PPOLearner(ActorCriticLearner):
|
|
|
69
69
|
advantages = self._advantages(
|
|
70
70
|
returns=returns,
|
|
71
71
|
rewards=rewards,
|
|
72
|
-
|
|
72
|
+
terminated=terminated,
|
|
73
73
|
values=old_values,
|
|
74
74
|
next_values=next_values,
|
|
75
75
|
)
|
|
@@ -96,7 +96,7 @@ class PPOLearner(ActorCriticLearner):
|
|
|
96
96
|
value_loss = self.config.value_lambda * self._value_loss(
|
|
97
97
|
returns=returns,
|
|
98
98
|
rewards=rewards,
|
|
99
|
-
|
|
99
|
+
terminated=terminated,
|
|
100
100
|
values=values,
|
|
101
101
|
next_values=next_values,
|
|
102
102
|
)
|
|
@@ -105,7 +105,7 @@ class PPOLearner(ActorCriticLearner):
|
|
|
105
105
|
|
|
106
106
|
reg_loss = self._regularization_loss(
|
|
107
107
|
rewards=rewards,
|
|
108
|
-
|
|
108
|
+
terminated=terminated,
|
|
109
109
|
states=states,
|
|
110
110
|
actions=actions,
|
|
111
111
|
next_states=next_states,
|
|
@@ -18,7 +18,7 @@ class ReinforceLearner(OnPolicyLearner):
|
|
|
18
18
|
self,
|
|
19
19
|
returns: th.Tensor,
|
|
20
20
|
rewards: th.Tensor,
|
|
21
|
-
|
|
21
|
+
terminated: th.Tensor,
|
|
22
22
|
values: th.Tensor | None,
|
|
23
23
|
next_values: th.Tensor | None,
|
|
24
24
|
) -> th.Tensor:
|
|
@@ -34,7 +34,7 @@ class ReinforceLearner(OnPolicyLearner):
|
|
|
34
34
|
def train(
|
|
35
35
|
self,
|
|
36
36
|
rewards: th.Tensor,
|
|
37
|
-
|
|
37
|
+
terminated: th.Tensor,
|
|
38
38
|
states: th.Tensor,
|
|
39
39
|
actions: th.Tensor,
|
|
40
40
|
next_states: th.Tensor,
|
|
@@ -50,7 +50,7 @@ class ReinforceLearner(OnPolicyLearner):
|
|
|
50
50
|
advantages = self._advantages(
|
|
51
51
|
returns=returns,
|
|
52
52
|
rewards=rewards,
|
|
53
|
-
|
|
53
|
+
terminated=terminated,
|
|
54
54
|
values=None,
|
|
55
55
|
next_values=None,
|
|
56
56
|
)
|
|
@@ -60,7 +60,7 @@ class ReinforceLearner(OnPolicyLearner):
|
|
|
60
60
|
entropy_loss = self._entropy_loss(logits)
|
|
61
61
|
reg_loss = self._regularization_loss(
|
|
62
62
|
rewards=rewards,
|
|
63
|
-
|
|
63
|
+
terminated=terminated,
|
|
64
64
|
states=states,
|
|
65
65
|
actions=actions,
|
|
66
66
|
next_states=next_states,
|