Vocabulary for this course

The terms the chapters assume, in plain words. You can open this from any chapter.

activation
A rule applied to each number in a layer that lets the network bend, rather than only scale and add.
autograd
Software that records operations during a forward pass and later computes their gradients automatically.
backpropagation
Working backwards through a network to find how each weight affects the loss, by multiplying local slopes.
batch
A group of examples processed together in one step, averaged into a single update.
epoch
One full pass over the training examples.
forward pass
Running inputs through a network to produce outputs, before any error is measured.
gradient
The direction and steepness in which a value rises fastest; training moves weights the opposite way.
learning rate
How far each update moves the weights; too large overshoots, too small crawls.
loss
One number saying how wrong the current predictions are, which training tries to reduce.
optimiser
The procedure that uses gradients to decide how each weight changes.
overfitting
When a network memorises accidental details of its training examples and does worse on new ones.
regularisation
Any penalty or limit that discourages a network from chasing noise in its training examples. The aim is better performance on new data.
tensor
A nested list of numbers with a shape that says what each axis means.

Deep learning from the ground up

The forward pass

A layer is a matrix multiply, a bias and a nonlinearity. Stack them and the nonlinearity is the only reason the stack is more than one big matrix.

Part 2 of 10

Intermediate15 min readBack to Courses

A layer is three operations

A dense layer takes a vector, multiplies it by a weight matrix, adds a bias vector, and passes the result through an activation. It is dense because every input connects to every output. The activation is a fixed nonlinear function, and the parameters are the numbers training adjusts. If the input has three features and the output has two, the matrix is two by three. The bias then has two entries, and the whole layer has eight parameters. A batch of inputs turns the vector into a matrix. The same weight matrix is reused for every row.

The linear part changes basis: it projects the input onto a new set of directions. The bias shifts the origin. That shift matters because many datasets are not centred on it. Without a bias, every boundary has to pass through zero. The activation then bends the result. All three parts are necessary, and only one of them is nonlinear.

The parameter count is the other thing to read from the shape. A layer with four inputs and eight outputs has thirty-two weights and eight biases. The activations are not parameters, but they are the memory. When a model is too large, the number that matters is usually the activation count, not the weight count.

Why the nonlinearity is the point

Without an activation, two layers collapse into one. The composition of two linear maps is another linear map. A hundred stacked matrices therefore have exactly the expressive power of a single matrix. The parameters are wasted, the depth is cosmetic, and the model still cannot represent an XOR. XOR is true when exactly one of two inputs is true.

ReLU is the default because it is cheap. The name is short for rectified linear unit, and it returns the input when it is positive and zero otherwise. Its gradient, the slope of the output with respect to the input, is either zero or one. Sigmoid and tanh saturate: for a large positive or negative input, the derivative is almost zero. The gradient that reaches earlier layers is then tiny, which is the vanishing gradient problem in its simplest form. ReLU avoids it on the positive side, at the cost of units that can get stuck at zero.

GELU and SiLU are smooth alternatives. They behave like ReLU for large inputs and like a soft gate near zero. They cost more to evaluate, and they often buy a small accuracy gain in large models. For a first network the choice barely matters. What matters is that there is a nonlinearity at all, and that it comes after the linear part rather than before it.

A stack in PyTorch

import torch
from torch import nn

model = nn.Sequential(
    nn.Linear(4, 8),
    nn.ReLU(),
    nn.Linear(8, 3),
)

x = torch.randn(16, 4)
logits = model(x)
print(logits.shape)                                  # (16, 3)
print(sum(p.numel() for p in model.parameters()))    # 67

One dense layer, by hand

Run the layer, then change the first bias from 0.1 to 2.0 and watch the dead unit come alive. Print the pre-activation so you can see where the bend happens.

Output
Click "Run" to execute your code

Logits, probabilities and decisions

The last layer usually returns logits: raw scores, one per class, with no normalisation. They are not probabilities, and they do not need to be. The loss function applies the softmax internally. Softmax turns scores into a distribution that sums to one, and the fused form is numerically stable. The prediction is the argmax, which picks the largest score and does not care about normalisation at all.

Only at inference, when a human reads the output, do you turn logits into probabilities. Doing it inside the model is a common mistake. The loss then receives probabilities and applies a second softmax, which flattens the distribution and slows learning. Keep the model linear at the end, and let the loss own the transformation.

Temperature is the exception that proves the rule. Dividing logits by a temperature before the softmax sharpens or flattens the distribution. That is useful for calibration and for sampling. It is a post-hoc operation, though, not a layer the loss expects. If you add it, keep it out of the training graph unless you have a reason.

If a deep model trains no better than a single linear layer, check the activations before anything else. A missing nonlinearity is silent: the shapes fit, the loss falls, and the model can only draw a line.

The forward pass is also a cache

Training keeps every intermediate activation. The backward pass needs it to compute the local gradient. That cache is why activation memory grows with depth and batch size. It is also why the largest batch a GPU can hold is often set by activations rather than by weights. Inference does not need the cache, and torch.no_grad() switches it off.

Initialisation is part of the forward pass too. Initialisation means the starting values of the weights. If every weight is drawn from a distribution whose variance ignores the layer width, the signal shrinks or explodes as it travels. He initialisation scales by the fan-in for ReLU, where fan-in is the number of inputs to a unit. Xavier scales for tanh. A network with a bad init can look broken before the first update.

A quick check is to print the mean and standard deviation of each layer’s output on a random batch. If they collapse toward zero by the last layer, or explode past a few units, the initialisation or the normalization is wrong. Fix that before training. It saves a day of tuning a model that could never have learned.

Depth without a bend

Compare the two-layer linear network with its collapsed single matrix, then add ReLU between the layers and watch the outputs diverge.

Output
Click "Run" to execute your code

Check what you learned

One question at a time. A wrong answer explains itself — take another go.

Part 1 of 5

A dense layer maps 6 inputs to 4 outputs. What shape is its weight matrix?