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 :
- is the previous layer's output (with , the input),
- and are the layer's learned weights and biases,
- is an elementwise nonlinearity such as ReLU,
- is called the pre-activation and the activation.
Two things make this composition interesting. First, the nonlinearity: without , the whole stack collapses into one affine map, so a 1000-layer linear network is exactly a linear model. Second, the caching: every intermediate (and often ) 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 for a distribution over classes.
In practice everything is batched: inputs are stacked into a matrix of shape , 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
Push through it:
| Step | Computation | Result |
|---|---|---|
| Pre-activation 1 | ||
| Pre-activation 2 | ||
| Hidden ReLU | ||
| Output logit | ||
| Prediction |
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 , , , are exactly what the backward pass consumes.
Parameter count, using layer shape : layer 1 has , layer 2 has , 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
- Layer: , . has shape — parameters per dense layer: .
- Batch form: is , layer computes → . Bias broadcasts over the batch dimension.
- No nonlinearity → no depth: any stack of affine layers equals one affine layer.
- Softmax: ; subtract first for numerical stability (frameworks do this for you).
| Task | Output head | Loss |
|---|---|---|
| Regression | linear (no activation) | MSE / MAE / Huber |
| Binary classification | 1 logit + sigmoid | binary cross-entropy (with logits) |
| K-class, one label | K logits + softmax | categorical cross-entropy (with logits) |
| Multi-label | K logits + K sigmoids | BCE per label |
- Memory: training caches every layer input for backprop → activation memory scales with batch size × network width × depth; inference does not.
- Train vs eval mode: dropout on / batch-norm batch-stats during training; dropout off / running stats at eval. Forgetting to switch is a classic silent bug.
- Gotcha: compute losses from logits (fused log-sum-exp), never
log(softmax(z))by hand. - Gotcha: a ReLU unit that outputs 0 passes zero gradient — visible already in the forward pass as inactive units.