Skip to main content
Back to module
Applied Machine Learning · Neural Networks

Neural network basics

Reading51mLesson 1 of 3 in this module

What you'll learn

  • Train a small two-layer neural network
  • Write the forward pass of a network as matrix multiplications plus activations
  • Explain backpropagation as the chain rule applied layer by layer
  • Check gradients numerically and explain why random initialisation breaks symmetry

Build a two-layer neural network in NumPy, write its backward pass and train it to solve XOR.

Why this matters

Linear and logistic regression draw straight boundaries. Many real problems need curved ones: the pixels of a handwritten digit, the words in a sentence, the interaction between two sensor readings. A neural network learns those curved boundaries by stacking simple layers. The same few ideas (layers, activations, a loss, backpropagation and gradient descent) power everything from a two-layer model on a spreadsheet to a large language model. In this lesson you build the smallest useful network by hand so the frameworks in the next lessons stop being magic.

The core idea: layers of weighted sums

A single neuron takes inputs x, computes a weighted sum plus a bias, then applies a non-linear activation function:

z = w1*x1 + w2*x2 + ... + b
a = activation(z)

A layer is many neurons side by side, which is one matrix multiplication. A two-layer network for binary classification looks like this:

hidden:  h = tanh(X @ W1 + b1)        X is (n, d), W1 is (d, k), h is (n, k)
output:  p = sigmoid(h @ W2 + b2)     W2 is (k,), p is (n,), each p in (0, 1)

The hidden layer turns each row into k new features, and the output layer is just logistic regression on those learned features. That is the key insight: the network learns its own features.

Why the activation? Without it, two layers collapse into one: (X @ W1) @ W2 equals X @ (W1 @ W2), still a straight line. tanh, sigmoid and ReLU (max(0, z)) bend the space so the next layer can separate classes a line cannot.

The loss and the backward pass

For binary labels we use binary cross-entropy, the same loss as logistic regression:

loss = -mean( y*log(p) + (1-y)*log(1-p) )

Training means nudging every weight against its gradient. Backpropagation is the chain rule applied layer by layer, from the output back to the input. For the network above the gradients are:

dz2 = (p - y) / n                    error signal at the output, shape (n,)
dW2 = h.T @ dz2                      db2 = sum(dz2)
dh  = outer(dz2, W2) * (1 - h**2)    (1 - h**2) is the derivative of tanh
dW1 = X.T @ dh                       db1 = dh.sum(axis=0)

The (p - y) term is neat: with sigmoid plus cross-entropy, the derivative simplifies to "prediction minus truth". Each layer multiplies the incoming error by its local derivative and passes it back.

Worked example: XOR

XOR is the classic problem a straight line cannot solve. The label is 1 when two inputs have the same sign:

x0x1label
0.80.61
-0.7-0.41
0.5-0.90
-0.60.30

Logistic regression tops out near 50% accuracy here. A network with 8 hidden tanh units learns to combine several tilted lines into a checkerboard boundary and reaches above 95%. A full training loop in NumPy is short:

Python
for epoch in range(3000):
    h, p = forward(X, params)          # forward pass
    grads = backward(X, y, h, p, params)
    for k in params:                   # gradient descent step
        params[k] -= lr * grads[k]

Checking your gradients

Backprop bugs are silent: the code runs and the loss just falls slowly or not at all. The standard defence is a numerical gradient check. Nudge one weight by a tiny eps up and down, measure the loss each time, and compare:

numerical = (loss(w + eps) - loss(w - eps)) / (2 * eps)

If that matches your analytic gradient to about six decimal places, your backward pass is right. Frameworks such as PyTorch compute gradients automatically (autograd), so you rarely do this at work, but it is the best way to understand what autograd does.

Initialisation matters

If every weight starts at zero, every hidden unit computes the same thing and receives the same gradient, so they never become different. This is the symmetry problem. Networks start from small random weights, usually scaled by the layer size (Xavier/Glorot or He initialisation). Fix the random seed while you learn so your results are reproducible.

Common mistakes

  • Forgetting the activation. Stacked linear layers are still linear.
  • Shape errors. Write the shape of every array in a comment, as above. Most bugs are a missing transpose.
  • Learning rate too high. The loss jumps around or becomes nan. Halve it until the loss falls smoothly.
  • Unscaled inputs. Features on very different scales make training slow. Standardise inputs first (mean 0, standard deviation 1).
  • Judging by training accuracy alone. A network can memorise training data. The next lesson covers validation curves.

Quick recap

  • A layer is a matrix multiplication plus bias followed by a non-linear activation.
  • Hidden layers learn features; the output layer turns them into a prediction.
  • Backpropagation is the chain rule, layer by layer, from the loss back to each weight.
  • Gradient checks catch backprop bugs; random initialisation breaks symmetry.

Try it

Open the Do tab. You will write the forward and backward passes of a two-layer network in NumPy, pass a numerical gradient check, and train it to solve XOR.

Key terms (5)

activation
A non-linear function such as tanh, sigmoid or ReLU applied after a weighted sum, so stacked layers can learn curved boundaries.
binary cross-entropy
The loss for binary labels: -mean(y*log(p) + (1-y)*log(1-p)), the same loss as logistic regression.
Backpropagation
The chain rule applied layer by layer from the loss back to each weight to compute gradients.
numerical gradient check
Comparing an analytic gradient with (loss(w + eps) - loss(w - eps)) / (2 * eps) to catch backprop bugs.
symmetry problem
If all weights start equal, every hidden unit computes and learns the same thing; random initialisation avoids it.

Recap

  • A layer is a matrix multiplication plus a bias, followed by a non-linear activation.
  • Without activations, stacked layers collapse into one linear model.
  • Hidden layers learn features; the output layer turns them into a prediction.
  • Backpropagation is the chain rule from the loss back to each weight; with sigmoid plus cross-entropy the output error is p - y.
  • Gradient checks catch backprop bugs, and small random initial weights break symmetry.
Also in this lesson: