streaming-deep-rl 0.3.2__tar.gz → 0.3.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.
- {streaming_deep_rl-0.3.2 → streaming_deep_rl-0.3.4}/PKG-INFO +1 -1
- {streaming_deep_rl-0.3.2 → streaming_deep_rl-0.3.4}/pyproject.toml +1 -1
- {streaming_deep_rl-0.3.2 → streaming_deep_rl-0.3.4}/streaming_deep_rl/streaming_deep_rl.py +31 -10
- {streaming_deep_rl-0.3.2 → streaming_deep_rl-0.3.4}/.gitignore +0 -0
- {streaming_deep_rl-0.3.2 → streaming_deep_rl-0.3.4}/LICENSE +0 -0
- {streaming_deep_rl-0.3.2 → streaming_deep_rl-0.3.4}/README.md +0 -0
- {streaming_deep_rl-0.3.2 → streaming_deep_rl-0.3.4}/streaming_deep_rl/__init__.py +0 -0
- {streaming_deep_rl-0.3.2 → streaming_deep_rl-0.3.4}/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.3.
|
|
3
|
+
Version: 0.3.4
|
|
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
|
|
@@ -5,7 +5,7 @@ from typing import NamedTuple, Literal
|
|
|
5
5
|
|
|
6
6
|
import torch
|
|
7
7
|
import torch.nn.functional as F
|
|
8
|
-
from torch import nn, tensor, is_tensor, cat, Tensor
|
|
8
|
+
from torch import nn, tensor, is_tensor, cat, stack, Tensor
|
|
9
9
|
from torch.nn import Module, Linear, Sequential
|
|
10
10
|
from torch.nn.utils import parameters_to_vector
|
|
11
11
|
|
|
@@ -186,6 +186,7 @@ class SelfPredictRepr(Module):
|
|
|
186
186
|
dim_predict = None,
|
|
187
187
|
target_embed_from_ema = True, # whether the target embed is from an EMA, or from the model itself (traditional vs sigreg from lejepa)
|
|
188
188
|
sigreg_weight = 0.,
|
|
189
|
+
sigreg_num_subspaces = 1,
|
|
189
190
|
dim_hidden_expand_factor = 4,
|
|
190
191
|
use_sem = True,
|
|
191
192
|
sem_dim_simplex = 8,
|
|
@@ -215,6 +216,18 @@ class SelfPredictRepr(Module):
|
|
|
215
216
|
self.apply_sigreg = sigreg_weight > 0.
|
|
216
217
|
self.sigreg_weight = sigreg_weight
|
|
217
218
|
|
|
219
|
+
# sub-jepa subspace gaussian regularization
|
|
220
|
+
# Kai Zhao et al https://arxiv.org/abs/2605.09241v1
|
|
221
|
+
|
|
222
|
+
self.num_subspaces = sigreg_num_subspaces
|
|
223
|
+
|
|
224
|
+
if self.num_subspaces > 1:
|
|
225
|
+
dim_subspace, remainder = divmod(dim_predict, self.num_subspaces)
|
|
226
|
+
assert remainder == 0, f'dimension {dim_predict} must be divisible by number of subspaces {self.num_subspaces}'
|
|
227
|
+
|
|
228
|
+
projs = stack([nn.init.orthogonal_(torch.empty(dim_subspace, dim_predict)) for _ in range(self.num_subspaces)])
|
|
229
|
+
self.register_buffer('subspace_projs', projs)
|
|
230
|
+
|
|
218
231
|
self.use_sem = use_sem
|
|
219
232
|
self.sem = SEM(dim_predict, dim_in = dim_embed, project_in = True, temperature = sem_temperature, dim_simplex = sem_dim_simplex) if use_sem else nn.Identity()
|
|
220
233
|
|
|
@@ -252,7 +265,14 @@ class SelfPredictRepr(Module):
|
|
|
252
265
|
total_loss = recon_loss
|
|
253
266
|
|
|
254
267
|
if self.apply_sigreg:
|
|
255
|
-
|
|
268
|
+
sigreg_input = projected
|
|
269
|
+
|
|
270
|
+
if self.num_subspaces > 1:
|
|
271
|
+
sigreg_input = einx.dot('... dim, k dim_subspace dim -> k ... dim_subspace', sigreg_input, self.subspace_projs)
|
|
272
|
+
else:
|
|
273
|
+
sigreg_input = rearrange(sigreg_input, '... d -> 1 ... d')
|
|
274
|
+
|
|
275
|
+
total_loss = total_loss + self.sigreg_weight * sigreg(sigreg_input)
|
|
256
276
|
|
|
257
277
|
return SSLLosses(total = total_loss, recon = recon_loss)
|
|
258
278
|
|
|
@@ -357,6 +377,7 @@ def sigreg(
|
|
|
357
377
|
mask = None
|
|
358
378
|
):
|
|
359
379
|
# Randall Balestriero - https://arxiv.org/abs/2511.08544
|
|
380
|
+
# Sub-JEPA - https://arxiv.org/abs/2605.09241v1
|
|
360
381
|
|
|
361
382
|
dim, device = x.shape[-1], x.device
|
|
362
383
|
|
|
@@ -375,13 +396,13 @@ def sigreg(
|
|
|
375
396
|
|
|
376
397
|
# empirical CF
|
|
377
398
|
|
|
378
|
-
x_t = einx.dot('... d, m d -> (...) m', x, rand_projs)
|
|
399
|
+
x_t = einx.dot('k ... d, m d -> k (...) m', x, rand_projs)
|
|
379
400
|
|
|
380
|
-
x_t = einx.multiply('n m, t -> n m t', x_t, t)
|
|
401
|
+
x_t = einx.multiply('k n m, t -> k n m t', x_t, t)
|
|
381
402
|
ecf = (1j * x_t).exp()
|
|
382
403
|
|
|
383
|
-
mask_1d = rearrange(mask, '... -> (...)') if exists(mask) else None
|
|
384
|
-
ecf = masked_mean(ecf, mask_1d, dim =
|
|
404
|
+
mask_1d = rearrange(mask, 'k ... -> k (...)') if exists(mask) else None
|
|
405
|
+
ecf = masked_mean(ecf, mask_1d, dim = 1)
|
|
385
406
|
|
|
386
407
|
# weighted L2 distance
|
|
387
408
|
|
|
@@ -1032,8 +1053,8 @@ class StreamingACLambda(Module):
|
|
|
1032
1053
|
|
|
1033
1054
|
td_error_factor = td_error.abs().clamp(min = 1.)
|
|
1034
1055
|
|
|
1035
|
-
actor_grad_norm =
|
|
1036
|
-
critic_grad_norm =
|
|
1056
|
+
actor_grad_norm = stack([g.norm(p = 1) for g in actor_grad.values()]).mean()
|
|
1057
|
+
critic_grad_norm = stack([g.norm(p = 1) for g in value_grad.values()]).mean()
|
|
1037
1058
|
|
|
1038
1059
|
if self.adaptive:
|
|
1039
1060
|
self.step.add_(1)
|
|
@@ -1076,9 +1097,9 @@ class StreamingACLambda(Module):
|
|
|
1076
1097
|
enc_names = [n for n in spr_grads.keys() if n.startswith('0.')]
|
|
1077
1098
|
enc_spr_updates = [-spr_grads[n] * self.spr_lr_param_update for n in enc_names]
|
|
1078
1099
|
enc_rl_updates = [rl_updates[n] for n in enc_names]
|
|
1079
|
-
|
|
1100
|
+
|
|
1080
1101
|
enc_spr_updates_proj = orthog_project_tensors(enc_spr_updates, enc_rl_updates)
|
|
1081
|
-
|
|
1102
|
+
|
|
1082
1103
|
spr_updates_proj = {n: g for n, g in zip(enc_names, enc_spr_updates_proj)}
|
|
1083
1104
|
else:
|
|
1084
1105
|
spr_updates_proj = {}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|