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
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 aforward()and abackward(). Calling one builds a new Node and hooks it into the graph.LinearandAddlive here.Activation— same as Layer, just semantically for non-parametric nonlinearities.ReLUlives here.LossFunction— takes(y_pred, y_true), returns a scalar Node you can call.backward()on.Mseis included.Optimizer— walks the model's parameters and applies updates.Sgdis included; new optimizers auto-register themselves via__init_subclass__.Model— subclass this, drop your layers into__init__, wire them inforward(). Getparameters(),predict(), and a fulltrain()loop for free.
The flow when you train:
- Forward pass through your
Modelbuilds a computation graph ofNodes. - The loss node sits at the root of that graph.
.backward()on the root does a topological sort and walks backwards, accumulating gradients on every Node withrequires_grad=True.- The optimizer applies those gradients to your parameters.
- 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file neural_net_from_scratch-0.1.0.tar.gz.
File metadata
- Download URL: neural_net_from_scratch-0.1.0.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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65bab309780148f74eddcc914541ee531541051b8791c4f4a9310f96547a3e52
|
|
| MD5 |
f4f67875f8f0dee08eb5533a927d3b2e
|
|
| BLAKE2b-256 |
57174be83b78feb8fe1559e9df91dc8ff6aaf18ab6be4153cab15aa909c8b6f2
|
File details
Details for the file neural_net_from_scratch-0.1.0-py3-none-any.whl.
File metadata
- Download URL: neural_net_from_scratch-0.1.0-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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f39960d4361b7e855a0e448beb1b40766bd1b3e500136a0a6804ac0def9173b2
|
|
| MD5 |
f9dc8299ef51a6c5899ceb11b8777f2f
|
|
| BLAKE2b-256 |
66f8c80e48b39fd84c3989dac13c5fc7eeae84681704fd825830d75be7eb7827
|