Model (Neural Network Composition)
March 25, 2026 · View on GitHub
Overview & Motivation
A Model composes a sequence of dense layers into a single trainable function . It is the orchestrator that:
- Chains layers so the output of each feeds into the next (forward pass).
- Propagates gradients backward through the chain (backward pass).
- Flattens all layer parameters into a single vector for the optimizer.
- Verifies dimensional compatibility at compile time using variadic templates.
In this library, the Model is fully statically typed — layer dimensions, parameter counts, and memory footprints are all known at compile time, enabling zero-overhead abstraction on embedded targets.
Mathematical Theory
Composition
For layers with transformations :
Each is a dense layer: .
Parameter Vector
All weights and biases are concatenated into a single vector:
where .
Forward Pass (Chained Evaluation)
graph LR
X["x ∈ ℝⁿ"] --> L1["Layer 1"] --> L2["Layer 2"] --> Ldots["⋯"] --> LL["Layer L"] --> Y["ŷ ∈ ℝᵐ"]
Backward Pass (Reverse Chain Rule)
Each layer stores its input during the forward pass so it can compute and during the backward pass.
Training Loop
graph TD
FP["Forward pass: ŷ = Model(x)"]
LC["Loss: ℒ(ŷ, y)"]
BP["Backward pass: ∇θ ℒ"]
UP["Update: θ ← θ − η ∇θ ℒ"]
FP --> LC --> BP --> UP --> FP
Complexity Analysis
| Operation | Time | Space |
|---|---|---|
| Forward pass | cached activations | |
| Backward pass | gradients | |
GetParameters() | flat vector | |
SetParameters() | — |
All operations scale linearly with the total parameter count .
Step-by-Step Walkthrough
Model: 2 → 3 → 1 (two layers).
Compile-time verification chain:
| Check | Condition | Status |
|---|---|---|
| Layer 1 input size = Model input size | $2 = 2$ | ✓ |
| Layer 1 output size = Layer 2 input size | $3 = 3$ | ✓ |
| Layer 2 output size = Model output size | $1 = 1$ | ✓ |
All types derive from Layer | type trait check | ✓ |
Parameter layout ():
| Index | Parameter |
|---|---|
| 0–5 | (3×2 = 6 elements) |
| 6–8 | (3 elements) |
| 9–11 | (1×3 = 3 elements) |
| 12 | (1 element) |
Forward pass with :
- Layer 1:
- Layer 2:
Backward pass with loss gradient :
- Layer 2 backward → produces , , and
- Layer 1 backward → produces ,
Optimizer receives the full and updates .
Pitfalls & Edge Cases
- Dimension mismatch caught at compile time. If layer outputs but layer expects , a
static_assertfires during compilation. - Empty model. The variadic template requires at least one layer.
static_assert(sizeof...(Layers) > 0). - Parameter ordering.
GetParameters()andSetParameters()must use the same concatenation order. The implementation iterates layers viastd::index_sequenceto guarantee consistency. - Training with wrong optimizer size. The optimizer's parameter count template argument must equal
Model::TotalParameters. A mismatch is also caught at compile time. - Large parameter vectors. All parameters live on the stack. A model with floats consumes 40 KB — verify this fits the target's stack.
Variants & Generalizations
| Variant | Key Difference |
|---|---|
| Sequential model (dynamic) | Layers stored in a container; dimension checked at runtime instead of compile time |
| Functional API | Supports branching and merging (DAG topology instead of linear chain) |
| Residual model | Adds skip connections: |
| Recurrent model | Unrolls the same layer across time steps |
Applications
- Embedded inference — A pre-trained model's parameters are loaded via
SetParameters()and onlyForward()is called at runtime. - On-device training — The full forward → loss → backward → update loop runs on the MCU for online learning/adaptation.
- System identification — A small model (2–3 layers) learns the plant dynamics from input-output data.
- Sensor fusion — Multiple sensor inputs are mapped to a unified state estimate through a trained model.
Connections to Other Algorithms
graph TD
Model["Model"]
Layer["Dense Layer"]
Loss["Loss Functions"]
Opt["Optimizer"]
Reg["Regularization"]
NN["Neural Network"]
Layer --> Model
Model --> Opt
Model --> Loss
Reg --> Loss
Model --> NN
| Component | Relationship |
|---|---|
| Dense Layer | The Model is a sequence of layers stored in a std::tuple |
| Loss Functions | Measures prediction error; the Model delegates loss computation to a Loss object |
| Optimizer | Receives the flat parameter/gradient vectors from the Model and returns updated parameters |
| Regularization | Added to the loss before optimization |
References & Further Reading
- Goodfellow, I., Bengio, Y., and Courville, A., Deep Learning, MIT Press, 2016 — Chapter 6 (deep feedforward networks).
- Paszke, A. et al., "PyTorch: An imperative style, high-performance deep learning library", NeurIPS, 2019 — inspiration for the sequential/functional model API.
- Abadi, M. et al., "TensorFlow: A system for large-scale machine learning", OSDI, 2016.