Forward pass

intro 8 minfundamentalsneural-networks

Builds on:Functions are machinesMatrices transform space

The idea

A feedforward network is just function composition: the input is pushed through a stack of layers, each of which does something very simple, and the prediction pops out the far end. For a dense (fully connected) layer ℓ\ell:

z(ℓ)=W(ℓ)a(ℓ−1)+b(ℓ),a(ℓ)=g(z(ℓ))z^{(\ell)} = W^{(\ell)} a^{(\ell-1)} + b^{(\ell)}, \qquad a^{(\ell)} = g\left(z^{(\ell)}\right)

Two things make this composition interesting. First, the nonlinearity: without gg, the whole stack collapses into one affine map, so a 1000-layer linear network is exactly a linear model. Second, the caching: every intermediate a(ℓ)a^{(\ell)} (and often z(ℓ)z^{(\ell)}) is kept in memory, because backpropagation reuses them — the forward pass is not just computing a prediction, it is laying down the breadcrumbs the backward pass will follow.

The final layer is a task-specific head. Its raw outputs are logits — unbounded real scores — and the last step maps them to the right output space: identity for regression, sigmoid for a binary probability, softmax pi=ezi/∑jezjp_i = e^{z_i}/\sum_j e^{z_j} for a distribution over classes.

In practice everything is batched: NN inputs are stacked into a matrix XX of shape N×dN \times d, and each layer transforms the whole batch in one matrix multiply. That is the entire reason GPUs make deep learning feasible.

Worked example

A 2-input, 2-hidden-unit (ReLU), 1-output (sigmoid) network, with

W(1)=[0.5−1.01.00.5],b(1)=[01],W(2)=[1.0−1.0],b(2)=0.5.\begin{aligned} W^{(1)} &= \begin{bmatrix} 0.5 & -1.0 \\ 1.0 & 0.5 \end{bmatrix}, & b^{(1)} &= \begin{bmatrix} 0 \\ 1 \end{bmatrix}, \\ W^{(2)} &= \begin{bmatrix} 1.0 & -1.0 \end{bmatrix}, & b^{(2)} &= 0.5. \end{aligned}

Push x=(1,2)x = (1, 2) through it:

StepComputationResult
Pre-activation 1z1(1)=0.5(1)−1.0(2)+0z^{(1)}_1 = 0.5(1) - 1.0(2) + 0−1.5-1.5
Pre-activation 2z2(1)=1.0(1)+0.5(2)+1z^{(1)}_2 = 1.0(1) + 0.5(2) + 13.03.0
Hidden ReLUa(1)=max⁡(0,z(1))a^{(1)} = \max(0, z^{(1)})(0,3)(0, 3)
Output logitz(2)=1.0(0)−1.0(3)+0.5z^{(2)} = 1.0(0) - 1.0(3) + 0.5−2.5-2.5
Predictiony^=σ(−2.5)=1/(1+e2.5)\hat{y} = \sigma(-2.5) = 1/(1 + e^{2.5})≈0.076\approx 0.076

The model says "class 1 with probability 7.6%". Note what happened at the ReLU: the first hidden unit's pre-activation was negative, so it output exactly 0 and contributed nothing downstream — and, as backprop will make precise, no gradient will flow through it for this example either. The cached values xx, z(1)z^{(1)}, a(1)a^{(1)}, z(2)z^{(2)} are exactly what the backward pass consumes.

Parameter count, using layer shape dout×din+doutd_{\text{out}} \times d_{\text{in}} + d_{\text{out}}: layer 1 has 2×2+2=62 \times 2 + 2 = 6, layer 2 has 1×2+1=31 \times 2 + 1 = 3, so this network has 9 trainable parameters. The same bookkeeping at scale — count weights plus biases per layer, sum over layers — is a standard interview warm-up, and it is worth noticing that a batch of 64 such inputs would change none of it: parameters are shared across the batch, only the activation tensors grow.

Cheat sheet

TaskOutput headLoss
Regressionlinear (no activation)MSE / MAE / Huber
Binary classification1 logit + sigmoidbinary cross-entropy (with logits)
K-class, one labelK logits + softmaxcategorical cross-entropy (with logits)
Multi-labelK logits + K sigmoidsBCE per label