Neural Network Toolbox

A Field Guide to Embedded Neural Network Algorithms

Gabriel Francisco dos Santos

gabriel.fra.santos@gmail.com

August 08, 2026

1 Neural Network

1.1 Neural Networks

1.1.1 Overview & Motivation

A neural network is a parameterized function \(f_\theta: \mathbb{R}^n \to \mathbb{R}^m\) built by composing simple, differentiable transformations called layers. Each layer applies an affine map followed by a non-linear activation, and the whole composition is trained end-to-end by gradient-based optimization.

Neural networks are powerful because of the universal approximation theorem: a single hidden layer with enough neurons can approximate any continuous function on a compact set to arbitrary accuracy. In practice, depth (many layers) is more parameter-efficient than width for learning hierarchical features.

This library provides a minimal, statically-sized neural network framework designed for embedded inference and on-device training — no heap allocation, no dynamic shapes, full compile-time dimension checking.

1.1.2 Mathematical Theory

1.1.2.1 Forward Propagation

Given \(L\) layers, the network computes:

\[a_0 = x\] \[z_\ell = W_\ell \, a_{\ell-1} + b_\ell, \quad \ell = 1, \ldots, L\] \[a_\ell = f_\ell(z_\ell)\] \[\hat{y} = a_L\]

where \(W_\ell \in \mathbb{R}^{n_\ell \times n_{\ell-1}}\) are weights, \(b_\ell \in \mathbb{R}^{n_\ell}\) are biases, and \(f_\ell\) is the activation function for layer \(\ell\).

1.1.2.2 Loss Function

Training minimizes a scalar loss \(\mathcal{L}(\hat{y}, y)\) that measures how far the prediction \(\hat{y}\) is from the target \(y\). Common choices:

Loss Formula Use Case
MSE \(\frac{1}{m}\sum(\hat{y}_i - y_i)^2\) Regression
BCE \(-\sum[y_i \log \hat{y}_i + (1-y_i)\log(1-\hat{y}_i)]\) Binary classification
CCE \(-\sum y_i \log \hat{y}_i\) Multi-class classification

1.1.2.3 Backpropagation

Backpropagation efficiently computes \(\nabla_\theta \mathcal{L}\) via the chain rule, working from the output layer backward:

\[\delta_L = \nabla_{a_L}\mathcal{L} \odot f_L'(z_L)\] \[\delta_\ell = (W_{\ell+1}^T \delta_{\ell+1}) \odot f_\ell'(z_\ell)\]

The gradients with respect to parameters are:

\[\frac{\partial \mathcal{L}}{\partial W_\ell} = \delta_\ell \, a_{\ell-1}^T, \qquad \frac{\partial \mathcal{L}}{\partial b_\ell} = \delta_\ell\]

1.1.2.4 Parameter Update

An optimizer uses the gradients to update the parameter vector \(\theta\):

\[\theta_{t+1} = \theta_t - \eta \, \nabla_\theta \mathcal{L}\]

where \(\eta\) is the learning rate. More sophisticated optimizers (momentum, Adam) modify this basic rule.

1.1.3 Complexity Analysis

Phase Time Space
Forward pass \(O\!\left(\sum_{\ell=1}^L n_\ell \cdot n_{\ell-1}\right)\) \(O\!\left(\sum n_\ell\right)\) activations
Backward pass Same as forward Same + gradient storage
Parameter update \(O(P)\) \(O(P)\) optimizer state

where \(P = \sum_\ell (n_\ell \cdot n_{\ell-1} + n_\ell)\) is the total parameter count. For small embedded networks (\(P < 10{,}000\)), both passes complete in microseconds.

1.1.4 Step-by-Step Walkthrough

Network: 2 inputs → 2 hidden (ReLU) → 1 output (Sigmoid). Learning XOR.

Architecture:

graph LR
    x1((x₁)) --> h1((h₁))
    x1 --> h2((h₂))
    x2((x₂)) --> h1
    x2 --> h2
    h1 --> y((ŷ))
    h2 --> y

Epoch 0 — Forward pass with input \(x = [1, 0]^T\), target \(y = 1\):

Step Computation Result
Hidden pre-activation \(z_1 = W_1 x + b_1\) \([0.3, -0.1]^T\)
Hidden activation \(a_1 = \text{ReLU}(z_1)\) \([0.3, 0.0]^T\)
Output pre-activation \(z_2 = W_2 a_1 + b_2\) \([0.15]\)
Output activation \(\hat{y} = \sigma(z_2)\) \([0.537]\)
Loss \(\mathcal{L} = -(y\log\hat{y} + (1-y)\log(1-\hat{y}))\) \(0.621\)

Epoch 0 — Backward pass:

Step Computation Result
Output gradient \(\delta_2 = \hat{y} - y\) \([-0.463]\)
\(\nabla W_2\) \(\delta_2 \cdot a_1^T\) \([-0.139, 0]\)
Hidden gradient \(\delta_1 = W_2^T \delta_2 \odot \text{ReLU}'(z_1)\) \([-0.231, 0]^T\)
\(\nabla W_1\) \(\delta_1 \cdot x^T\) \([[-0.231, 0], [0, 0]]\)

Update: \(W \leftarrow W - 0.1 \cdot \nabla W\). After ~500 epochs, the network correctly classifies all four XOR inputs.

1.1.5 Pitfalls & Edge Cases

1.1.6 Variants & Generalizations

Variant Key Difference
Convolutional Neural Network (CNN) Layers share weights spatially; efficient for image/signal data
Recurrent Neural Network (RNN) Layers share weights across time steps; models sequences
Residual Network (ResNet) Skip connections mitigate vanishing gradients in very deep networks
Transformer Attention-based; no recurrence; state-of-the-art for sequences
Quantized Neural Network Weights and activations in low-bit integers; optimal for MCU deployment

1.1.7 Applications

1.1.8 Connections to Other Algorithms

graph TD
    NN["Neural Network"]
    Layer["Dense Layer"]
    Act["Activation Functions"]
    Loss["Loss Functions"]
    Opt["Optimizer"]
    Reg["Regularization"]
    Model["Model"]
    LR["Linear Regression"]

    Layer --> NN
    Act --> NN
    Loss --> NN
    Opt --> NN
    Reg --> NN
    NN --> Model
    NN -.->|"single-layer, linear activation, MSE loss"| LR
Component Relationship
Dense Layer The fundamental building block; computes affine transformations
Activation Functions Introduce non-linearity after each layer
Loss Functions Define the training objective
Optimizer (numerical-toolbox-cpp) Drives parameter updates via gradient descent
Regularization (numerical-toolbox-cpp) Penalizes complexity to prevent overfitting
Model Composes layers into a trainable pipeline
Linear Regression (numerical-toolbox-cpp) Special case: single layer, identity activation, MSE loss

1.2 Dense Layer

1.2.1 Overview & Motivation

A dense (fully-connected) layer is the most fundamental building block of a neural network. It maps an input vector \(a_{\text{in}} \in \mathbb{R}^n\) to an output vector \(a_{\text{out}} \in \mathbb{R}^m\) through a learnable affine transformation followed by a non-linear activation:

\[a_{\text{out}} = f(W \, a_{\text{in}} + b)\]

Every input neuron is connected to every output neuron — hence “fully connected.” The layer’s parameters are the weight matrix \(W\) and bias vector \(b\); training adjusts these to minimize the loss.

In this library, input size, output size, and parameter count are all compile-time constants, enabling stack allocation and dimension checking with zero runtime overhead.

1.2.2 Mathematical Theory

1.2.2.1 Forward Pass

\[z = W \, a_{\text{in}} + b, \qquad a_{\text{out}} = f(z)\]

where \(W \in \mathbb{R}^{m \times n}\), \(b \in \mathbb{R}^m\), and \(f\) is the activation function.

1.2.2.2 Backward Pass

Given the gradient of the loss with respect to the output \(\frac{\partial \mathcal{L}}{\partial a_{\text{out}}}\):

  1. Pre-activation gradient: \[\delta = \frac{\partial \mathcal{L}}{\partial a_{\text{out}}} \odot f'(z)\]

  2. Weight gradient: \[\frac{\partial \mathcal{L}}{\partial W} = \delta \, a_{\text{in}}^T\]

  3. Bias gradient: \[\frac{\partial \mathcal{L}}{\partial b} = \delta\]

  4. Input gradient (propagated to the previous layer): \[\frac{\partial \mathcal{L}}{\partial a_{\text{in}}} = W^T \delta\]

1.2.2.3 Parameter Count

\[P = m \times n + m = m(n + 1)\]

For a layer with 128 inputs and 64 outputs: \(P = 64 \times 129 = 8{,}256\) parameters.

1.2.3 Complexity Analysis

Operation Time Space
Forward (\(W a + b\)) \(O(m \cdot n)\) \(O(m)\) output + \(O(m)\) cached \(z\)
Backward (\(\delta\), \(\nabla W\), \(\nabla b\)) \(O(m \cdot n)\) \(O(m \cdot n)\) weight gradient
Total parameters \(O(m \cdot n + m)\)

The matrix-vector product dominates both passes. For embedded networks (e.g. \(n = 32, m = 16\)), a single forward pass takes ~512 multiply-accumulate operations.

1.2.4 Step-by-Step Walkthrough

Layer: 3 inputs → 2 outputs, ReLU activation.

\[W = \begin{bmatrix} 0.5 & -0.3 & 0.8 \\ 0.1 & 0.7 & -0.2 \end{bmatrix}, \quad b = \begin{bmatrix} 0.1 \\ -0.1 \end{bmatrix}, \quad a_{\text{in}} = \begin{bmatrix} 1.0 \\ 0.5 \\ -1.0 \end{bmatrix}\]

Forward:

Step Computation Result
\(z = W a_{\text{in}} + b\) \([0.5 - 0.15 - 0.8 + 0.1,\; 0.1 + 0.35 + 0.2 - 0.1]\) \([-0.35,\; 0.55]^T\)
\(a_{\text{out}} = \text{ReLU}(z)\) \([\max(0, -0.35),\; \max(0, 0.55)]\) \([0.0,\; 0.55]^T\)

Backward with \(\frac{\partial \mathcal{L}}{\partial a_{\text{out}}} = [0.2,\; -0.4]^T\):

Step Computation Result
\(\delta = \nabla a_{\text{out}} \odot \text{ReLU}'(z)\) \([0.2 \cdot 0,\; -0.4 \cdot 1]\) \([0,\; -0.4]^T\)
\(\nabla W = \delta \, a_{\text{in}}^T\) row 1: all zeros; row 2: \(-0.4 \times [1, 0.5, -1]\) \(\begin{bmatrix}0 & 0 & 0\\-0.4 & -0.2 & 0.4\end{bmatrix}\)
\(\nabla b = \delta\) \([0,\; -0.4]^T\)
\(\nabla a_{\text{in}} = W^T \delta\) \(W^T [0, -0.4]^T\) \([-0.04,\; -0.28,\; 0.08]^T\)

1.2.5 Pitfalls & Edge Cases

1.2.6 Variants & Generalizations

Variant Key Difference
Convolutional layer Weight sharing across spatial positions; \(O(k^2 \cdot c)\) parameters per filter instead of \(O(n \cdot m)\)
Recurrent layer Shares weights across time steps; adds a hidden state feedback connection
Batch normalization layer Normalizes activations to zero mean and unit variance; accelerates training
Dropout layer Randomly zeros activations during training; regularization effect
Sparse layer Only a subset of connections exist; reduces parameter count and computation

1.2.7 Applications

1.2.8 Connections to Other Algorithms

graph TD
    Layer["Dense Layer"]
    Act["Activation Functions"]
    Model["Model"]
    Opt["Optimizer"]
    LR["Linear Regression"]

    Act --> Layer
    Layer --> Model
    Model --> Opt
    Layer -.->|"no activation, MSE loss"| LR
Component Relationship
Activation Functions Applied element-wise after the affine transformation
Model Chains multiple dense layers into a network
Optimizer (numerical-toolbox-cpp) Updates \(W\) and \(b\) using the computed gradients
Linear Regression (numerical-toolbox-cpp) A dense layer with identity activation and MSE loss is equivalent to linear regression

1.3 Activation Functions

1.3.1 Overview & Motivation

An activation function \(f\) is a non-linear, element-wise transformation applied after the affine map in each neural network layer:

\[a = f(z) = f(W x + b)\]

Without activation functions, stacking layers would collapse into a single affine transformation — the network could only represent linear mappings regardless of depth. Activation functions are what give neural networks their expressive power.

The choice of activation function controls gradient flow during back-propagation, output range, and computational cost — all critical on resource-constrained embedded targets.

1.3.2 Mathematical Theory

1.3.2.1 Forward and Backward

Every activation function exposes two operations:

Operation Definition Purpose
Forward \(a = f(z)\) Transform the pre-activation
Backward \(f'(z)\) Provide the local derivative for back-propagation

The chain rule connects them during training:

\[\frac{\partial \mathcal{L}}{\partial z} = \frac{\partial \mathcal{L}}{\partial a} \cdot f'(z)\]

1.3.2.2 Catalogue

1.3.2.2.1 ReLU (Rectified Linear Unit)

\[f(z) = \max(0, z), \qquad f'(z) = \begin{cases} 1 & z > 0 \\ 0 & z \le 0 \end{cases}\]

1.3.2.2.2 Leaky ReLU

\[f(z) = \begin{cases} z & z > 0 \\ \alpha z & z \le 0 \end{cases}, \qquad f'(z) = \begin{cases} 1 & z > 0 \\ \alpha & z \le 0 \end{cases}\]

where \(\alpha\) is a small positive constant (typically \(0.01\)). Prevents dead neurons by allowing a small gradient for \(z < 0\).

1.3.2.2.3 Sigmoid

\[f(z) = \frac{1}{1 + e^{-z}}, \qquad f'(z) = f(z)(1 - f(z))\]

1.3.2.2.4 Tanh (Hyperbolic Tangent)

\[f(z) = \tanh(z) = \frac{e^z - e^{-z}}{e^z + e^{-z}}, \qquad f'(z) = 1 - f(z)^2\]

1.3.2.2.5 Softmax

For a vector \(\mathbf{z} \in \mathbb{R}^k\):

\[f(z_i) = \frac{e^{z_i}}{\sum_{j=1}^{k} e^{z_j}}\]

1.3.3 Complexity Analysis

Activation Forward (per element) Backward (per element) Notes
ReLU \(O(1)\) — comparison \(O(1)\) — comparison Fastest
Leaky ReLU \(O(1)\) — comparison + multiply \(O(1)\) Negligible overhead vs ReLU
Sigmoid \(O(1)\) — exp + divide \(O(1)\) — reuse forward result Requires exp()
Tanh \(O(1)\) — exp (twice) \(O(1)\) — reuse forward result Requires exp()
Softmax \(O(k)\) — vector exp + sum \(O(k^2)\) — full Jacobian Significantly more expensive

1.3.4 Step-by-Step Walkthrough

Scenario: Forward and backward pass through a 3-neuron hidden layer with ReLU, given pre-activations \(z = [-0.5, \; 1.2, \; 0.0]\).

Forward:

Neuron \(z\) \(\text{ReLU}(z)\)
1 \(-0.5\) \(0.0\)
2 \(1.2\) \(1.2\)
3 \(0.0\) \(0.0\)

Backward with incoming gradient \(\frac{\partial \mathcal{L}}{\partial a} = [0.3, \; -0.7, \; 0.1]\):

Neuron \(f'(z)\) \(\frac{\partial \mathcal{L}}{\partial z}\)
1 \(0\) (dead) \(0.3 \times 0 = 0\)
2 \(1\) \(-0.7 \times 1 = -0.7\)
3 \(0\) (at boundary) \(0.1 \times 0 = 0\)

Neuron 1 is dead — its gradient is zero and its weights will not update. If this persists across all training samples, the neuron is permanently inactive.

1.3.5 Pitfalls & Edge Cases

1.3.6 Variants & Generalizations

Variant Key Difference
PReLU (Parametric ReLU) \(\alpha\) is a learnable parameter per channel
ELU (Exponential LU) \(\alpha(e^z - 1)\) for \(z < 0\); smooth and zero-centered
GELU (Gaussian Error LU) \(z \cdot \Phi(z)\); used in Transformers
Swish / SiLU \(z \cdot \sigma(z)\); smooth, non-monotonic
Hard Sigmoid / Hard Tanh Piece-wise linear approximations; no transcendentals

1.3.7 Applications

1.3.8 Connections to Other Algorithms

graph TD
    Act["Activation Functions"]
    Layer["Dense Layer"]
    NN["Neural Network"]
    Loss["Loss Functions"]
    Act --> Layer
    Layer --> NN
    NN --> Loss
Component Relationship
Dense Layer Applies the activation function after the affine transformation
Neural Network Activations enable the non-linear function approximation that makes deep networks useful
Loss Functions The output activation must match the loss: Sigmoid + BCE, Softmax + CCE

1.4 Loss Functions

1.4.1 Overview & Motivation

A loss function \(\mathcal{L}(\hat{y}, y)\) quantifies how far a model’s prediction \(\hat{y}\) is from the true target \(y\). Training a neural network means finding parameters \(\theta\) that minimize the expected loss over the training data:

\[\theta^* = \arg\min_\theta \; \mathbb{E}[\mathcal{L}(f_\theta(x), y)]\]

The loss function defines the entire learning objective — different losses lead to different optimal models even on the same data. It must also provide a gradient \(\nabla_{\hat{y}} \mathcal{L}\) for back-propagation.

1.4.2 Mathematical Theory

1.4.2.1 Mean Squared Error (MSE)

\[\mathcal{L}_{\text{MSE}} = \frac{1}{m} \sum_{i=1}^{m} (\hat{y}_i - y_i)^2\]

\[\frac{\partial \mathcal{L}}{\partial \hat{y}_i} = \frac{2}{m}(\hat{y}_i - y_i)\]

1.4.2.2 Mean Absolute Error (MAE)

\[\mathcal{L}_{\text{MAE}} = \frac{1}{m} \sum_{i=1}^{m} |\hat{y}_i - y_i|\]

\[\frac{\partial \mathcal{L}}{\partial \hat{y}_i} = \frac{1}{m} \mathrm{sign}(\hat{y}_i - y_i)\]

1.4.2.3 Binary Cross-Entropy (BCE)

\[\mathcal{L}_{\text{BCE}} = -\frac{1}{m}\sum_{i=1}^{m} \left[ y_i \log \hat{y}_i + (1 - y_i) \log(1 - \hat{y}_i) \right]\]

\[\frac{\partial \mathcal{L}}{\partial \hat{y}_i} = -\frac{1}{m}\left(\frac{y_i}{\hat{y}_i} - \frac{1 - y_i}{1 - \hat{y}_i}\right)\]

1.4.2.4 Categorical Cross-Entropy (CCE)

\[\mathcal{L}_{\text{CCE}} = -\sum_{i=1}^{k} y_i \log \hat{y}_i\]

\[\frac{\partial \mathcal{L}}{\partial \hat{y}_i} = -\frac{y_i}{\hat{y}_i}\]

1.4.3 Complexity Analysis

Loss Forward Backward Notes
MSE \(O(m)\) \(O(m)\) Cheapest; no transcendentals
MAE \(O(m)\) \(O(m)\) Requires sign()
BCE \(O(m)\) \(O(m)\) Requires log()
CCE \(O(k)\) \(O(k)\) Requires log()

All losses are \(O(m)\) where \(m\) is the output dimension. The computational cost is negligible compared to the dense layer matrix products.

1.4.4 Step-by-Step Walkthrough

Scenario: 3-class classification. Target \(y = [0, 1, 0]\) (class 2). Softmax output \(\hat{y} = [0.1, 0.7, 0.2]\).

CCE Forward:

\[\mathcal{L} = -(0 \cdot \log 0.1 + 1 \cdot \log 0.7 + 0 \cdot \log 0.2) = -\log(0.7) \approx 0.357\]

CCE Backward:

\(i\) \(y_i\) \(\hat{y}_i\) \(\partial \mathcal{L}/\partial \hat{y}_i = -y_i / \hat{y}_i\)
1 0 0.1 \(0\)
2 1 0.7 \(-1.429\)
3 0 0.2 \(0\)

The gradient is non-zero only for the true class, and its magnitude \(1/\hat{y}_2\) grows as the prediction worsens — providing a strong corrective signal.

For comparison — MSE on the same example:

\[\mathcal{L}_{\text{MSE}} = \frac{1}{3}[(0.1)^2 + (0.7-1)^2 + (0.2)^2] = \frac{1}{3}[0.01 + 0.09 + 0.04] = 0.047\]

MSE gives a much weaker signal and does not account for the probabilistic nature of the output.

1.4.5 Pitfalls & Edge Cases

1.4.6 Variants & Generalizations

Variant Key Difference
Huber loss Quadratic for small errors, linear for large; robust regression
Focal loss Down-weights well-classified examples; addresses class imbalance
KL divergence Measures distance between two distributions; used in variational inference
Hinge loss Margin-based; used in SVMs and some neural classifiers
Contrastive loss Learns similarity metrics; used in Siamese networks

1.4.7 Applications

1.4.8 Connections to Other Algorithms

graph TD
    Loss["Loss Functions"]
    Act["Activation Functions"]
    Opt["Optimizer"]
    Reg["Regularization"]
    Model["Model"]
    LR["Linear Regression"]

    Act -->|"output activation must match loss"| Loss
    Loss --> Opt
    Reg -->|"added to loss"| Loss
    Loss --> Model
    Loss -.->|"MSE + normal equation"| LR
Component Relationship
Activation Functions Output activation must match: Sigmoid ↔︎ BCE, Softmax ↔︎ CCE, identity ↔︎ MSE
Optimizer (numerical-toolbox-cpp) Uses \(\nabla \mathcal{L}\) to update parameters
Regularization (numerical-toolbox-cpp) Adds a penalty term to the loss: \(\mathcal{L}_{\text{total}} = \mathcal{L} + \lambda \Omega(\theta)\)
Linear Regression (numerical-toolbox-cpp) Solved analytically when the loss is MSE and the model is linear

1.5 Model (Neural Network Composition)

1.5.1 Overview & Motivation

A Model composes a sequence of dense layers into a single trainable function \(f: \mathbb{R}^n \to \mathbb{R}^m\). It is the orchestrator that:

  1. Chains layers so the output of each feeds into the next (forward pass).
  2. Propagates gradients backward through the chain (backward pass).
  3. Flattens all layer parameters into a single vector for the optimizer.
  4. 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.

1.5.2 Mathematical Theory

1.5.2.1 Composition

For \(L\) layers with transformations \(f_1, f_2, \ldots, f_L\):

\[\hat{y} = (f_L \circ f_{L-1} \circ \cdots \circ f_1)(x) = f_L(f_{L-1}(\ldots f_1(x) \ldots))\]

Each \(f_\ell\) is a dense layer: \(f_\ell(a) = \sigma_\ell(W_\ell a + b_\ell)\).

1.5.2.2 Parameter Vector

All weights and biases are concatenated into a single vector:

\[\theta = [\text{vec}(W_1), b_1, \text{vec}(W_2), b_2, \ldots, \text{vec}(W_L), b_L] \in \mathbb{R}^P\]

where \(P = \sum_{\ell=1}^L m_\ell(n_\ell + 1)\).

1.5.2.3 Forward Pass (Chained Evaluation)

graph LR
    X["x ∈ ℝⁿ"] --> L1["Layer 1"] --> L2["Layer 2"] --> Ldots["⋯"] --> LL["Layer L"] --> Y["ŷ ∈ ℝᵐ"]

1.5.2.4 Backward Pass (Reverse Chain Rule)

\[\frac{\partial \mathcal{L}}{\partial \theta_\ell} = \frac{\partial \mathcal{L}}{\partial a_L} \cdot \frac{\partial a_L}{\partial a_{L-1}} \cdots \frac{\partial a_{\ell+1}}{\partial a_\ell} \cdot \frac{\partial a_\ell}{\partial \theta_\ell}\]

Each layer stores its input \(a_{\ell-1}\) during the forward pass so it can compute \(\nabla W_\ell\) and \(\nabla b_\ell\) during the backward pass.

1.5.2.5 Training Loop

graph TD
    FP["Forward pass: ŷ = Model(x)"]
    LC["Loss: ℒ(ŷ, y)"]
    BP["Backward pass: ∇θ ℒ"]
    UP["Update: θ ← θ − η ∇θ ℒ"]
    FP --> LC --> BP --> UP --> FP

1.5.3 Complexity Analysis

Operation Time Space
Forward pass \(O(P)\) \(O(\sum n_\ell)\) cached activations
Backward pass \(O(P)\) \(O(P)\) gradients
GetParameters() \(O(P)\) \(O(P)\) flat vector
SetParameters() \(O(P)\)

All operations scale linearly with the total parameter count \(P\).

1.5.4 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 (\(P = 3(2 + 1) + 1(3 + 1) = 9 + 4 = 13\)):

Index Parameter
0–5 \(W_1\) (3×2 = 6 elements)
6–8 \(b_1\) (3 elements)
9–11 \(W_2\) (1×3 = 3 elements)
12 \(b_2\) (1 element)

Forward pass with \(x = [1.0, 0.5]^T\):

  1. Layer 1: \(a_1 = \text{ReLU}(W_1 x + b_1) = [0.0, 0.8, 0.3]^T\)
  2. Layer 2: \(\hat{y} = \sigma(W_2 a_1 + b_2) = [0.62]\)

Backward pass with loss gradient \(\delta_{\text{out}} = [0.12]\):

  1. Layer 2 backward → produces \(\nabla W_2\), \(\nabla b_2\), and \(\delta_1 = W_2^T \delta_2 \odot \text{ReLU}'(z_1)\)
  2. Layer 1 backward → produces \(\nabla W_1\), \(\nabla b_1\)

Optimizer receives the full \(\nabla \theta \in \mathbb{R}^{13}\) and updates \(\theta\).

1.5.5 Pitfalls & Edge Cases

1.5.6 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: \(a_{\ell+2} = f_{\ell+1}(a_\ell) + a_\ell\)
Recurrent model Unrolls the same layer across time steps

1.5.7 Applications

1.5.8 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 (numerical-toolbox-cpp) Receives the flat parameter/gradient vectors from the Model and returns updated parameters
Regularization (numerical-toolbox-cpp) Added to the loss before optimization

2 References