Skip to main content

nn3d

Watch neural networks train in live 3D in your browser. Every layer's activation and every connection's weight stream in real time.

import nn3d

nn3d.show(model)                                       # opens browser
model.fit(X, y, callbacks=[nn3d.Monitor(X[:1])])       # training streams live

In a notebook, nothing else is needed. In a plain .py script the process exits when the script finishes — add nn3d.wait() at the end to keep the server alive.

A churn model training live

Screenshots

Every image below is a real capture of the viewer while a Keras model was actually training — note the CANLI · epoch N · adim N badge in the bottom-left corner and the metrics ticking in the top-right.

Hover a neuron — its connections light up in gold, everything else dims, and the tooltip reports the real neuron index behind the drawn subset:

Hovering a neuron highlights its connections

A CNN — Conv2D → BatchNorm → MaxPool → Conv2D → MaxPool → Flatten → Dense → Softmax on Fashion-MNIST. Each card shows the layer's tensor shape (26x26x32), and the 784 and 1600 layers are drawn as 16 representative neurons each:

Fashion-MNIST CNN training live

Drag to orbit — the scene is real 3D, so the layer planes separate in depth as you rotate:

The same CNN seen from an angle

Installation

pip install nn3d

Node.js is not required — the 3D viewer ships pre-built inside the package. Node is only needed if you want to modify the viewer itself.

What you see

  • Layer cards — name, neuron/channel count, tensor shape, activation like [ReLU]
  • Neurons — brightness and size reflect the current activation value
  • Connections — teal = positive weight, red = negative; brightness = |weight| × source activation
  • Input/output labels — feature names ("Hunger Level", "Fox Distance") color-shift with activation
  • Hover — hovering a neuron highlights all its connections in gold, dims the rest
  • Metrics — loss, accuracy, val_loss… live in the top-right corner

API

nn3d.show(model, ...)

Builds the graph and opens a browser tab. Returns a View.

parameter description
sample if provided, sends the first frame immediately so the screen isn't blank
input_labels names for the input neurons (your feature column names)
output_labels names for the output neurons (your class names)
max_neurons points drawn per layer (default 16)
port default 8092; falls back to a free port automatically
open_browser set False to print the URL without opening a tab

nn3d.Monitor(sample, every=20, ...)

A Keras callback. Drop it into model.fit(callbacks=[...]).

every sends a frame every N batches. Running an extra forward pass every single batch adds measurable overhead; every 20 looks smooth and costs almost nothing.

View.update(x, metrics=..., epoch=...)

For custom training loops (RL, manual gradient steps) — push a frame manually.

Virtualization — is what you see real?

Yes, but not all of it. Drawing Dense(3072) as 3 072 points means 2.3 million edges to the previous layer — the browser would freeze.

Instead, max_neurons evenly-spaced representative neurons are selected per layer; activations and weights are sliced to the same indices. Every point and every line you see corresponds to a real neuron or weight — nothing is made up, it is just a subset. When you hover a neuron the tooltip shows the real neuron index (neuron 1847 / 3072) so you always know which slice you are looking at.

Supported layers (Keras 3)

Dense · Conv1D/2D/3D · Conv2DTranspose · SeparableConv2D · LSTM · GRU · SimpleRNN · Flatten · Reshape · Dropout · BatchNormalization · LayerNormalization · MaxPooling* · AveragePooling* · Activation · LeakyReLU · ReLU · Softmax · Embedding

Weights are reduced to a (input_units, output_units) matrix for visualization: conv kernels are summed over spatial axes, LSTM/GRU gates are averaged. The goal is sign and magnitude of the connection, not numerical precision.

Architecture

Keras model ──build_graph()──▶ graph dict ──┐
                                             ├─▶ stdlib HTTP + SSE ──▶ Three.js viewer
ActivationTap.read(x) ──────▶ frame (base64 f32) ┘      (:8092)         (browser)
  • Zero dependencies. The server is pure Python standard library. SSE is used instead of WebSockets because the stream is one-way (Python → browser), SSE is exactly what it was designed for, works with http.server, and reconnects automatically on drop. WebSockets would need either an external package or a hand-written handshake — both break the "pip install nn3d is enough" goal.
  • The viewer knows nothing about the model — only the schema in src/nn3d/schema.py. The same viewer renders a 10-neuron game agent and a 12-block Transformer. Adding support for another framework (PyTorch, Unity, JS game) means writing a new adapter, not touching the viewer.
  • Single geometry. All edges live in one LineSegments, all neurons in one Points. Only the color buffer is updated per frame; geometry never changes.

Modifying the viewer

cd viewer
npm install
npm run dev      # live dev server (start the Python server separately first)
npm run build    # compiles into src/nn3d/static/index.html

The compiled output is part of the package, so the result of npm run build must be committed too.

Examples

file description
examples/nn3d_baslangic.ipynb End-to-end guide: static view, live training, manual frame push, virtualization
examples/churn_canli.py Plain script example (nn3d.wait() usage)
examples/kurs/ FNN / CNN / RNN / GAN course notebooks with nn3d integration
PYTHONPATH=src python examples/churn_canli.py

Metadata

Release files for nn3d 0.1.1

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

Source distribution (sdist)

Source distribution for nn3d 0.1.1
File Size Uploaded Provenance Actions
nn3d-0.1.1.tar.gz 2.5 MB Without provenance Details for nn3d-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for nn3d 0.1.1
File Interpreter ABI Platform Actions
nn3d-0.1.1-py3-none-any.whl Python 3 none any Details for nn3d-0.1.1-py3-none-any.whl

Total release size: 2.7 MB

Release files / nn3d-0.1.1.tar.gz

Download URL nn3d-0.1.1.tar.gz
Size 2.5 MB
Tags Source
SHA-256 checksum
How to use checksums
b3ad58cb29b22e3fcb07a4c68117ef1e2e5abc0926aa031cd6acbaa6ad8db834
BLAKE2b-256 checksum
How to use checksums
71ac27737e0deafd0eb5822f112834a507174491194a150d636aa910e5cd742d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.4

Release files / nn3d-0.1.1-py3-none-any.whl

Download URL nn3d-0.1.1-py3-none-any.whl
Size 201.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
06b81e0002f8d0d82a73fcfbb47d271d66864a6b2d857d5bc702ebc6e15ee176
BLAKE2b-256 checksum
How to use checksums
fa5f38f5120c55141354f6b743bf1d295ba00eee7d22e44610764331930fc67c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.4

Security for nn3d 0.1.1

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

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