streaming-deep-rl 0.2.0__tar.gz → 0.2.2__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.
- {streaming_deep_rl-0.2.0 → streaming_deep_rl-0.2.2}/PKG-INFO +1 -1
- {streaming_deep_rl-0.2.0 → streaming_deep_rl-0.2.2}/pyproject.toml +1 -1
- {streaming_deep_rl-0.2.0 → streaming_deep_rl-0.2.2}/streaming_deep_rl/streaming_deep_rl.py +63 -11
- {streaming_deep_rl-0.2.0 → streaming_deep_rl-0.2.2}/.gitignore +0 -0
- {streaming_deep_rl-0.2.0 → streaming_deep_rl-0.2.2}/LICENSE +0 -0
- {streaming_deep_rl-0.2.0 → streaming_deep_rl-0.2.2}/README.md +0 -0
- {streaming_deep_rl-0.2.0 → streaming_deep_rl-0.2.2}/streaming_deep_rl/__init__.py +0 -0
- {streaming_deep_rl-0.2.0 → streaming_deep_rl-0.2.2}/streaming_deep_rl/buffer_dict.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: streaming-deep-rl
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Streaming Deep Reinforcement Learning
|
|
5
5
|
Project-URL: Homepage, https://pypi.org/project/streaming-deep-rl/
|
|
6
6
|
Project-URL: Repository, https://codeberg.org/lucidrains/streaming-deep-rl
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
import math
|
|
3
3
|
from collections import deque
|
|
4
|
+
from contextlib import nullcontext
|
|
4
5
|
from typing import Callable, NamedTuple
|
|
5
6
|
|
|
6
7
|
import torch
|
|
@@ -25,12 +26,21 @@ from streaming_deep_rl.buffer_dict import BufferDict
|
|
|
25
26
|
def exists(v):
|
|
26
27
|
return v is not None
|
|
27
28
|
|
|
29
|
+
def identity(t):
|
|
30
|
+
return t
|
|
31
|
+
|
|
28
32
|
def divisible_by(num, den):
|
|
29
33
|
return (num % den) == 0
|
|
30
34
|
|
|
31
35
|
def default(v, d):
|
|
32
36
|
return v if exists(v) else d
|
|
33
37
|
|
|
38
|
+
def no_grad_detach(fn):
|
|
39
|
+
def inner(t):
|
|
40
|
+
with torch.no_grad():
|
|
41
|
+
return fn(t).detach()
|
|
42
|
+
return inner
|
|
43
|
+
|
|
34
44
|
def cast_tensor(t):
|
|
35
45
|
return tensor(t) if not is_tensor(t) else t
|
|
36
46
|
|
|
@@ -104,7 +114,8 @@ class SelfPredictRepr(Module):
|
|
|
104
114
|
dim_embed,
|
|
105
115
|
num_discrete_actions = 0,
|
|
106
116
|
num_continuous_actions = 0,
|
|
107
|
-
dim_predict = None
|
|
117
|
+
dim_predict = None,
|
|
118
|
+
target_embed_from_ema = True # whether the target embed is from an EMA, or from the model itself (traditional vs sigreg from lejepa)
|
|
108
119
|
):
|
|
109
120
|
super().__init__()
|
|
110
121
|
assert num_discrete_actions > 0 or num_continuous_actions > 0
|
|
@@ -113,6 +124,8 @@ class SelfPredictRepr(Module):
|
|
|
113
124
|
|
|
114
125
|
self.to_action_embed = Embed(dim_embed, num_discrete = num_discrete_actions, num_continuous = num_continuous_actions)
|
|
115
126
|
|
|
127
|
+
self.target_embed_from_ema = target_embed_from_ema
|
|
128
|
+
|
|
116
129
|
self.to_projection = nn.Sequential(
|
|
117
130
|
nn.RMSNorm(dim_embed),
|
|
118
131
|
nn.Linear(dim_embed, dim_predict, bias = False)
|
|
@@ -130,8 +143,11 @@ class SelfPredictRepr(Module):
|
|
|
130
143
|
):
|
|
131
144
|
projected = self.to_projection(state_embed)
|
|
132
145
|
|
|
133
|
-
|
|
134
|
-
|
|
146
|
+
# maybe no
|
|
147
|
+
|
|
148
|
+
decorator = no_grad_detach if self.target_embed_from_ema else identity
|
|
149
|
+
|
|
150
|
+
next_projected = decorator(self.to_projection)(next_state_embed)
|
|
135
151
|
|
|
136
152
|
action_embed = self.to_action_embed(actions)
|
|
137
153
|
|
|
@@ -314,7 +330,8 @@ class StreamingACLambda(Module):
|
|
|
314
330
|
actor_use_ema = False,
|
|
315
331
|
actor_ema_beta = 0.7,
|
|
316
332
|
critic_ema_beta = 0.7,
|
|
317
|
-
|
|
333
|
+
actor_self_predict_repr = False,
|
|
334
|
+
critic_self_predict_repr = False,
|
|
318
335
|
entropy_weight = 0.01,
|
|
319
336
|
init_sparsity = 0.9,
|
|
320
337
|
dim_critic = 128,
|
|
@@ -384,18 +401,29 @@ class StreamingACLambda(Module):
|
|
|
384
401
|
# self-predictive representation
|
|
385
402
|
# Schwarzer et al. https://arxiv.org/abs/2007.05929
|
|
386
403
|
|
|
387
|
-
self.
|
|
404
|
+
self.actor_self_predict_repr = actor_self_predict_repr
|
|
405
|
+
self.critic_self_predict_repr = critic_self_predict_repr
|
|
388
406
|
|
|
389
|
-
if
|
|
407
|
+
if actor_self_predict_repr:
|
|
390
408
|
|
|
391
409
|
actor_use_ema |= True
|
|
392
410
|
|
|
393
|
-
self.
|
|
411
|
+
self.actor_spr = SelfPredictRepr(
|
|
394
412
|
dim_actor,
|
|
395
413
|
num_discrete_actions = num_discrete_actions,
|
|
396
414
|
num_continuous_actions = num_continuous_actions,
|
|
397
415
|
)
|
|
398
416
|
|
|
417
|
+
if critic_self_predict_repr:
|
|
418
|
+
|
|
419
|
+
use_critic_ema |= True
|
|
420
|
+
|
|
421
|
+
self.critic_spr = SelfPredictRepr(
|
|
422
|
+
dim_critic,
|
|
423
|
+
num_discrete_actions = num_discrete_actions,
|
|
424
|
+
num_continuous_actions = num_continuous_actions,
|
|
425
|
+
)
|
|
426
|
+
|
|
399
427
|
# actor
|
|
400
428
|
|
|
401
429
|
self.actor = actor
|
|
@@ -652,7 +680,7 @@ class StreamingACLambda(Module):
|
|
|
652
680
|
# get the SPR loss
|
|
653
681
|
|
|
654
682
|
actor_spr_grad = None
|
|
655
|
-
if self.
|
|
683
|
+
if self.actor_self_predict_repr:
|
|
656
684
|
actor_embed = self.actor(oldest_state)
|
|
657
685
|
|
|
658
686
|
if self.actor_use_ema:
|
|
@@ -660,9 +688,9 @@ class StreamingACLambda(Module):
|
|
|
660
688
|
else:
|
|
661
689
|
actor_next_embed = self.actor(last_next_state)
|
|
662
690
|
|
|
663
|
-
spr_loss = self.
|
|
691
|
+
spr_loss = self.actor_spr(actor_embed, oldest_action, actor_next_embed)
|
|
664
692
|
|
|
665
|
-
spr_params = list(self.
|
|
693
|
+
spr_params = list(self.actor_spr.parameters())
|
|
666
694
|
spr_grads_tup = torch.autograd.grad(spr_loss, actor_params + spr_params, retain_graph = True, allow_unused = True)
|
|
667
695
|
spr_grads_tup = tuple(default(g, torch.zeros_like(p)) for g, p in zip(spr_grads_tup, actor_params + spr_params))
|
|
668
696
|
|
|
@@ -673,6 +701,30 @@ class StreamingACLambda(Module):
|
|
|
673
701
|
for param, grad in zip(spr_params, spr_only_grad):
|
|
674
702
|
param.data.add_(grad, alpha = -self.actor_lr)
|
|
675
703
|
|
|
704
|
+
# critic SPR loss
|
|
705
|
+
|
|
706
|
+
critic_spr_grad = None
|
|
707
|
+
if self.critic_self_predict_repr:
|
|
708
|
+
critic_embed = self.critic(oldest_state)
|
|
709
|
+
|
|
710
|
+
if self.use_critic_ema:
|
|
711
|
+
critic_next_embed = self.critic_ema.ema_model[0](last_next_state)
|
|
712
|
+
else:
|
|
713
|
+
critic_next_embed = self.critic(last_next_state)
|
|
714
|
+
|
|
715
|
+
critic_spr_loss = self.critic_spr(critic_embed, oldest_action, critic_next_embed)
|
|
716
|
+
|
|
717
|
+
critic_spr_params = list(self.critic_spr.parameters())
|
|
718
|
+
critic_spr_grads_tup = torch.autograd.grad(critic_spr_loss, critic_params + critic_spr_params, retain_graph = True, allow_unused = True)
|
|
719
|
+
critic_spr_grads_tup = tuple(default(g, torch.zeros_like(p)) for g, p in zip(critic_spr_grads_tup, critic_params + critic_spr_params))
|
|
720
|
+
|
|
721
|
+
critic_spr_grad = {name: grad for (name, _), grad in zip(self.critic_full.named_parameters(), critic_spr_grads_tup[:len(critic_params)])}
|
|
722
|
+
critic_spr_only_grad = critic_spr_grads_tup[len(critic_params):]
|
|
723
|
+
|
|
724
|
+
# Update SPR networks via SGD
|
|
725
|
+
for param, grad in zip(critic_spr_params, critic_spr_only_grad):
|
|
726
|
+
param.data.add_(grad, alpha = -self.critic_lr)
|
|
727
|
+
|
|
676
728
|
# entropy gradient decoupled from td_error
|
|
677
729
|
|
|
678
730
|
entropy_grads_tup = torch.autograd.grad(entropy, actor_params, retain_graph = True)
|
|
@@ -820,7 +872,7 @@ class StreamingACLambda(Module):
|
|
|
820
872
|
self.cautious_wd,
|
|
821
873
|
self.wd_towards_init,
|
|
822
874
|
None,
|
|
823
|
-
|
|
875
|
+
critic_spr_grad
|
|
824
876
|
)
|
|
825
877
|
|
|
826
878
|
if self.actor_use_ema:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|