Skip to main content

PyANN

Python wrapper for the libann neural network library with a Keras-like API.

Features

  • Keras-style API: Familiar Sequential model with add(), fit(), predict()
  • Multiple optimizers: SGD, Momentum, RMSProp, AdaGrad, Adam
  • Activation functions: Sigmoid, ReLU, LeakyReLU, Tanh, Softsign, Softmax
  • Loss functions: MSE, Categorical Cross-Entropy
  • Learning rate schedulers: Step decay, Exponential decay, Cosine annealing
  • Hyperparameter tuning: Grid search, Random search, Bayesian optimization, TPE
  • NumPy optional: Works with Python lists, optimized for NumPy arrays
  • Model persistence: Save/load in text or binary format, ONNX export/import
  • Network visualization: Export architecture as PIKCHR diagrams (renders to SVG)
  • Regularization: L1 and L2 (weight decay) regularization, dropout
  • Evaluation: Accuracy scoring, confusion matrix with MCC
  • Data utilities: CSV loading, normalization, one-hot encoding, train/val splitting
  • Hardware acceleration: BLAS-accelerated CPU everywhere (Accelerate on macOS, OpenBLAS on Linux and Windows), plus optional GPU inference and training via Metal (macOS) or CUDA

Installation

pip install pylibann

The PyPI package is called pylibann, but you import it as pyann. (The unrelated pyann project on PyPI is a different package with the same module name, so don't install both in one environment.)

Pre-built wheels include the native library, so no compiler is needed:

Platform BLAS GPU
macOS (Apple silicon, 12+) Accelerate Metal
Linux x86_64 and aarch64 (glibc, manylinux2014+) OpenBLAS -
Windows x86_64 OpenBLAS -

On other platforms pip builds from source, which needs CMake and a C compiler (see below). NumPy is optional: pip install "pylibann[numpy]".

Building from source

git clone --recurse-submodules https://github.com/mseminatore/pyann.git
cd pyann
pip install -e ".[dev]"      # builds the native library with CMake
pytest

The build picks the same acceleration as the wheels. On Linux and Windows it downloads the prebuilt OpenBLAS from the scipy-openblas32 package. Choose other options by passing CMake flags through CMAKE_ARGS:

CMAKE_ARGS="-DUSE_CUDA=ON" pip install -e .                                 # NVIDIA CUDA (Linux/Windows)
CMAKE_ARGS="-DUSE_CBLAS=ON" pip install -e .                                # CBLAS from /opt/cblas
CMAKE_ARGS="-DUSE_BLAS=ON" pip install -e .                                 # system OpenBLAS from /opt/OpenBLAS
CMAKE_ARGS="-DUSE_METAL=OFF -DUSE_ACCELERATE=OFF" pip install -e .          # plain CPU build
CMake option Meaning
USE_ACCELERATE Apple Accelerate (macOS; default there)
USE_METAL Apple Metal GPU backend (macOS; default there)
USE_SCIPY_OPENBLAS OpenBLAS from scipy-openblas32 (Linux/Windows; default there)
USE_BLAS OpenBLAS installed at /opt/OpenBLAS
USE_CBLAS CBLAS installed at /opt/cblas
USE_CUDA NVIDIA CUDA GPU backend

python build_lib.py [--accelerate | --scipy-openblas | --cblas | --blas] [--metal] [--cuda] [--clean] builds just the shared library into src/pyann/lib/ without installing, which is handy when working on the C side. Set PYANN_LIB_PATH to load a library from another location.

Check what a given install was built with:

import pyann
pyann.backend_info()   # {'blas': 'accelerate', 'gpu': 'metal', 'gpu_active': None, ...}

Quick Start

from pyann import Sequential, Dense, Adam, Loss

# Create model
model = Sequential(optimizer=Adam(lr=0.001), loss=Loss.MSE)
model.add(Dense(128, activation='relu', input_shape=(784,)))
model.add(Dense(64, activation='relu'))
model.add(Dense(10, activation='softmax'))

# Train
model.fit(X_train, y_train, epochs=10, batch_size=32)

# Predict
predictions = model.predict(X_test)

# Evaluate
accuracy = model.evaluate(X_test, y_test)
print(f"Accuracy: {accuracy:.2%}")

Examples

XOR Problem

from pyann import Sequential, Dense

# XOR data
X = [[0, 0], [0, 1], [1, 0], [1, 1]]
y = [[0], [1], [1], [0]]

model = Sequential()
model.add(Dense(4, activation='relu', input_shape=(2,)))
model.add(Dense(1, activation='sigmoid'))

model.fit(X, y, epochs=1000, batch_size=4)
print(model.predict(X))

With NumPy

import numpy as np
from pyann import Sequential, Dense

X = np.random.randn(1000, 20).astype(np.float32)
y = (X.sum(axis=1) > 0).astype(np.float32).reshape(-1, 1)

model = Sequential()
model.add(Dense(32, activation='relu', input_shape=(20,)))
model.add(Dense(16, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

model.fit(X, y, epochs=50)

Learning Rate Scheduling

from pyann import Sequential, Dense
from pyann.callbacks import CosineAnnealing

model = Sequential()
model.add(Dense(64, activation='relu', input_shape=(10,)))
model.add(Dense(1, activation='sigmoid'))

scheduler = CosineAnnealing(T_max=100, min_lr=0.0001)
model.fit(X, y, epochs=100, lr_scheduler=scheduler)

Early Stopping

from pyann.callbacks import EarlyStopping

stopping = EarlyStopping(patience=10, min_delta=0.0001)
model.fit(X, y, epochs=500, callbacks=[stopping])

Hyperparameter Tuning

from pyann.hypertune import RandomSearch, HyperparamSpace
from pyann.utils import split_data

# Split data
X_train, y_train, X_val, y_val = split_data(X, y, train_ratio=0.8)

# Define search space
space = HyperparamSpace(
    learning_rate=(0.0001, 0.01),
    batch_sizes=[32, 64, 128],
    hidden_layers=(1, 3),
    layer_sizes=[64, 128, 256],
)

# Run search
search = RandomSearch(space, n_trials=20)
best, results = search.run(
    X_train, y_train, X_val, y_val,
    input_size=784, output_size=10
)

# Create best model
model = search.create_model(best, input_size=784, output_size=10)
from pyann.hypertune import TPESearch, HyperparamSpace

space = HyperparamSpace(
    learning_rate=(0.0001, 0.01),
    batch_sizes=[32, 64, 128],
    hidden_layers=(1, 3),
    layer_sizes=[64, 128, 256],
)

# TPE uses KDE to model good vs bad configs
search = TPESearch(space, n_trials=50, n_startup=10, gamma=0.25)
best, results = search.run(
    X_train, y_train, X_val, y_val,
    input_size=784, output_size=10
)

Save and Load

# Save
model.save('model.nna')  # Text format
model.save('model.nnb', format='binary')  # Binary format
model.export_onnx('model.onnx.json')  # ONNX format

# Load
loaded = Sequential.load('model.nna')
loaded = Sequential.load_onnx('model.onnx.json')  # From ONNX

Network Visualization

# Export architecture as PIKCHR diagram
model.export_pikchr('network.pikchr')

# Then render to SVG with the pikchr CLI tool:
# pikchr network.pikchr > network.svg

Small networks (≤10 nodes per layer) get a detailed diagram with individual nodes and connections. Larger networks get a simplified box diagram.

Data Utilities

from pyann.utils import load_csv, split_data
from pyann.utils.data import normalize, one_hot_encode

# Load CSV data
data, rows, cols = load_csv('data.csv', has_header=True)

# Normalize features
X_norm, mean, std = normalize(X)

# One-hot encode labels
y_encoded = one_hot_encode(labels, num_classes=10)

# Split into train/validation sets
X_train, y_train, X_val, y_val = split_data(X, y, train_ratio=0.8)

API Reference

Sequential

Sequential(layers=None, optimizer=None, loss=Loss.MSE, name=None)

Methods:

  • add(layer) - Add a layer
  • compile(optimizer, loss, learning_rate, weight_decay, l1_regularization) - Configure training
  • fit(x, y, epochs, batch_size, ...) - Train the model
  • predict(x) - Generate predictions
  • evaluate(x, y) - Compute accuracy
  • confusion_matrix(x, y) - Compute TP/FP/TN/FN and MCC (binary classification)
  • save(filepath, format) - Save model
  • load(filepath, format) - Load model (classmethod)
  • export_onnx(filepath) - Export to ONNX JSON format
  • load_onnx(filepath) - Load from ONNX JSON (classmethod)
  • export_pikchr(filepath) - Export architecture as PIKCHR diagram
  • export_learning_curve(filepath) - Export training history as CSV
  • clear_history() - Clear training history to free memory
  • set_weight_decay(lambda_) - Set L2 regularization coefficient
  • set_l1_regularization(lambda_) - Set L1 regularization coefficient
  • summary() - Get model summary

Backend

pyann.backend_info()   # dict: blas, gpu (compiled in), gpu_active, plus CBLAS details when present
pyann.enable_gpu()     # initialize the GPU backend; returns True if one is active
pyann.gpu_enabled()    # whether a GPU backend is active

Layers

Dense(units, activation=None, input_shape=None, dropout=0.0)
Input(shape)

Optimizers

SGD(lr=0.05)
Momentum(lr=0.01)
RMSProp(lr=0.001)
AdaGrad(lr=0.01)
Adam(lr=0.001)  # Recommended

Loss Functions

Loss.MSE                        # Mean Squared Error
Loss.CATEGORICAL_CROSS_ENTROPY  # For classification

CATEGORICAL_CROSS_ENTROPY needs a softmax output layer (one class per sample) or a sigmoid output layer (binary cross-entropy per output). Training with any other output activation fails.

Activations

Activation.NONE      # Linear
Activation.SIGMOID
Activation.RELU
Activation.LEAKY_RELU
Activation.TANH
Activation.SOFTSIGN
Activation.SOFTMAX

Callbacks

StepDecay(step_size, gamma=0.5)          # Multiply LR by gamma every step_size epochs
ExponentialDecay(gamma=0.95)             # Multiply LR by gamma each epoch
CosineAnnealing(T_max, min_lr=0.0001)   # Smooth decay to min_lr over T_max epochs
EarlyStopping(patience=10, min_delta=0.0001)  # Stop when loss stops improving

Hyperparameter Tuning

GridSearch(space, lr_steps=3)                          # Exhaustive grid search
RandomSearch(space, n_trials=50)                       # Random sampling
BayesianSearch(space, n_trials=50, n_initial=10)       # Bayesian optimization
TPESearch(space, n_trials=50, n_startup=10, gamma=0.25)  # Tree-structured Parzen Estimator

All accept a HyperparamSpace and return (best_result, all_results) from run().

Hardware Acceleration

The CPU path uses the BLAS the library was built with (see backend_info()["blas"]). GPU use is opt-in:

import pyann

if pyann.enable_gpu():          # True when a GPU backend is compiled in and a device is available
    print("Using", pyann.backend_info()["gpu_active"])   # 'metal' or 'cuda'

model.fit(X, y, epochs=10)      # trains on the GPU when enabled
model.predict(X)                # batch inference on the GPU when enabled

If no GPU backend is built in, or no device is found, enable_gpu() returns False and everything keeps running on the CPU with BLAS, so the same code works everywhere.

Notes:

  • enable_gpu() applies to the whole process and cannot be undone.
  • GPU speedups depend on problem size. In an informal test on Apple silicon (batch size 128) Metal sped up batch inference but was several times slower than the CPU for training, which is why it is not enabled automatically. Measure your own workload.
  • The macOS wheels include Metal. CUDA is only available when building from source with USE_CUDA=ON, and has had little testing.
  • predict() runs the whole input as one batch call.

License

MIT License - see LICENSE for details.

The Linux and Windows wheels also bundle OpenBLAS, LAPACK and the GCC runtime libraries (libgfortran, libquadmath) under their own licenses, included in the wheel as pyann/lib/LICENSE-scipy-openblas32.txt.

Metadata

Release files for pylibann 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pylibann 0.1.0
File Size Uploaded Provenance
pylibann-0.1.0.tar.gz 167.0 kB With provenance Details

Built distributions (wheels)

Table of built distributions (wheels) for pylibann 0.1.0
File
pylibann-0.1.0-py3-none-win_amd64.whl Python 3 none Windows x86-64 Details
pylibann-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details
pylibann-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl Python 3 none Linux glibc 2.17+ ARM64 Details
pylibann-0.1.0-py3-none-macosx_12_0_arm64.whl Python 3 none macOS 12.0+ ARM64 Details

Total release size: 25.4 MB

Release files / pylibann-0.1.0.tar.gz

Download URL pylibann-0.1.0.tar.gz
Size 167.0 kB
Tags Source
SHA-256 checksum
How to use checksums
a0bdb90578228cc23b7c8b90e8d5efaa32c99afea533e04917f006adfd1d03a2
BLAKE2b-256 checksum
How to use checksums
c9b2c2628a4e93e38b19739db8af17cc26fbf1c57f9dce458194035aa0b23709
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / pylibann-0.1.0-py3-none-win_amd64.whl

Download URL pylibann-0.1.0-py3-none-win_amd64.whl
Size 6.8 MB
Tags Python 3 Windows x86-64
SHA-256 checksum
How to use checksums
b849bb3d9801c801a7412835045108175ea0125a3431ef645091236d9b18f8e6
BLAKE2b-256 checksum
How to use checksums
16a3d6fd543f9afe8379fbc6cc878490afa4d0492ae0dfd94d55201133c0bf88
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / pylibann-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL pylibann-0.1.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 8.8 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
cff3bf9726804af6dcd77e6be5cf663933910815f4ab3d060ce6ad777740cedc
BLAKE2b-256 checksum
How to use checksums
610c543c5cafd5d40687b7d28d7a82a8166cea7ea977be190db0a17f642c4d9e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / pylibann-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL pylibann-0.1.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 9.5 MB
Tags Linux glibc 2.17+ ARM64 Python 3
SHA-256 checksum
How to use checksums
1651425fbefa4dbfaaaa85cbf85fb494b6d262ad073f4c2e634edc74e3fce8e0
BLAKE2b-256 checksum
How to use checksums
ad2d8d2779f7361971d2d20ec5857cc2086ed8e22c070f37d0c631ca45f6d27c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Release files / pylibann-0.1.0-py3-none-macosx_12_0_arm64.whl

Download URL pylibann-0.1.0-py3-none-macosx_12_0_arm64.whl
Size 106.0 kB
Tags Python 3 macOS 12.0+ ARM64
SHA-256 checksum
How to use checksums
c04783a35e4d890980075ff4f9bea202895c09095c40b84cf44579cec4d2118a
BLAKE2b-256 checksum
How to use checksums
1a45869ae08d29b3865a0e8805c2334537a5c2a9ecb69be459fa53dababfed44
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

Security for pylibann 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 5 files in this release have been uploaded with provenance metadata.

Select from 5 files

Attestation for pylibann-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 19, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page