Skip to main content

A tiny neural network library built from scratch in NumPy — for learning how autograd, backprop, and optimizers actually work.

Project description

neural-net-from-scratch

PyPI Python License

A tiny neural network library built from scratch in NumPy.

Why does this exist?

I wanted to know how autograd actually works, not just "PyTorch handles it" but how: how the computation graph gets built, how gradients flow backwards, what an optimizer actually does when you call .step(). Best way to learn was to build it myself!

Everything here is pure NumPy. No PyTorch, no JAX, no C extensions. If you want a fast production framework, use PyTorch. If you want to read a few hundred lines of Python that spells out what those frameworks do under the hood, this might be useful.

Installation

Requires Python 3.14+.

Library use (in a project)

uv add neural-net-from-scratch

Or with the demo example included:

uv add "neural-net-from-scratch[examples]"

Try the demo (no project needed)

uvx --from "neural-net-from-scratch[examples]" nn-regression-1d

uvx grabs the package into an ephemeral environment, runs the demo, and cleans up after itself.

Quickstart

Fit a small MLP to y = x² + 1:

import numpy as np

from neural_net.activation import ReLU
from neural_net.layer import Linear
from neural_net.loss_function import Mse
from neural_net.model import Model
from neural_net.node import Node


class MyModel(Model):
    def __init__(self):
        self.linear1 = Linear(1, 16, seed=42)
        self.relu = ReLU()
        self.linear2 = Linear(16, 1, seed=43)

    def forward(self, x: Node) -> Node:
        return self.linear2(self.relu(self.linear1(x)))


rng = np.random.default_rng(7)
X_train = rng.uniform(0, 1, size=(500, 1))
y_true = X_train**2 + 1 + rng.normal(scale=0.03, size=X_train.shape)

model = MyModel()
model.train(
    x_train=X_train,
    y_true=y_true,
    loss=Mse(),
    optimizer_key="sgd",
    num_epochs=2000,
    batch_size=40,
    learning_rate=0.04,
    shuffle=True,
)

X_test = np.linspace(0, 1, 100).reshape(-1, 1)
y_pred = model.predict(X_test)[0]

That's the whole thing. Subclass Model, define your layers in __init__, wire them together in forward, call .train(...).

Examples

Once you install with the examples extra, you get a CLI demo:

uv run nn-regression-1d

That runs a 1D regression sweep across a few hidden layer sizes (4, 8, 32, 256) and plots them side by side so you can see how capacity affects the fit. Source lives at src/neural_net/examples/regression_1d.py if you want to poke at it.

Core concepts

A quick tour of the building blocks:

  • Node — a NumPy array with autograd metadata attached (who created it, what its parents are, its accumulated gradient, whether it needs one). The autograd graph is a graph of Nodes.
  • Layer — a stateless-ish transformation with a forward() and a backward(). Calling one builds a new Node and hooks it into the graph. Linear and Add live here.
  • Activation — same as Layer, just semantically for non-parametric nonlinearities. ReLU lives here.
  • LossFunction — takes (y_pred, y_true), returns a scalar Node you can call .backward() on. Mse is included.
  • Optimizer — walks the model's parameters and applies updates. Sgd is included; new optimizers auto-register themselves via __init_subclass__.
  • Model — subclass this, drop your layers into __init__, wire them in forward(). Get parameters(), predict(), and a full train() loop for free.

The flow when you train:

  1. Forward pass through your Model builds a computation graph of Nodes.
  2. The loss node sits at the root of that graph.
  3. .backward() on the root does a topological sort and walks backwards, accumulating gradients on every Node with requires_grad=True.
  4. The optimizer applies those gradients to your parameters.
  5. Repeat.

That's it! No magic layers, no framework internals hiding anything. Read the source in src/neural_net/ and you can trace every step.

License

MIT. See LICENSE.

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

neural_net_from_scratch-0.1.1.tar.gz (43.6 kB view details)

Uploaded Source

Built Distribution

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

neural_net_from_scratch-0.1.1-py3-none-any.whl (13.1 kB view details)

Uploaded Python 3

File details

Details for the file neural_net_from_scratch-0.1.1.tar.gz.

File metadata

  • Download URL: neural_net_from_scratch-0.1.1.tar.gz
  • Upload date:
  • Size: 43.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for neural_net_from_scratch-0.1.1.tar.gz
Algorithm Hash digest
SHA256 3a61a85c48255e2fbf64b1b7edabe913a85db79ff3cf3bd70ce12ed609e0b56a
MD5 1b5632ee59cd9b7bf55c8ef182110064
BLAKE2b-256 1e03ddc0b589de3e74277cb28e78155ced2e225886dfeaeb9b370b87040f38c4

See more details on using hashes here.

File details

Details for the file neural_net_from_scratch-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: neural_net_from_scratch-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 13.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for neural_net_from_scratch-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 963edeb2bb014825b8f99cb3f8af911cb3ec14ac3ae6dfb5a77abeb252b6a041
MD5 72ca37a419ed70a4dcb5046866ab5854
BLAKE2b-256 5cff552aea1b94be02dd201f07297584ba7ce4678afe83d11e2cb240b6d0a551

See more details on using hashes here.

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