alberta-framework 0.1.0__tar.gz → 0.1.1__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.
Files changed (59) hide show
  1. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/CLAUDE.md +45 -5
  2. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/PKG-INFO +10 -2
  3. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/README.md +9 -1
  4. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/pyproject.toml +1 -1
  5. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/__init__.py +43 -22
  6. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/core/learners.py +357 -18
  7. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/core/normalizers.py +1 -1
  8. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/core/optimizers.py +14 -12
  9. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/core/types.py +31 -0
  10. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/streams/base.py +8 -5
  11. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/streams/synthetic.py +16 -10
  12. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/utils/experiments.py +4 -3
  13. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/utils/timing.py +42 -36
  14. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/tests/test_learners.py +189 -0
  15. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/.github/workflows/ci.yml +0 -0
  16. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/.github/workflows/docs.yml +0 -0
  17. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/.github/workflows/publish.yml +0 -0
  18. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/.gitignore +0 -0
  19. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/ALBERTA_PLAN.md +0 -0
  20. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/CHANGELOG.md +0 -0
  21. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/LICENSE +0 -0
  22. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/ROADMAP.md +0 -0
  23. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/docs/contributing.md +0 -0
  24. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/docs/gen_ref_pages.py +0 -0
  25. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/docs/getting-started/installation.md +0 -0
  26. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/docs/getting-started/quickstart.md +0 -0
  27. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/docs/guide/concepts.md +0 -0
  28. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/docs/guide/experiments.md +0 -0
  29. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/docs/guide/gymnasium.md +0 -0
  30. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/docs/guide/optimizers.md +0 -0
  31. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/docs/guide/streams.md +0 -0
  32. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/docs/index.md +0 -0
  33. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/docs/javascripts/mathjax.js +0 -0
  34. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/examples/The Alberta Plan/Step1/README.md +0 -0
  35. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/examples/The Alberta Plan/Step1/autostep_comparison.py +0 -0
  36. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/examples/The Alberta Plan/Step1/external_normalization_study.py +0 -0
  37. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/examples/The Alberta Plan/Step1/idbd_lms_autostep_comparison.py +0 -0
  38. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/examples/The Alberta Plan/Step1/normalization_study.py +0 -0
  39. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/examples/The Alberta Plan/Step1/sutton1992_experiment1.py +0 -0
  40. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/examples/The Alberta Plan/Step1/sutton1992_experiment2.py +0 -0
  41. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/examples/gymnasium_reward_prediction.py +0 -0
  42. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/examples/publication_experiment.py +0 -0
  43. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/examples/td_cartpole_lms.py +0 -0
  44. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/mkdocs.yml +0 -0
  45. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/papers/mahmood-msc-thesis-summary.md +0 -0
  46. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/core/__init__.py +0 -0
  47. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/py.typed +0 -0
  48. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/streams/__init__.py +0 -0
  49. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/streams/gymnasium.py +0 -0
  50. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/utils/__init__.py +0 -0
  51. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/utils/export.py +0 -0
  52. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/utils/metrics.py +0 -0
  53. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/utils/statistics.py +0 -0
  54. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/src/alberta_framework/utils/visualization.py +0 -0
  55. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/tests/conftest.py +0 -0
  56. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/tests/test_gymnasium_streams.py +0 -0
  57. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/tests/test_normalizers.py +0 -0
  58. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/tests/test_optimizers.py +0 -0
  59. {alberta_framework-0.1.0 → alberta_framework-0.1.1}/tests/test_streams.py +0 -0
@@ -14,10 +14,10 @@ This framework implements Step 1 of the Alberta Plan: demonstrating that IDBD (I
14
14
  ```
15
15
  src/alberta_framework/
16
16
  ├── core/
17
- │ ├── types.py # TimeStep, LearnerState, LMSState, IDBDState, AutostepState, StepSizeTrackingConfig, StepSizeHistory
17
+ │ ├── types.py # TimeStep, LearnerState, LMSState, IDBDState, AutostepState, StepSizeTrackingConfig, StepSizeHistory, NormalizerTrackingConfig, NormalizerHistory
18
18
  │ ├── optimizers.py # LMS, IDBD, Autostep optimizers
19
19
  │ ├── normalizers.py # OnlineNormalizer, NormalizerState
20
- │ └── learners.py # LinearLearner, NormalizedLinearLearner, run_learning_loop, metrics_to_dicts
20
+ │ └── learners.py # LinearLearner, NormalizedLinearLearner, run_learning_loop, run_normalized_learning_loop, metrics_to_dicts
21
21
  ├── streams/
22
22
  │ ├── base.py # ScanStream protocol (pure function interface for jax.lax.scan)
23
23
  │ ├── synthetic.py # RandomWalkStream, AbruptChangeStream, CyclicStream, PeriodicChangeStream, ScaledStreamWrapper, DynamicScaleShiftStream, ScaleDriftStream
@@ -125,15 +125,15 @@ IDBD/Autostep should beat LMS when starting from the same step-size (demonstrate
125
125
  With optimal parameters, adaptive methods should match best grid-searched LMS.
126
126
 
127
127
  ### Step-Size Tracking for Meta-Adaptation Analysis
128
- The `run_learning_loop` function supports optional per-weight step-size tracking for analyzing how adaptive optimizers evolve their step-sizes during training:
128
+ The `run_learning_loop` and `run_normalized_learning_loop` functions support optional per-weight step-size tracking for analyzing how adaptive optimizers evolve their step-sizes during training:
129
129
 
130
130
  ```python
131
- from alberta_framework import LinearLearner, IDBD, StepSizeTrackingConfig, run_learning_loop
131
+ from alberta_framework import LinearLearner, IDBD, Autostep, StepSizeTrackingConfig, run_learning_loop
132
132
  from alberta_framework.streams import RandomWalkStream
133
133
  import jax.random as jr
134
134
 
135
135
  stream = RandomWalkStream(feature_dim=10)
136
- learner = LinearLearner(optimizer=IDBD())
136
+ learner = LinearLearner(optimizer=Autostep())
137
137
  config = StepSizeTrackingConfig(interval=100) # Record every 100 steps
138
138
 
139
139
  state, metrics, history = run_learning_loop(
@@ -143,6 +143,7 @@ state, metrics, history = run_learning_loop(
143
143
  # history.step_sizes: shape (100, 10) - per-weight step-sizes at each recording
144
144
  # history.bias_step_sizes: shape (100,) - bias step-size at each recording
145
145
  # history.recording_indices: shape (100,) - step indices where recordings were made
146
+ # history.normalizers: shape (100, 10) - Autostep's v_i normalizers (None for IDBD/LMS)
146
147
  ```
147
148
 
148
149
  Key features:
@@ -150,6 +151,41 @@ Key features:
150
151
  - Configurable interval to control memory usage
151
152
  - Optional `include_bias=False` to skip bias tracking
152
153
  - Works with LMS (constant), IDBD, and Autostep optimizers
154
+ - **Autostep's normalizers (v_i)** are tracked automatically when using Autostep
155
+
156
+ ### Normalizer State Tracking for Reactive Lag Analysis
157
+ The `run_normalized_learning_loop` function supports tracking the OnlineNormalizer's per-feature mean and variance estimates over time. This is essential for analyzing reactive lag — how quickly the normalizer adapts to distribution shifts:
158
+
159
+ ```python
160
+ from alberta_framework import (
161
+ NormalizedLinearLearner, IDBD,
162
+ StepSizeTrackingConfig, NormalizerTrackingConfig,
163
+ run_normalized_learning_loop
164
+ )
165
+ from alberta_framework.streams import RandomWalkStream
166
+ import jax.random as jr
167
+
168
+ stream = RandomWalkStream(feature_dim=10)
169
+ learner = NormalizedLinearLearner(optimizer=IDBD())
170
+ ss_config = StepSizeTrackingConfig(interval=100)
171
+ norm_config = NormalizerTrackingConfig(interval=100)
172
+
173
+ # Track both step-sizes and normalizer state
174
+ state, metrics, ss_history, norm_history = run_normalized_learning_loop(
175
+ learner, stream, num_steps=10000, key=jr.key(42),
176
+ step_size_tracking=ss_config, normalizer_tracking=norm_config
177
+ )
178
+
179
+ # norm_history.means: shape (100, 10) - per-feature mean estimates at each recording
180
+ # norm_history.variances: shape (100, 10) - per-feature variance estimates at each recording
181
+ # norm_history.recording_indices: shape (100,) - step indices where recordings were made
182
+ ```
183
+
184
+ Return value depends on tracking options:
185
+ - No tracking: `(state, metrics)` — 2-tuple
186
+ - step_size_tracking only: `(state, metrics, ss_history)` — 3-tuple
187
+ - normalizer_tracking only: `(state, metrics, norm_history)` — 3-tuple
188
+ - Both: `(state, metrics, ss_history, norm_history)` — 4-tuple
153
189
 
154
190
  ## Gymnasium Integration
155
191
 
@@ -267,6 +303,10 @@ The API Reference section is auto-generated from docstrings in the source code.
267
303
  ### Docstring Style
268
304
  Use NumPy-style docstrings for all public functions and classes. See `core/optimizers.py` for examples.
269
305
 
306
+ **Code examples**: Use fenced markdown code blocks (triple backticks with `python`) inside an `Examples` section, not doctest `>>>` format. This ensures proper syntax highlighting in mkdocstrings. See `streams/base.py` or `utils/timing.py` for examples.
307
+
308
+ **Math formulas**: Wrap inline math expressions in backticks for monospace rendering, e.g., `` `y = w @ x + b` `` or `` `alpha_i = exp(log_alpha_i)` ``. See `core/optimizers.py` for examples.
309
+
270
310
  ## Streams for Factorial Studies
271
311
 
272
312
  The framework supports factorial experiment designs with multiple non-stationarity types and scale ranges:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: alberta-framework
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: Implementation of the Alberta Plan for AI Research - continual learning with meta-learned step-sizes
5
5
  Project-URL: Homepage, https://github.com/j-klawson/alberta-framework
6
6
  Project-URL: Repository, https://github.com/j-klawson/alberta-framework
@@ -49,7 +49,7 @@ Description-Content-Type: text/markdown
49
49
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
50
50
  [![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/downloads/)
51
51
 
52
- A JAX-based research framework implementing components of [The Alberta Plan](https://arxiv.org/abs/2208.11173) in the pursuit of building the foundations of Continual AI.
52
+ A JAX-based research framework implementing components of [The Alberta Plan for AI Research](https://arxiv.org/abs/2208.11173) in the pursuit of building the foundations of Continual AI.
53
53
 
54
54
  > "The agents are complex only because they interact with a complex world... their initial design is as simple, general, and scalable as possible." — *Sutton et al., 2022*
55
55
 
@@ -57,6 +57,14 @@ A JAX-based research framework implementing components of [The Alberta Plan](htt
57
57
 
58
58
  The Alberta Framework provides foundational components for continual reinforcement learning research. Built on JAX for hardware acceleration, the framework emphasizes temporal uniformity every component updates at every time step, with no special training phases or batch processing.
59
59
 
60
+ ## Project Context
61
+
62
+ This framework is developed as part of my D.Eng. work focusing on the foundations of Continual AI. For more background and context see:
63
+
64
+ * **Research Blog**: [blog.9600baud.net](https://blog.9600baud.net)
65
+ * **Replicating Sutton '92**: [The Foundation of Step-size Adaptation](https://blog.9600baud.net/sutton92.html)
66
+ * **About the Author**: [Keith Lawson](https://blog.9600baud.net/about.html)
67
+
60
68
  ### Roadmap
61
69
 
62
70
  Depending on my research trajectory I may or may not implement components required for the plan. The current focus of this framework is the Step 1 Baseline Study, investigating the interaction between adaptive optimizers and online normalization.
@@ -5,7 +5,7 @@
5
5
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
6
6
  [![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/downloads/)
7
7
 
8
- A JAX-based research framework implementing components of [The Alberta Plan](https://arxiv.org/abs/2208.11173) in the pursuit of building the foundations of Continual AI.
8
+ A JAX-based research framework implementing components of [The Alberta Plan for AI Research](https://arxiv.org/abs/2208.11173) in the pursuit of building the foundations of Continual AI.
9
9
 
10
10
  > "The agents are complex only because they interact with a complex world... their initial design is as simple, general, and scalable as possible." — *Sutton et al., 2022*
11
11
 
@@ -13,6 +13,14 @@ A JAX-based research framework implementing components of [The Alberta Plan](htt
13
13
 
14
14
  The Alberta Framework provides foundational components for continual reinforcement learning research. Built on JAX for hardware acceleration, the framework emphasizes temporal uniformity every component updates at every time step, with no special training phases or batch processing.
15
15
 
16
+ ## Project Context
17
+
18
+ This framework is developed as part of my D.Eng. work focusing on the foundations of Continual AI. For more background and context see:
19
+
20
+ * **Research Blog**: [blog.9600baud.net](https://blog.9600baud.net)
21
+ * **Replicating Sutton '92**: [The Foundation of Step-size Adaptation](https://blog.9600baud.net/sutton92.html)
22
+ * **About the Author**: [Keith Lawson](https://blog.9600baud.net/about.html)
23
+
16
24
  ### Roadmap
17
25
 
18
26
  Depending on my research trajectory I may or may not implement components required for the plan. The current focus of this framework is the Step 1 Baseline Study, investigating the interaction between adaptive optimizers and online normalization.
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "alberta-framework"
7
- version = "0.1.0"
7
+ version = "0.1.1"
8
8
  description = "Implementation of the Alberta Plan for AI Research - continual learning with meta-learned step-sizes"
9
9
  readme = "README.md"
10
10
  license = "Apache-2.0"
@@ -1,25 +1,42 @@
1
- """Alberta Framework: Implementation of the Alberta Plan for AI Research.
2
-
3
- This framework implements Step 1 of the Alberta Plan: continual supervised
4
- learning with meta-learned step-sizes.
5
-
6
- Core Philosophy: Temporal uniformity - every component updates at every time step.
7
-
8
- Quick Start:
9
- >>> import jax.random as jr
10
- >>> from alberta_framework import LinearLearner, IDBD, RandomWalkStream, run_learning_loop
11
- >>>
12
- >>> # Create a non-stationary stream
13
- >>> stream = RandomWalkStream(feature_dim=10, drift_rate=0.001)
14
- >>>
15
- >>> # Create a learner with adaptive step-sizes
16
- >>> learner = LinearLearner(optimizer=IDBD())
17
- >>>
18
- >>> # Run learning loop with scan
19
- >>> key = jr.key(42)
20
- >>> state, metrics = run_learning_loop(learner, stream, num_steps=10000, key=key)
21
-
22
- Reference: The Alberta Plan for AI Research (Sutton et al.)
1
+ """Alberta Framework: A JAX-based research framework for continual AI.
2
+
3
+ The Alberta Framework provides foundational components for continual reinforcement
4
+ learning research. Built on JAX for hardware acceleration, the framework emphasizes
5
+ temporal uniformity — every component updates at every time step, with no special
6
+ training phases or batch processing.
7
+
8
+ Roadmap
9
+ -------
10
+ | Step | Focus | Status |
11
+ |------|-------|--------|
12
+ | 1 | Meta-learned step-sizes (IDBD, Autostep) | **Complete** |
13
+ | 2 | Feature generation and testing | Planned |
14
+ | 3 | GVF predictions, Horde architecture | Planned |
15
+ | 4 | Actor-critic with eligibility traces | Planned |
16
+ | 5-6 | Off-policy learning, average reward | Planned |
17
+ | 7-12 | Hierarchical, multi-agent, world models | Future |
18
+
19
+ Examples
20
+ --------
21
+ ```python
22
+ import jax.random as jr
23
+ from alberta_framework import LinearLearner, IDBD, RandomWalkStream, run_learning_loop
24
+
25
+ # Non-stationary stream where target weights drift over time
26
+ stream = RandomWalkStream(feature_dim=10, drift_rate=0.001)
27
+
28
+ # Learner with IDBD meta-learned step-sizes
29
+ learner = LinearLearner(optimizer=IDBD())
30
+
31
+ # JIT-compiled training via jax.lax.scan
32
+ state, metrics = run_learning_loop(learner, stream, num_steps=10000, key=jr.key(42))
33
+ ```
34
+
35
+ References
36
+ ----------
37
+ - The Alberta Plan for AI Research (Sutton et al., 2022): https://arxiv.org/abs/2208.11173
38
+ - Adapting Bias by Gradient Descent (Sutton, 1992)
39
+ - Tuning-free Step-size Adaptation (Mahmood et al., 2012)
23
40
  """
24
41
 
25
42
  __version__ = "0.1.0"
@@ -50,6 +67,8 @@ from alberta_framework.core.types import (
50
67
  IDBDState,
51
68
  LearnerState,
52
69
  LMSState,
70
+ NormalizerHistory,
71
+ NormalizerTrackingConfig,
53
72
  Observation,
54
73
  Prediction,
55
74
  StepSizeHistory,
@@ -122,7 +141,9 @@ __all__ = [
122
141
  "IDBDState",
123
142
  "LMSState",
124
143
  "LearnerState",
144
+ "NormalizerHistory",
125
145
  "NormalizerState",
146
+ "NormalizerTrackingConfig",
126
147
  "Observation",
127
148
  "Prediction",
128
149
  "StepSizeHistory",