diff --git a/README.md b/README.md index a164fff3..9650623f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ -ngc-learn is a Python library for building, simulating, and analyzing biophysical / neurobiological systems, spiking neuronal networks, predictive coding circuitry, and biomimetic (NeuroAI) agents that learn in a biologically-plausible manner. This simulation toolkit, meant to support computational neuroscience and brain-inspired computing research, is built on top of JAX and is distributed under the 3-Clause BSD license. +ngc-learn is a Python library for building, simulating, and analyzing biophysical / neurobiological systems, spiking neural networks, predictive coding circuitry, and biomimetic (NeuroAI) agents that learn in a biologically-plausible manner. This simulation toolkit, meant to support computational neuroscience and brain-inspired computing research, is built on top of JAX and is distributed under the 3-Clause BSD license. It is currently maintained by the Neural Adaptive Computing (NAC) laboratory. @@ -15,15 +15,12 @@ which implements several historical models, can be found here. The official blog-post related to the source paper behind this software library -can be found +can be found here.
You can find the related paper right here, which was selected to appear in the Nature Neuromorphic Hardware and Computing Collection in 2023 and was chosen as one of the Editors' Highlights for Applied Physics and Mathematics in 2022. - - ## Installation ### Dependencies @@ -42,7 +39,7 @@ ngc-learn requires: --> --- -ngc-learn 3.0.0 and later require Python 3.10 or newer as well as ngcsimlib >=3.0.0. +ngc-learn 3.1.0 and later require Python 3.10 or newer as well as ngcsimlib >=3.0.0. ngc-learn's plotting capabilities (routines within `ngclearn.utils.viz`) require Matplotlib (>=3.8.0) and imageio (>=2.31.5) and both plotting and density estimation tools (routines within ``ngclearn.utils.density``) will require Scikit-learn (>=0.24.2). @@ -75,7 +72,7 @@ Python 3.11.4 (main, MONTH DAY YEAR, TIME) [GCC XX.X.X] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import ngclearn >>> ngclearn.__version__ -'3.0.0' +'3.1.0' ``` Note: For access to the previous Tensorflow-2 version of ngc-learn (of @@ -122,7 +119,7 @@ $ python install -e . **Version:**
-3.0.1 +3.1.0 Author: Alexander G. Ororbia II
diff --git a/docs/source/ngclearn.components.synapses.hebbian.rst b/docs/source/ngclearn.components.synapses.hebbian.rst index 778e59ec..ef76ced8 100644 --- a/docs/source/ngclearn.components.synapses.hebbian.rst +++ b/docs/source/ngclearn.components.synapses.hebbian.rst @@ -12,6 +12,14 @@ ngclearn.components.synapses.hebbian.BCMSynapse module :undoc-members: :show-inheritance: +ngclearn.components.synapses.hebbian.STDPSynapse module +------------------------------------------------------- + +.. automodule:: ngclearn.components.synapses.hebbian.STDPSynapse + :members: + :undoc-members: + :show-inheritance: + ngclearn.components.synapses.hebbian.eventSTDPSynapse module ------------------------------------------------------------ diff --git a/history.txt b/history.txt index e03221af..4345a232 100644 --- a/history.txt +++ b/history.txt @@ -92,3 +92,11 @@ History * integration/addition of RL-SNN model in model-museum * integration of full dynamics synapses -- alpha, exponential, and double-exponential synaptic cables * new metrics/clean-up of metrics in utils.metric_utils (e.g., KL divs, etc.) + + 3.1.0 + — — — — — — — — - + * important patch made to ensure MethodProcess auto-jits (by default) - recovers ngc-learn's jax-driven speed + * new suite of competitive learning synapses (generalized formats), including vector-quantization, self-organizing map, adaptive resonance theory (contus-version), and modern hopfield network + * revisions to metric and model utils + * some additional clean-up, including supported retinal ganglion encoder + diff --git a/ngclearn/__init__.py b/ngclearn/__init__.py index 210f5121..6121286c 100644 --- a/ngclearn/__init__.py +++ b/ngclearn/__init__.py @@ -1,8 +1,15 @@ import sys -import pkg_resources -from pkg_resources import get_distribution - -__version__ = get_distribution('ngclearn').version +if sys.version_info >= (3, 8): ## for new versions of python/ngc-learn + from importlib.metadata import version, distributions, PackageNotFoundError +else: ## for older versions of python before 3.8 + from importlib_metadata import version, distributions, PackageNotFoundError +#import pkg_resources +#from pkg_resources import get_distribution +#__version__ = get_distribution('ngclearn').version + +## Following obtains ngc-learn's version +from importlib.metadata import version +__version__ = version("ngclearn") if sys.version_info.minor < 10: import warnings @@ -10,9 +17,12 @@ "Running ngclearn and jax in a python version prior to 3.10 may have unintended consequences. Compatibility " "with python 3.8 is maintained to allow for lava-nc components and should only be used with those") +## Following obtains installed package names (as normalized keys) for ngc-learn #required = {'ngcsimlib', 'jax', 'jaxlib'} ## list of core ngclearn dependencies required = {'ngcsimlib'} #, 'jax', 'jaxlib'} -installed = {pkg.key for pkg in pkg_resources.working_set} +#installed = {pkg.key for pkg in pkg_resources.working_set} +#missing = required - installed +installed = {dist.metadata['Name'].lower().replace('-', '_') for dist in distributions()} missing = required - installed for key in required: @@ -20,7 +30,7 @@ raise ImportError(str(key) + ", a core dependency of ngclearn, is not " \ "currently installed!") - +################################################################################## ## Needed to preload is called before anything in ngclearn from pathlib import Path from sys import argv @@ -36,7 +46,7 @@ from ngcsimlib.parser import compilable from ngcsimlib.operations import Summation, Product - +## this prevents ngc-learn from messing with sphinx/building if not Path(argv[0]).name == "sphinx-build" or Path(argv[0]).name == "build.py": if "readthedocs" not in argv[0]: ## prevent readthedocs execution of preload from ngcsimlib import configure diff --git a/ngclearn/components/synapses/hebbian/STDPSynapse.py b/ngclearn/components/synapses/hebbian/STDPSynapse.py index cd97388e..b16df8db 100755 --- a/ngclearn/components/synapses/hebbian/STDPSynapse.py +++ b/ngclearn/components/synapses/hebbian/STDPSynapse.py @@ -1,5 +1,6 @@ from jax import random, numpy as jnp, jit -from ngclearn import resolver, Component, Compartment +from ngclearn import compilable #from ngcsimlib.parser import compilable +from ngclearn import Compartment #from ngcsimlib.compartment import Compartment from ngclearn.components.synapses import DenseSynapse from ngclearn.utils import tensorstats @@ -112,43 +113,48 @@ def _compute_update(Aplus, Aminus, tau_plus, tau_minus, preSpike, postSpike, dW = (dWpost + dWpre) return dW - @staticmethod - def _evolve(dt, w_bound, w_decay, tau_w, Aplus, Aminus, tau_plus, tau_minus, preSpike, - postSpike, pre_tols, post_tols, weights, eta): + @compilable + def evolve(self, t, dt): + weights = self.weights.get() + preSpike = self.preSpike.get() + postSpike = self.postSpike.get() + pre_tols = self.pre_tols.get() + post_tols = self.post_tols.get() dWeights = STDPSynapse._compute_update( - Aplus, Aminus, tau_plus, tau_minus, preSpike, postSpike, pre_tols, - post_tols, weights + self.Aplus, + self.Aminus, + self.tau_plus, + self.tau_minus, + preSpike, + postSpike, + pre_tols, + post_tols, + weights ) ## shift/alter values of synaptic efficacies - if tau_w > 0.: ## triggers Euler-style synaptic update - weights = weights + (-weights * dt/tau_w + dWeights * eta) - else: ## raw simple ascent-style update - weights = weights + dWeights * eta - weights * w_decay + if self.tau_w > 0.: ## triggers Euler-style synaptic update + weights = weights + (-weights * dt / self.tau_w + dWeights * self.eta) + else: ## raw simple ascent-style update + weights = weights + dWeights * self.eta - weights * self.w_decay ## enforce non-negativity - eps = 0.001 # 0.01 - weights = jnp.clip(weights, eps, w_bound - eps) # jnp.abs(w_bound)) - return weights, dWeights + eps = 0.001 # 0.01 + weights = jnp.clip(weights, eps, self.w_bound - eps) # jnp.abs(w_bound)) - @resolver(_evolve) - def evolve(self, weights, dWeights): self.weights.set(weights) self.dWeights.set(dWeights) - @staticmethod - def _reset(batch_size, shape): - preVals = jnp.zeros((batch_size, shape[0])) - postVals = jnp.zeros((batch_size, shape[1])) + @compilable + def reset(self): + preVals = jnp.zeros((self.batch_size, self.shape[0])) + postVals = jnp.zeros((self.batch_size, self.shape[1])) inputs = preVals outputs = postVals preSpike = preVals postSpike = postVals pre_tols = preVals post_tols = postVals - dWeights = jnp.zeros(shape) - return inputs, outputs, preSpike, postSpike, pre_tols, post_tols, dWeights + dWeights = jnp.zeros(self.shape) - @resolver(_reset) - def reset(self, inputs, outputs, preSpike, postSpike, pre_tols, post_tols, dWeights): self.inputs.set(inputs) self.outputs.set(outputs) self.preSpike.set(preSpike) diff --git a/pyproject.toml b/pyproject.toml index 057a86f5..bd1c7194 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,7 +8,7 @@ build-backend = "setuptools.build_meta" # using setuptool building engine [project] name = "ngclearn" -version = "3.0.1" +version = "3.1.0" description = "Simulation software for building and analyzing computational neuroscience models, brain-inspired computing systems, and NeuroAI agents." authors = [ {name = "Alexander Ororbia", email = "ago@cs.rit.edu"},