braintrace 0.2.4__tar.gz → 0.2.6__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.
- {braintrace-0.2.4 → braintrace-0.2.6}/PKG-INFO +45 -3
- {braintrace-0.2.4 → braintrace-0.2.6}/README.md +42 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/__init__.py +33 -11
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/__init___test.py +47 -26
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/__init__.py +21 -10
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/_common.py +90 -137
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/_common_test.py +0 -25
- braintrace-0.2.6/braintrace/_algorithm/axes.py +663 -0
- braintrace-0.2.6/braintrace/_algorithm/axes_test.py +497 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/base.py +51 -11
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/base_test.py +2 -2
- braintrace-0.2.6/braintrace/_algorithm/d_rtrl.py +107 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/d_rtrl_test.py +1 -1
- braintrace-0.2.6/braintrace/_algorithm/dni.py +668 -0
- braintrace-0.2.6/braintrace/_algorithm/dni_test.py +1004 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/e_prop.py +41 -122
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/e_prop_test.py +1 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/graph_executor.py +27 -9
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/graph_executor_test.py +1 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/io_dim_vjp.py +339 -144
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/io_dim_vjp_test.py +92 -4
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/ostl.py +59 -12
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/ostl_test.py +1 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/param_dim_vjp.py +565 -292
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/param_dim_vjp_test.py +3 -2
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/pp_prop.py +34 -4
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/pp_prop_test.py +9 -4
- braintrace-0.2.6/braintrace/_algorithm/random_projection_vjp.py +701 -0
- braintrace-0.2.6/braintrace/_algorithm/random_projection_vjp_test.py +412 -0
- braintrace-0.2.6/braintrace/_algorithm/sequence.py +575 -0
- braintrace-0.2.6/braintrace/_algorithm/sequence_test.py +1534 -0
- braintrace-0.2.6/braintrace/_algorithm/snap_n.py +221 -0
- braintrace-0.2.6/braintrace/_algorithm/snap_n_test.py +1289 -0
- braintrace-0.2.6/braintrace/_algorithm/tests/approx_correctness_test.py +308 -0
- braintrace-0.2.6/braintrace/_algorithm/tests/axis_acceptance_test.py +520 -0
- braintrace-0.2.6/braintrace/_algorithm/tests/axis_discrimination_test.py +111 -0
- braintrace-0.2.6/braintrace/_algorithm/tests/axis_golden_test.py +337 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/tests/diagnostic_exploration_test.py +2 -2
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/tests/exact_correctness_test.py +25 -77
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/tests/public_api_test.py +17 -3
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/tests/scan_descent_support_test.py +2 -2
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/tests/scan_fusion_test.py +2 -2
- braintrace-0.2.6/braintrace/_algorithm/tests/snn_model_correctness_test.py +136 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/tests/transform_correctness_test.py +3 -82
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/tests/while_support_test.py +2 -2
- braintrace-0.2.6/braintrace/_algorithm/three_factor.py +200 -0
- braintrace-0.2.6/braintrace/_algorithm/three_factor_test.py +651 -0
- braintrace-0.2.6/braintrace/_algorithm/uoro.py +181 -0
- braintrace-0.2.6/braintrace/_algorithm/uoro_test.py +912 -0
- braintrace-0.2.6/braintrace/_algorithm/vjp_base.py +1908 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/vjp_base_test.py +493 -28
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/vjp_graph_executor.py +85 -21
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/vjp_graph_executor_test.py +57 -0
- braintrace-0.2.6/braintrace/_compatible_imports.py +280 -0
- braintrace-0.2.6/braintrace/_compatible_imports_test.py +227 -0
- braintrace-0.2.6/braintrace/_compile.py +396 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compile_test.py +26 -9
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/__init__.py +70 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/base.py +6 -5
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/canonicalize.py +318 -120
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/canonicalize_test.py +435 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/diagnostics.py +12 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/graph.py +118 -24
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/graph_test.py +76 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/hid_param_op.py +18 -9
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/hid_param_op_test.py +30 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/hidden_group.py +660 -123
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/hidden_group_test.py +429 -2
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/hidden_pertubation.py +108 -67
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/hidden_pertubation_test.py +63 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/jaxpr_graph.py +12 -5
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/module_info.py +65 -38
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/module_info_test.py +1 -1
- braintrace-0.2.6/braintrace/_compiler/position_graph.py +636 -0
- braintrace-0.2.6/braintrace/_compiler/position_graph_test.py +604 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/report.py +2 -2
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/report_test.py +1 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/scan_descent.py +16 -10
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/scan_descent_test.py +19 -8
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/tests/compiler_oracle_test.py +6 -2
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/tests/compiler_property_test.py +1 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_grad_exponential.py +0 -5
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_input_data.py +69 -39
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_legacy/_ops.py +35 -35
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_legacy/_params.py +28 -21
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_misc.py +8 -4
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/__init__.py +22 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/_primitive.py +25 -3
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/_registries.py +105 -12
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/_registries_test.py +91 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/conv.py +29 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/conv_test.py +1 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/dense.py +49 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/dense_test.py +2 -2
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/einsum.py +31 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/einsum_test.py +1 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/elemwise.py +69 -25
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/elemwise_test.py +1 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/embedding_test.py +1 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/grouped.py +23 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/grouped_test.py +1 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/lora.py +23 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/lora_test.py +1 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/sparse.py +81 -12
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/sparse_test.py +20 -20
- braintrace-0.2.4/braintrace/_state_managment.py → braintrace-0.2.6/braintrace/_state_management.py +2 -10
- braintrace-0.2.4/braintrace/_state_managment_test.py → braintrace-0.2.6/braintrace/_state_management_test.py +1 -1
- braintrace-0.2.6/braintrace/_testing/__init__.py +50 -0
- braintrace-0.2.6/braintrace/_testing/oracle.py +779 -0
- braintrace-0.2.6/braintrace/_testing/oracle_models.py +1227 -0
- braintrace-0.2.6/braintrace/_testing/oracle_models_test.py +348 -0
- {braintrace-0.2.4/braintrace/_algorithm → braintrace-0.2.6/braintrace/_testing}/oracle_test.py +324 -32
- {braintrace-0.2.4/braintrace/_compiler → braintrace-0.2.6/braintrace/_testing}/scenario_catalog_test.py +4 -4
- braintrace-0.2.6/braintrace/_typing_test.py +295 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_version.py +1 -1
- braintrace-0.2.6/braintrace/_version_test.py +170 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/nn/__init__.py +48 -26
- braintrace-0.2.6/braintrace/nn/__init___test.py +248 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/nn/_conv.py +41 -3
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/nn/_conv_test.py +67 -0
- braintrace-0.2.6/braintrace/nn/_embedding.py +288 -0
- braintrace-0.2.6/braintrace/nn/_embedding_test.py +186 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/nn/_linear_test.py +4 -4
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/nn/_rnn.py +6 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/nn/_rnn_test.py +57 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace.egg-info/PKG-INFO +45 -3
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace.egg-info/SOURCES.txt +35 -16
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace.egg-info/requires.txt +2 -1
- {braintrace-0.2.4 → braintrace-0.2.6}/pyproject.toml +99 -11
- braintrace-0.2.6/setup.py +136 -0
- braintrace-0.2.4/braintrace/_algorithm/d_rtrl.py +0 -58
- braintrace-0.2.4/braintrace/_algorithm/oracle.py +0 -276
- braintrace-0.2.4/braintrace/_algorithm/oracle_models.py +0 -467
- braintrace-0.2.4/braintrace/_algorithm/osttp.py +0 -232
- braintrace-0.2.4/braintrace/_algorithm/osttp_test.py +0 -243
- braintrace-0.2.4/braintrace/_algorithm/otpe.py +0 -497
- braintrace-0.2.4/braintrace/_algorithm/otpe_test.py +0 -423
- braintrace-0.2.4/braintrace/_algorithm/ottt.py +0 -357
- braintrace-0.2.4/braintrace/_algorithm/ottt_test.py +0 -327
- braintrace-0.2.4/braintrace/_algorithm/tests/approx_correctness_test.py +0 -323
- braintrace-0.2.4/braintrace/_algorithm/vjp_base.py +0 -857
- braintrace-0.2.4/braintrace/_compatible_imports.py +0 -81
- braintrace-0.2.4/braintrace/_compatible_imports_test.py +0 -94
- braintrace-0.2.4/braintrace/_compile.py +0 -305
- braintrace-0.2.4/braintrace/_docs_examples_test.py +0 -247
- braintrace-0.2.4/braintrace/nn/_embedding.py +0 -81
- braintrace-0.2.4/braintrace/nn/_embedding_test.py +0 -75
- {braintrace-0.2.4 → braintrace-0.2.6}/LICENSE +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/tests/conv_vmap_correctness_test.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_algorithm/tests/cross_check_test.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/base_test.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/diagnostics_test.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/jaxpr_graph_test.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_compiler/tests/cell_relation_guardrail_test.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_grad_exponential_test.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_input_data_test.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_legacy/__init__.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_legacy/_ops_test.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_legacy/_params_test.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_misc_test.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/_primitive_test.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/embedding.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/op_rule_oracle.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_op/op_rule_oracle_test.py +0 -0
- /braintrace-0.2.4/braintrace/_compiler/model4test.py → /braintrace-0.2.6/braintrace/_testing/compiler_models.py +0 -0
- /braintrace-0.2.4/braintrace/_etrace_model_test.py → /braintrace-0.2.6/braintrace/_testing/models.py +0 -0
- {braintrace-0.2.4/braintrace/_compiler → braintrace-0.2.6/braintrace/_testing}/scenario_catalog.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/_typing.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/nn/_linear.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/nn/_readout.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/nn/_readout_test.py +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace/py.typed +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace.egg-info/dependency_links.txt +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/braintrace.egg-info/top_level.txt +0 -0
- {braintrace-0.2.4 → braintrace-0.2.6}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: braintrace
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: Enabling Scalable Online Learning for Brain Dynamics.
|
|
5
5
|
Author-email: BrainTrace Developers <chao.brain@qq.com>
|
|
6
6
|
License: Apache-2.0 license
|
|
@@ -26,9 +26,10 @@ Classifier: Topic :: Software Development :: Libraries
|
|
|
26
26
|
Requires-Python: >=3.11
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
License-File: LICENSE
|
|
29
|
+
Requires-Dist: jax>=0.8.0
|
|
29
30
|
Requires-Dist: brainstate>=0.5.2
|
|
30
31
|
Requires-Dist: brainunit
|
|
31
|
-
Requires-Dist: brainevent
|
|
32
|
+
Requires-Dist: brainevent>=0.1.2
|
|
32
33
|
Requires-Dist: brainpy.state
|
|
33
34
|
Requires-Dist: braintools
|
|
34
35
|
Provides-Extra: cpu
|
|
@@ -74,7 +75,7 @@ It has been integrated into our establishing [brain modeling ecosystem](https://
|
|
|
74
75
|
|
|
75
76
|
## Installation
|
|
76
77
|
|
|
77
|
-
``braintrace``
|
|
78
|
+
``braintrace`` requires Python 3.11 or newer and supports Linux, macOS, and Windows. You can install ``braintrace`` via pip:
|
|
78
79
|
|
|
79
80
|
```bash
|
|
80
81
|
pip install braintrace --upgrade
|
|
@@ -86,6 +87,47 @@ Alternatively, you can install `BrainX`, which bundles `braintrace` with other c
|
|
|
86
87
|
pip install BrainX -U
|
|
87
88
|
```
|
|
88
89
|
|
|
90
|
+
## Quickstart
|
|
91
|
+
|
|
92
|
+
Mark the trainable operations with an ETP primitive (here, via `braintrace.nn`
|
|
93
|
+
layers, which use them internally), then compile the model into a learner and
|
|
94
|
+
drive a sequence. There is no scan to write and no special parameter class —
|
|
95
|
+
weights stay plain `brainstate.ParamState`.
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
import brainstate
|
|
99
|
+
import jax.numpy as jnp
|
|
100
|
+
import braintrace
|
|
101
|
+
|
|
102
|
+
class GRUNet(brainstate.nn.Module):
|
|
103
|
+
def __init__(self, n_in, n_rec, n_out):
|
|
104
|
+
super().__init__()
|
|
105
|
+
self.rnn = braintrace.nn.GRUCell(n_in, n_rec)
|
|
106
|
+
self.out = braintrace.nn.Linear(n_rec, n_out)
|
|
107
|
+
|
|
108
|
+
def update(self, x):
|
|
109
|
+
return self.out(self.rnn(x))
|
|
110
|
+
|
|
111
|
+
model = GRUNet(3, 8, 1)
|
|
112
|
+
|
|
113
|
+
# One call: initialise states, compile the eligibility-trace graph,
|
|
114
|
+
# return a ready learner.
|
|
115
|
+
learner = braintrace.compile(model, braintrace.D_RTRL, jnp.zeros((1, 3)), batch_size=1)
|
|
116
|
+
|
|
117
|
+
def step_loss(x, y):
|
|
118
|
+
return jnp.mean((learner(x) - y) ** 2)
|
|
119
|
+
|
|
120
|
+
xs = brainstate.random.randn(100, 1, 3) # (time, batch, features)
|
|
121
|
+
ys = brainstate.random.randn(100, 1, 1)
|
|
122
|
+
|
|
123
|
+
# Drives the sequence and accumulates online gradients -- O(1) memory in T.
|
|
124
|
+
grads, losses = learner.etrace_grad(xs, ys, step_fn=step_loss, return_value=True)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Swap `braintrace.D_RTRL` for `pp_prop`, `SnAp`, `UORO`, `ThreeFactor`, `DNI`,
|
|
128
|
+
`EProp`, the OSTL variants, or an explicit `braintrace.ETraceConfig` to change
|
|
129
|
+
the learning rule; nothing else in the snippet changes.
|
|
130
|
+
|
|
89
131
|
## Documentation
|
|
90
132
|
|
|
91
133
|
The official documentation is hosted on Read the Docs: [https://brainx.chaobrain.com/braintrace](https://brainx.chaobrain.com/braintrace)
|
|
@@ -19,7 +19,7 @@ It has been integrated into our establishing [brain modeling ecosystem](https://
|
|
|
19
19
|
|
|
20
20
|
## Installation
|
|
21
21
|
|
|
22
|
-
``braintrace``
|
|
22
|
+
``braintrace`` requires Python 3.11 or newer and supports Linux, macOS, and Windows. You can install ``braintrace`` via pip:
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
pip install braintrace --upgrade
|
|
@@ -31,6 +31,47 @@ Alternatively, you can install `BrainX`, which bundles `braintrace` with other c
|
|
|
31
31
|
pip install BrainX -U
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
+
## Quickstart
|
|
35
|
+
|
|
36
|
+
Mark the trainable operations with an ETP primitive (here, via `braintrace.nn`
|
|
37
|
+
layers, which use them internally), then compile the model into a learner and
|
|
38
|
+
drive a sequence. There is no scan to write and no special parameter class —
|
|
39
|
+
weights stay plain `brainstate.ParamState`.
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
import brainstate
|
|
43
|
+
import jax.numpy as jnp
|
|
44
|
+
import braintrace
|
|
45
|
+
|
|
46
|
+
class GRUNet(brainstate.nn.Module):
|
|
47
|
+
def __init__(self, n_in, n_rec, n_out):
|
|
48
|
+
super().__init__()
|
|
49
|
+
self.rnn = braintrace.nn.GRUCell(n_in, n_rec)
|
|
50
|
+
self.out = braintrace.nn.Linear(n_rec, n_out)
|
|
51
|
+
|
|
52
|
+
def update(self, x):
|
|
53
|
+
return self.out(self.rnn(x))
|
|
54
|
+
|
|
55
|
+
model = GRUNet(3, 8, 1)
|
|
56
|
+
|
|
57
|
+
# One call: initialise states, compile the eligibility-trace graph,
|
|
58
|
+
# return a ready learner.
|
|
59
|
+
learner = braintrace.compile(model, braintrace.D_RTRL, jnp.zeros((1, 3)), batch_size=1)
|
|
60
|
+
|
|
61
|
+
def step_loss(x, y):
|
|
62
|
+
return jnp.mean((learner(x) - y) ** 2)
|
|
63
|
+
|
|
64
|
+
xs = brainstate.random.randn(100, 1, 3) # (time, batch, features)
|
|
65
|
+
ys = brainstate.random.randn(100, 1, 1)
|
|
66
|
+
|
|
67
|
+
# Drives the sequence and accumulates online gradients -- O(1) memory in T.
|
|
68
|
+
grads, losses = learner.etrace_grad(xs, ys, step_fn=step_loss, return_value=True)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Swap `braintrace.D_RTRL` for `pp_prop`, `SnAp`, `UORO`, `ThreeFactor`, `DNI`,
|
|
72
|
+
`EProp`, the OSTL variants, or an explicit `braintrace.ETraceConfig` to change
|
|
73
|
+
the learning rule; nothing else in the snippet changes.
|
|
74
|
+
|
|
34
75
|
## Documentation
|
|
35
76
|
|
|
36
77
|
The official documentation is hosted on Read the Docs: [https://brainx.chaobrain.com/braintrace](https://brainx.chaobrain.com/braintrace)
|
|
@@ -41,8 +41,10 @@ downward:
|
|
|
41
41
|
hidden->weight / hidden->hidden Jacobian computations.
|
|
42
42
|
4. **Algorithms** — online-learning orchestrators: the exact algorithms
|
|
43
43
|
:class:`D_RTRL` / :func:`pp_prop` / :class:`ES_D_RTRL`, and the SNN family
|
|
44
|
-
:class:`EProp`, :class:`OSTLRecurrent`, :class:`OSTLFeedforward
|
|
45
|
-
|
|
44
|
+
:class:`EProp`, :class:`OSTLRecurrent`, :class:`OSTLFeedforward`. Every one
|
|
45
|
+
of them carries the two sequence drivers of
|
|
46
|
+
:class:`SequenceDriverMixin` — ``etrace_grad`` and ``etrace_evolve`` — so a
|
|
47
|
+
caller never writes the per-step gradient-accumulation loop by hand.
|
|
46
48
|
|
|
47
49
|
The :mod:`braintrace.nn` subpackage provides ready-made ETP-wired layers
|
|
48
50
|
(linear maps, convolutions, recurrent cells, read-outs).
|
|
@@ -50,7 +52,13 @@ The :mod:`braintrace.nn` subpackage provides ready-made ETP-wired layers
|
|
|
50
52
|
Notes
|
|
51
53
|
-----
|
|
52
54
|
The convenience entry point :func:`compile` wraps a model together with an
|
|
53
|
-
algorithm into a single trainable object and is the recommended starting point
|
|
55
|
+
algorithm into a single trainable object and is the recommended starting point:
|
|
56
|
+
one call replaces ``init_all_states`` + algorithm construction +
|
|
57
|
+
``compile_graph`` (+ the vmap wrapper, with ``vmap=True``). The object it
|
|
58
|
+
returns drives a sequence with :meth:`~SequenceDriverMixin.etrace_grad`
|
|
59
|
+
(accumulate online gradients under a loss) or
|
|
60
|
+
:meth:`~SequenceDriverMixin.etrace_evolve` (advance hidden state and the
|
|
61
|
+
eligibility trace with no loss).
|
|
54
62
|
The ``braintrace.MatMulOp`` / ``ETraceParam`` style names from the v0.1.x API
|
|
55
63
|
are deprecated shims served lazily with a :class:`DeprecationWarning`; new code
|
|
56
64
|
should mark parameters by routing them through ETP ops instead.
|
|
@@ -73,9 +81,12 @@ from typing import TYPE_CHECKING, Any
|
|
|
73
81
|
from . import nn
|
|
74
82
|
from ._compile import compile
|
|
75
83
|
from ._algorithm import (
|
|
84
|
+
ETraceConfig,
|
|
76
85
|
ETraceAlgorithm,
|
|
77
86
|
EligibilityTrace,
|
|
78
87
|
ETraceGraphExecutor,
|
|
88
|
+
ETraceVmap,
|
|
89
|
+
SequenceDriverMixin,
|
|
79
90
|
ETraceVjpAlgorithm,
|
|
80
91
|
ETraceVjpGraphExecutor,
|
|
81
92
|
ParamDimVjpAlgorithm,
|
|
@@ -83,15 +94,18 @@ from ._algorithm import (
|
|
|
83
94
|
pp_prop,
|
|
84
95
|
ES_D_RTRL,
|
|
85
96
|
IODimVjpAlgorithm,
|
|
97
|
+
SnAp,
|
|
98
|
+
RandomProjectionVjpAlgorithm,
|
|
99
|
+
UORO,
|
|
100
|
+
ThreeFactor,
|
|
101
|
+
DNI,
|
|
102
|
+
SyntheticGradient,
|
|
103
|
+
train_synthetic_gradient,
|
|
86
104
|
EProp,
|
|
87
105
|
OSTLRecurrent,
|
|
88
106
|
OSTLFeedforward,
|
|
89
|
-
OTPE,
|
|
90
|
-
OTTT,
|
|
91
|
-
OSTTP,
|
|
92
107
|
FixedRandomFeedback,
|
|
93
108
|
KappaFilter,
|
|
94
|
-
PresynapticTrace,
|
|
95
109
|
)
|
|
96
110
|
from ._compiler import (
|
|
97
111
|
ControlFlowPolicy,
|
|
@@ -156,9 +170,14 @@ __all__ = [
|
|
|
156
170
|
'__version__',
|
|
157
171
|
'__version_info__',
|
|
158
172
|
|
|
173
|
+
# learning-rule axes
|
|
174
|
+
'ETraceConfig',
|
|
175
|
+
|
|
159
176
|
# algorithms
|
|
160
177
|
'ETraceAlgorithm',
|
|
161
178
|
'EligibilityTrace',
|
|
179
|
+
'ETraceVmap',
|
|
180
|
+
'SequenceDriverMixin',
|
|
162
181
|
'ETraceVjpAlgorithm',
|
|
163
182
|
'ETraceVjpGraphExecutor',
|
|
164
183
|
'ParamDimVjpAlgorithm',
|
|
@@ -166,6 +185,13 @@ __all__ = [
|
|
|
166
185
|
'pp_prop',
|
|
167
186
|
'ES_D_RTRL',
|
|
168
187
|
'IODimVjpAlgorithm',
|
|
188
|
+
'SnAp',
|
|
189
|
+
'RandomProjectionVjpAlgorithm',
|
|
190
|
+
'UORO',
|
|
191
|
+
'ThreeFactor',
|
|
192
|
+
'DNI',
|
|
193
|
+
'SyntheticGradient',
|
|
194
|
+
'train_synthetic_gradient',
|
|
169
195
|
|
|
170
196
|
# one-call entry point
|
|
171
197
|
'compile',
|
|
@@ -220,12 +246,8 @@ __all__ = [
|
|
|
220
246
|
'EProp',
|
|
221
247
|
'OSTLRecurrent',
|
|
222
248
|
'OSTLFeedforward',
|
|
223
|
-
'OTPE',
|
|
224
|
-
'OTTT',
|
|
225
|
-
'OSTTP',
|
|
226
249
|
'FixedRandomFeedback',
|
|
227
250
|
'KappaFilter',
|
|
228
|
-
'PresynapticTrace',
|
|
229
251
|
|
|
230
252
|
# errors
|
|
231
253
|
'NotSupportedError',
|
|
@@ -33,7 +33,7 @@ import pytest
|
|
|
33
33
|
|
|
34
34
|
import braintrace
|
|
35
35
|
import braintrace._legacy as legacy
|
|
36
|
-
from braintrace.
|
|
36
|
+
from braintrace._testing.oracle_models import tanh_rnn
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
# ===========================================================================
|
|
@@ -71,6 +71,10 @@ def _algo_constructors():
|
|
|
71
71
|
'EProp': lambda m: braintrace.EProp(m),
|
|
72
72
|
'OSTLRecurrent': lambda m: braintrace.OSTLRecurrent(m),
|
|
73
73
|
'OSTLFeedforward': lambda m: braintrace.OSTLFeedforward(m, decay_or_rank=0.9),
|
|
74
|
+
'SnAp': lambda m: braintrace.SnAp(m, n=1),
|
|
75
|
+
'UORO': lambda m: braintrace.UORO(m),
|
|
76
|
+
# `modulatory` has no fallback: a standing modulator is required.
|
|
77
|
+
'ThreeFactor': lambda m: braintrace.ThreeFactor(m, modulator=0.5),
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
|
|
@@ -87,33 +91,30 @@ def test_algorithm_is_usable_end_to_end(name):
|
|
|
87
91
|
assert bool(jnp.all(jnp.isfinite(y)))
|
|
88
92
|
|
|
89
93
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
model = tanh_rnn(seed=0).factory()
|
|
94
|
+
def test_dni_is_usable_end_to_end():
|
|
95
|
+
# DNI is the one preset whose second collaborator is sized from the compiled
|
|
96
|
+
# graph, so it cannot join the shared map above: build, compile, then attach.
|
|
97
|
+
model = tanh_rnn(n_in=3, n_rec=4, seed=0).factory()
|
|
94
98
|
brainstate.nn.init_all_states(model, batch_size=1)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
+
algo = braintrace.DNI(model)
|
|
100
|
+
x0 = jnp.ones((3,), dtype='float32')
|
|
101
|
+
algo.compile_graph(x0)
|
|
102
|
+
algo.init_etrace_state()
|
|
103
|
+
algo.attach_synthesizer(
|
|
104
|
+
braintrace.SyntheticGradient(algo.group_signal_shapes()))
|
|
105
|
+
y = algo(x0)
|
|
106
|
+
assert y.shape == (1, 4)
|
|
107
|
+
assert bool(jnp.all(jnp.isfinite(y)))
|
|
99
108
|
|
|
100
109
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def test_osttp_constructs_with_B_list():
|
|
111
|
-
model = tanh_rnn(n_in=3, n_rec=4, seed=0).factory()
|
|
112
|
-
brainstate.nn.init_all_states(model, batch_size=1)
|
|
113
|
-
# OSTTP needs one random-feedback matrix per HiddenGroup; B.shape[1] == n_l (=4).
|
|
114
|
-
B_list = [jnp.eye(4, dtype='float32')]
|
|
115
|
-
algo = braintrace.OSTTP(model, B_list)
|
|
116
|
-
assert algo is not None
|
|
110
|
+
@pytest.mark.parametrize('name', ['UORO', 'ThreeFactor', 'DNI',
|
|
111
|
+
'SyntheticGradient', 'train_synthetic_gradient',
|
|
112
|
+
'RandomProjectionVjpAlgorithm'])
|
|
113
|
+
def test_p4_symbols_are_exported_from_both_all_lists(name):
|
|
114
|
+
from braintrace import _algorithm
|
|
115
|
+
assert name in braintrace.__all__, f'{name} missing from braintrace.__all__'
|
|
116
|
+
assert name in _algorithm.__all__, f'{name} missing from _algorithm.__all__'
|
|
117
|
+
assert getattr(braintrace, name) is getattr(_algorithm, name)
|
|
117
118
|
|
|
118
119
|
|
|
119
120
|
# --- Task 4: dynamic weight assignment raises NotSupportedError --------------
|
|
@@ -200,6 +201,14 @@ def test_nn_forwarded_name_warns():
|
|
|
200
201
|
_ = nn.LayerNorm
|
|
201
202
|
|
|
202
203
|
|
|
204
|
+
def test_nn_forwarded_state_name_warns_and_resolves():
|
|
205
|
+
import brainpy.state
|
|
206
|
+
import braintrace.nn as nn
|
|
207
|
+
with pytest.warns(DeprecationWarning):
|
|
208
|
+
forwarded = nn.LIF
|
|
209
|
+
assert forwarded is brainpy.state.LIF
|
|
210
|
+
|
|
211
|
+
|
|
203
212
|
def test_nn_unknown_name_raises_attribute_error():
|
|
204
213
|
import braintrace.nn as nn
|
|
205
214
|
with pytest.raises(AttributeError):
|
|
@@ -226,8 +235,20 @@ def test_iodim_lives_in_io_dim_vjp_module():
|
|
|
226
235
|
def test_expected_rnn_cells_exist():
|
|
227
236
|
import braintrace.nn as nn
|
|
228
237
|
for cell in ('ValinaRNNCell', 'GRUCell', 'MGUCell', 'LSTMCell', 'URLSTMCell',
|
|
229
|
-
'MinimalRNNCell', 'MiniGRU', 'MiniLSTM', 'LRUCell'):
|
|
238
|
+
'MinimalRNNCell', 'MiniGRU', 'MiniLSTM', 'LRUCell', 'CFNCell'):
|
|
230
239
|
assert hasattr(nn, cell), f"missing cell: {cell}"
|
|
240
|
+
assert cell in nn.__all__, f"cell not in __all__: {cell}"
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def test_nn_dir_advertises_deprecated_forwards():
|
|
244
|
+
# ``braintrace.nn.__getattr__`` forwards ~50 names to brainstate.nn /
|
|
245
|
+
# brainpy.state. Without ``__dir__`` none of them is discoverable, so the
|
|
246
|
+
# forwarding is invisible to tab-completion and to ``dir()``-based tooling.
|
|
247
|
+
import braintrace.nn as nn
|
|
248
|
+
names = dir(nn)
|
|
249
|
+
assert 'ReLU' in names # forwarded to brainstate.nn
|
|
250
|
+
assert 'LIF' in names # forwarded to brainpy.state
|
|
251
|
+
assert set(nn.__all__).issubset(names)
|
|
231
252
|
|
|
232
253
|
|
|
233
254
|
# ===========================================================================
|
|
@@ -17,32 +17,40 @@
|
|
|
17
17
|
|
|
18
18
|
Groups the core ETrace infrastructure (``ETraceAlgorithm``, ``EligibilityTrace``,
|
|
19
19
|
``ETraceGraphExecutor``), VJP-based algorithms (D-RTRL, pp_prop / ES-D-RTRL),
|
|
20
|
-
and paper-faithful SNN algorithms (EProp, OSTLRecurrent, OSTLFeedforward
|
|
21
|
-
OTTT, OSTTP).
|
|
20
|
+
and paper-faithful SNN algorithms (EProp, OSTLRecurrent, OSTLFeedforward).
|
|
22
21
|
"""
|
|
23
22
|
|
|
24
23
|
from __future__ import annotations
|
|
25
24
|
|
|
26
|
-
from ._common import FixedRandomFeedback, KappaFilter
|
|
25
|
+
from ._common import FixedRandomFeedback, KappaFilter
|
|
26
|
+
from .axes import ETraceConfig
|
|
27
27
|
from .base import ETraceAlgorithm, EligibilityTrace
|
|
28
28
|
from .d_rtrl import D_RTRL
|
|
29
29
|
from .e_prop import EProp
|
|
30
30
|
from .graph_executor import ETraceGraphExecutor
|
|
31
31
|
from .ostl import OSTLFeedforward, OSTLRecurrent
|
|
32
|
-
from .osttp import OSTTP
|
|
33
|
-
from .otpe import OTPE
|
|
34
|
-
from .ottt import OTTT
|
|
35
32
|
from .io_dim_vjp import IODimVjpAlgorithm
|
|
36
33
|
from .param_dim_vjp import ParamDimVjpAlgorithm
|
|
34
|
+
from .random_projection_vjp import RandomProjectionVjpAlgorithm
|
|
37
35
|
from .pp_prop import ES_D_RTRL, pp_prop # ES_D_RTRL: back-compat alias
|
|
36
|
+
from .sequence import ETraceVmap, SequenceDriverMixin
|
|
37
|
+
from .snap_n import SnAp
|
|
38
|
+
from .dni import DNI, SyntheticGradient, train_synthetic_gradient
|
|
39
|
+
from .three_factor import ThreeFactor
|
|
40
|
+
from .uoro import UORO
|
|
38
41
|
from .vjp_base import ETraceVjpAlgorithm
|
|
39
42
|
from .vjp_graph_executor import ETraceVjpGraphExecutor
|
|
40
43
|
|
|
41
44
|
__all__ = [
|
|
45
|
+
# axes
|
|
46
|
+
'ETraceConfig',
|
|
42
47
|
# core
|
|
43
48
|
'ETraceAlgorithm',
|
|
44
49
|
'EligibilityTrace',
|
|
45
50
|
'ETraceGraphExecutor',
|
|
51
|
+
# sequence drivers
|
|
52
|
+
'ETraceVmap',
|
|
53
|
+
'SequenceDriverMixin',
|
|
46
54
|
# VJP
|
|
47
55
|
'ETraceVjpAlgorithm',
|
|
48
56
|
'ETraceVjpGraphExecutor',
|
|
@@ -51,14 +59,17 @@ __all__ = [
|
|
|
51
59
|
'pp_prop',
|
|
52
60
|
'ES_D_RTRL',
|
|
53
61
|
'IODimVjpAlgorithm',
|
|
62
|
+
'SnAp',
|
|
63
|
+
'RandomProjectionVjpAlgorithm',
|
|
64
|
+
'UORO',
|
|
65
|
+
'ThreeFactor',
|
|
66
|
+
'DNI',
|
|
67
|
+
'SyntheticGradient',
|
|
68
|
+
'train_synthetic_gradient',
|
|
54
69
|
# SNN
|
|
55
70
|
'EProp',
|
|
56
71
|
'OSTLRecurrent',
|
|
57
72
|
'OSTLFeedforward',
|
|
58
|
-
'OTPE',
|
|
59
|
-
'OTTT',
|
|
60
|
-
'OSTTP',
|
|
61
73
|
'FixedRandomFeedback',
|
|
62
74
|
'KappaFilter',
|
|
63
|
-
'PresynapticTrace',
|
|
64
75
|
]
|