Skip to main content

JAX-based simulations of Boltzmann machines.

Project description

jaxbm

CI PyPI License: MIT

JAX-based simulations of Boltzmann machines.

jaxbm aims to provide simple, composable, jit- and vmap-friendly building blocks for simulating and training Boltzmann machines on top of JAX.

Installation

pip install jaxbm

Or from a clone of this repository:

pip install .

Quick start

jaxbm exposes two functions: BM_chain for a fully-connected Boltzmann machine, and RBM_chain for a restricted one (separate visible/hidden units, block-Gibbs sampling). Both take a PRNG key, an initial state, the model's weights/bias arrays, and n_samples (required, no default -- None means "just advance the chain and return the final state", otherwise a positive number of samples to draw). steps (the number of chain-update steps between returned states) defaults to 1.

import jax
import jax.numpy as jnp
from jaxbm import BM_chain, RBM_chain

key = jax.random.PRNGKey(0)

# --- Fully-connected Boltzmann machine ---
n = 4
weights = jnp.zeros((n, n))   # symmetric (n, n) coupling matrix, zero diagonal
bias = jnp.zeros(n)           # bias vector, or None for no bias
x0 = jnp.ones(n)              # initial state, {-1, +1}-valued (spin=True, the default)

final_x, samples = BM_chain(key, x0, weights, bias, n_samples=100)
# final_x.shape == (4,), samples.shape == (100, 4)

# --- Restricted Boltzmann machine (visible/hidden layers) ---
n_v, n_h = 4, 3
weights_rbm = jnp.zeros((n_v, n_h))   # visible-hidden coupling matrix
bias_v, bias_h = jnp.zeros(n_v), jnp.zeros(n_h)
x_v0, x_h0 = jnp.ones(n_v), jnp.ones(n_h)

(final_v, final_h), (samples_v, samples_h) = RBM_chain(
    key, x_v0, x_h0, weights_rbm, bias_v, bias_h, n_samples=100
)
# (final_v, final_h) is the last state; samples_v.shape == (100, 4), samples_h.shape == (100, 3)

See BM_chain / RBM_chain's docstrings (jaxbm/sample.py) for the full set of behaviors, including validation rules, spin, and clamp.

More guides

Sampling modes

The mode selects how the n_samples visited states are summarized. mode defaults to "HIST", so you can leave it out to just collect the trajectory:

# mode defaults to "HIST": stack every sampled state -- shape (n_samples, n)
x, samples = BM_chain(key, x0, weights, bias, n_samples=100)

# mode="MEAN": running elementwise mean of the sampled states -- shape (n,)
x, x_mean = BM_chain(key, x0, weights, bias, n_samples=100, mode="MEAN")

# mode="CORR": running mean of outer(x, x) -- shape (n, n)
x, corr_mean = BM_chain(key, x0, weights, bias, n_samples=100, mode="CORR")

# n_samples=None (mode must also be None): advance 100 steps, no
# accumulation -- just the final state, returned bare (not a tuple)
x = BM_chain(key, x0, weights, bias, n_samples=None, steps=100)

None of the three modes above ever include the input state you passed in -- samples / x_mean / corr_mean only summarize the n_samples new states produced by sampling.

RBM_chain supports the same modes, applied to the (x_v, x_h) pair (mode="CORR" gives the mean of outer(x_v, x_h), shape (n_v, n_h)). Check the documentation for more details.

jit

n_samples, steps, mode, spin, and in_jit all control Python-level branching inside BM_chain / RBM_chain, so they must be passed as static arguments under jax.jit. Eager input validation also isn't traceable, so pass in_jit=True to skip it and make the whole call traceable.

jitted_bm_chain = jax.jit(
    BM_chain, static_argnames=("n_samples", "steps", "mode", "spin", "in_jit")
)
final_x, samples = jitted_bm_chain(
    key, x0, weights, bias, n_samples=100, mode="HIST", in_jit=True
)

The same applies to RBM_chain.

vmap

BM_chain / RBM_chain are vmap-able too. Run many independent chains from the same model in parallel, batch over key (and optionally x0, or even weights/bias for an ensemble of different models). A bare jax.vmap(...) doesn't need in_jit=True:

keys = jax.random.split(key, 8)  # 8 independent chains

run_many = jax.vmap(
    lambda k: BM_chain(k, x0, weights, bias, n_samples=100, mode="HIST")
)
final_xs, all_samples = run_many(keys)
# final_xs.shape == (8, 4), all_samples.shape == (8, 100, 4)

in_jit=True is needed as soon as jit enters the picture, though -- whether directly or wrapping a vmap (e.g. jax.jit(jax.vmap(...))):

run_many_jit = jax.jit(jax.vmap(
    lambda k: BM_chain(k, x0, weights, bias, n_samples=100, mode="HIST", in_jit=True)
))
final_xs, all_samples = run_many_jit(keys)
# final_xs.shape == (8, 4), all_samples.shape == (8, 100, 4)

Development

pip install -e ".[dev]"
pytest
ruff check .

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jaxbm-0.1.0.tar.gz (25.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

jaxbm-0.1.0-py3-none-any.whl (14.3 kB view details)

Uploaded Python 3

File details

Details for the file jaxbm-0.1.0.tar.gz.

File metadata

  • Download URL: jaxbm-0.1.0.tar.gz
  • Upload date:
  • Size: 25.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for jaxbm-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e2621e16647bd43bca1f10c92e7d6bc4496bca5bb16142950bb7298b26f41832
MD5 c81b76fd609f81d6f0e3f9545830a412
BLAKE2b-256 03eb9e34879dc9123f0a2685510c5e24265fc14538bdf23c9f45589a45e11edd

See more details on using hashes here.

Provenance

The following attestation bundles were made for jaxbm-0.1.0.tar.gz:

Publisher: release.yml on SwissChardLeaf/jaxbm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file jaxbm-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: jaxbm-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 14.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for jaxbm-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 115e51c24909eb8183dfc739971e0d4430f11a0692f3b8775a4989d33f2b2ddf
MD5 d47c663c3367cd4986ff28fd96ba3f7c
BLAKE2b-256 88f03d64ec7d4e6e3e4aa505e0bd61995c111279ecb1338b45d1612b0fb473e1

See more details on using hashes here.

Provenance

The following attestation bundles were made for jaxbm-0.1.0-py3-none-any.whl:

Publisher: release.yml on SwissChardLeaf/jaxbm

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page