The Problem

Training continuous‑time recurrent networks that respect biologically‑inspired sparsity is cumbersome. Existing deep‑learning libraries provide LSTM/GRU primitives but lack ready‑made wiring diagrams and specialized cells (LTC, CfC) needed for Neural Circuit Policies (NCPs). Teams building control or time‑series models must either re‑implement these cells or stitch together ad‑hoc solutions.

What This Does

ncps ships a reference implementation of three NCP‑related cells—LTC, CfC, and wired‑CFC—for PyTorch, TensorFlow/Keras, and Paddle. The core modules live under ncps/torch/, ncps/tf/, and ncps/keras/ (e.g., ncps/torch/cfc.py, ncps/tf/ltc.py).

Wiring diagrams are generated by the AutoNCP class in ncps/wirings/wirings.py, which maps a user‑specified neuron count to a sparse connectivity matrix. Example scripts (examples/ataritorch.py, examples/torchcfcsinusoidal.py) demonstrate end‑to‑end training on Atari and synthetic tasks, while the docs/ folder contains full API reference (docs/api/torch.rst, docs/api/tensorflow.rst) and tutorial pages.

How To Use It

Setup

Install the library from PyPI (includes required runtime deps) pip install ncps

Or install from source to work on the examples/docs git clone https://github.com/mlech26l/ncps.git cd ncps pip install -r requirements.txt # pulls torch, tensorflow, keras, etc.

The repository does not ship a lockfile; reproducibility depends on the versions pinned in requirements.txt.

Configuration

No external configuration files are required for basic usage. All hyper‑parameters are passed to model constructors (e.g., hidden size, wiring object). Optional environment variables for CUDA (CUDAVISIBLEDEVICES) follow the usual PyTorch/TensorFlow conventions.

Running an Example

PyTorch Atari behavior cloning (see examples/ataritorch.py) python examples/ataritorch.py --env BreakoutNoFrameskip-v4 --epochs 10

The script imports ncps.torch.CfC and ncps.wirings.AutoNCP, builds the model, and trains using standard PyTorch utilities. Equivalent TensorFlow examples exist in examples/ataritf.py.

Library Usage (inline)

from ncps.torch import CfC from ncps.wirings import AutoNCP

wiring = AutoNCP(numneurons=28, numoutputs=4) rnn = CfC(inputsize=20, wiring=wiring) # sparse NCP‑wired CfC output, hidden = rnn(x, h0)

All models accept either a plain integer (fully‑connected) or a wiring object, as documented in docs/quickstart.rst.

Real‑World Use

A robotics team can embed an NCP controller in a ROS node by importing ncps.torch.CfC and feeding sensor streams as batched tensors. The sparse wiring reduces parameter count, which translates to lower memory footprint on edge hardware. A typical workflow:

rosnode.py import torch, rospy from sensormsgs.msg import LaserScan from ncps.torch import LTC from ncps.wirings import AutoNCP

wiring = AutoNCP(64, 2) # 64 neurons, 2 motor outputs policy = LTC(inputsize=360, wiring=wiring).eval() policy.loadstatedict(torch.load('policy.pt'))

def callback(msg): x = torch.fromnumpy(np.array(msg.ranges)).float().unsqueeze(0).unsqueeze(0) , cmd = policy(x, torch.zeros(1, 2)) publishmotorcommands(cmd.squeeze().tolist())

rospy.Subscriber('/scan', LaserScan, callback) rospy.spin()

Code Health & Issues

Low – missing lockfile – requirements.txt lists unpinned versions; builds may diverge across environments. Low – limited test coverage – only 4 test files (ncps/tests/) covering Keras, TF, and Torch; many edge cases (e.g., Paddle backend) lack tests. Low – no type hints – source files omit static typing, which hampers IDE support and automated analysis. Low – documentation‑code drift risk – API docs are generated from .rst files; any undocumented change in ncps/torch/ or ncps/tf/ may go unnoticed. Info – CI present – GitHub Actions workflow (.github/workflows/python-test.yml) runs the test suite on each PR, confirming basic sanity. Info – license included – LICENSE file present (MIT‑style).

No secret keys, no hard‑coded paths, and the package follows a clear module layout, which eases onboarding.

The Bottom Line

ncps delivers a functional, well‑documented reference implementation of NCP, LTC, and CfC cells across major DL frameworks, suitable for researchers and engineers needing sparse continuous‑time RNNs. The main drawbacks are the lack of a dependency lockfile and modest test depth; teams should pin versions locally and add targeted tests for critical paths. If your workload benefits from biologically‑inspired sparse recurrent architectures, this library offers a ready‑to‑use, extensible foundation.