45  AI: Neural networks

From neuron to network

A neural network is a set of neurons in which the outputs of some are the inputs of others. The neurons are arranged in layers, as in Figure 45.1.

x₁ x₂ h₁ h₂ h₃ y Input layer Hidden layer Output layer
Figure 45.1: A small feed-forward network. Every line carries a weight, and every hidden and output node has its own threshold and applies the activation function.

The input nodes hold the numbers you give the network: the brightness of each pixel in an image, say, or which base sits at each position of a DNA sequence. They compute nothing. They only pass their values on.

The hidden nodes are neurons of the kind described above. Each has its own weight on every incoming connection and its own threshold, and each applies the activation function to its net input. They are called hidden because, seen from outside, you only set the inputs and read the outputs. What happens in between is the network’s internal working. A network can have many hidden layers, each fed by the one before. A network with many of them is called deep, which is where the term deep learning comes from.

The output nodes are neurons too, and their values are the network’s answer. A yes-or-no question needs one output node. A network that predicts whether each residue of a protein sits in a helix, a strand or a coil might have three, one for each answer, and pick the one with the largest value.

Information flows one way, from the inputs through the hidden layers to the outputs, which is why this kind of network is called feed-forward. Computing the output means working through the layers in order, finding each neuron’s weighted sum and putting it through the activation function. It is the substitution and reduction you have practiced on Python expressions, with many more numbers.

The weights and thresholds together are the network’s parameters, and they are everything the network knows. The tiny network in the next chapter, with one input, three hidden nodes and one output, has ten: three weights into the hidden layer, three hidden thresholds, three weights into the output, and one output threshold. The language models behind AI assistants have billions, the largest hundreds of billions.

What a network can model

Think of a neuron with two inputs. It says yes when \(w_1x_1 + w_2x_2 \geq \theta\). If you draw every possible pair of inputs as a point on a sheet of paper, the points where \(w_1x_1 + w_2x_2\) equals \(\theta\) form a straight line. The neuron says yes on one side of that line and no on the other. With three inputs the line becomes a flat plane, but the idea is the same: a single neuron divides its inputs with a straight cut.

Many useful rules are a straight cut. With all weights equal to 1, a neuron with three yes/no inputs computes AND (“all three”) when the threshold is 2.5, “at least two” when it is 1.5, and OR (“at least one”) when it is 0.5. You will try this in the exercises. Some rules cannot be drawn with a straight cut, and the simplest is “exactly one of the two”. A staircase light with a switch at the top and one at the bottom should be on when exactly one switch is up. The last exercise in this chapter asks you to build that with a single neuron and explains why you cannot. This limitation was well known by the end of the 1960s, and for some years it made the perceptron look like a dead end.

A hidden layer fixes it. “Exactly one” is the same as “at least one, but not both”. Give the network two hidden neurons that each see both switches. The first, with weights 1 and 1 and threshold 0.5, computes “at least one”. The second, with weights 1 and 1 and threshold 1.5, computes “both”. The output neuron gets weight 1 from the first and −1 from the second, and threshold 0.5, so it says yes when the first hidden neuron is on and the second is off. Work through all four switch positions and you will find the lamp is on exactly when it should be. The hidden neurons re-described the input in terms that made the final decision easy. That is what hidden layers do in general. In a network trained to recognize images, early hidden neurons end up responding to edges and later ones to shapes made of edges, without anyone telling them to.

Networks are not limited to yes or no. Give a network one input \(x\) and a single hidden neuron with the step function, and plot the output against \(x\). The hidden neuron switches on where \(wx - \theta \geq 0\), that is where \(x\) passes \(\theta/w\), so the plot is a step at that point, and the output weight sets how tall the step is. Two hidden neurons give two steps, and one step up followed by one step down gives a bump. Enough bumps side by side can trace out any curve you like, as closely as you like. This result, that a single hidden layer with enough neurons can approximate any reasonable function, is called the universal approximation theorem (Cybenko, 1989; Hornik et al., 1989). You will build steps, bumps and staircases yourself in the next chapter. The theorem says that suitable weights exist. It says nothing about how to find them, or how many hidden neurons it will take.

Why neural networks are powerful

Finding the weights is the part that made neural networks what they are today. Throughout this course you have instructed the machine by writing out every step. A neural network is instructed in a different way. You give it examples, inputs paired with the correct outputs, and a training algorithm adjusts the weights a little at a time, each time in the direction that brings the network’s outputs closer to the correct ones. The standard algorithm, backpropagation, works out how much each weight contributed to the error (Rumelhart et al., 1986). It depends on small changes to a weight giving small changes to the output, which is why the step function had to give way to smooth activation functions. After many rounds of adjustment, the weights settle on values that make the network do the job. Nobody writes them down.

Three things together make this powerful. The building block is flexible: the same neurons, wired the same way, can compute very different things depending only on their weights, and with enough of them almost anything. The weights are learned from examples, so a network can do jobs that nobody knows how to write instructions for, such as recognizing a cat, predicting how a protein folds, or guessing the next word in a sentence. And all the arithmetic is multiplying and adding, which modern computers do extremely fast, so networks can have billions of parameters and learn from enormous collections of examples.

The same properties explain problems you have already met. A network learns whatever is in its examples, including their mistakes and biases. What it knows is spread across a vast number of weights, none of which means anything on its own, so you cannot read the weights to find out why it gave a particular answer. And it produces an answer for any input, including inputs unlike anything it was trained on, with no sign that it is out of its depth. This is why you check what the AI assistant produces, and why the same caution applies to every neural network.

A tiny network

Each exercise below has its own copy of the network, already set up for that exercise. You change one slider at a time. Before every change, decide what you expect to happen to the graph. Sketch it or write it down in one sentence. Only then change the slider and compare. If the graph does something else than you predicted, try to explain why before you open the answer.

In each interactive network, the input \(x\) goes to each hidden neuron \(h_i\), and the hidden neurons feed the output \(y\):

  • Hidden neuron: \(h_i = f(w_i x - \theta_i)\)
  • Output with “Apply \(f\) at output” disabled: \(y = v_1 h_1 + v_2 h_2 + v_3 h_3 - \theta\)
  • Output with “Apply \(f\) at output” enabled: \(y = f(v_1 h_1 + v_2 h_2 + v_3 h_3 - \theta)\)

With the “step” activation, \(f(z) = 1\) if \(z \geq 0\) and \(0\) otherwise. A hidden neuron with a positive weight therefore switches on where \(w_i x \geq \theta_i\), that is for \(x \geq \theta_i / w_i\).

NotePractical tips
  • “Reset” puts a network back to the start of its exercise.
  • All weights and thresholds go from −10 to 10. To set a slider to an exact value, click it and use the arrow keys: each press changes it by 0.1.
  • Move the mouse over the graph to choose an input \(x\); the network then shows the value of every neuron for that input.
  • “Show contributions” draws each hidden neuron’s contribution \(v_i h_i\) as a dashed line. Use it to check your reasoning.
  • The \(y\)-axis always runs from −25 to 25, so small values (like 1) give small changes in the graph.

Exercise 45-1

One step

One hidden neuron with the step activation, starting from “Flat”: all weights \(w\) are 1, all thresholds are 0 and the output weight \(v_1\) is 0, so the graph is flat at \(y = 0\).

A step: \(y = 0\) for \(x < 0\) and \(y = 10\) for \(x \geq 0\). The hidden neuron switches on where \(1 \times x - 0 \geq 0\), i.e. at \(x = 0\), and \(v_1\) sets the height of the step.

At \(x = 2\). The neuron now needs \(x - 2 \geq 0\). Increasing the threshold moves the step to the right.

At \(x = -3\): a negative threshold moves the step to the left.

The step now goes down: \(y = 0\) for \(x < -3\) and \(y = -10\) for \(x \geq -3\). The hidden neuron still switches on at the same place; a negative output weight turns its contribution upside down.

Everything moves up by 5: \(y = 5\) for \(x < -3\) and \(y = -5\) for \(x \geq -3\). The output threshold is subtracted from the output, so a negative \(\theta\) adds to it.


Exercise 45-2

What the input weight does

One hidden neuron with the step activation, starting from Flat with \(v_1 = 10\) and \(\theta_1 = 2\): a step up at \(x = 2\).

At \(x = 1\). The neuron switches on where \(2x - 2 \geq 0\), i.e. \(x \geq \theta_1/w_1 = 2/2 = 1\). A larger weight moves the step towards \(x = 0\).

At \(x = 4\) (\(\theta_1/w_1 = 2/0.5\)). A smaller weight moves the step away from \(x = 0\).

The step flips direction and moves to \(x = -2\): \(y = 10\) for \(x \leq -2\) and \(y = 0\) for \(x > -2\). The neuron now needs \(-x - 2 \geq 0\), i.e. \(x \leq -2\): with a negative weight, the neuron is on to the left of the switching point.

The graph is flat at \(y = 0\). With weight 0 the neuron ignores the input: its input is always \(0 - 2 = -2\), which is below 0, so it is never on.


Exercise 45-3

Building a bump from two steps

Two hidden neurons with the step activation, starting from Flat, with Show contributions ticked.

A step up from 0 to 10 at \(x = 0\), made by \(h_1\) alone.

The step becomes twice as high (\(0 \to 20\)), still at \(x = 0\). Both neurons switch on at the same place, so their contributions add up.

Two steps (a staircase): \(y = 0\) for \(x < 0\), \(y = 10\) for \(0 \leq x < 2\), and \(y = 20\) for \(x \geq 2\). The second neuron now switches on later.

A bump: \(y = 10\) for \(0 \leq x < 2\) and \(y = 0\) everywhere else. The first neuron steps up at 0, the second steps down by the same amount at 2, so they cancel to the right of 2.

It gets wider: it now runs from \(x = -2\) to \(x = 2\). Each threshold controls one edge of the bump.


Exercise 45-4

Moving the edges of a bump

The “Bump” example: a bump of height 10 between \(x = -1\) and \(x = 1\) (\(\theta_1 = -1\), \(\theta_2 = 1\), \(v_1 = 10\), \(v_2 = -10\)).

The bump disappears and the graph is flat at 0. Both neurons now switch on at \(x = 1\); the step up and the step down happen at the same place and cancel.

A dip: \(y = -10\) for \(1 \leq x < 3\) and 0 elsewhere. Now the step down (at 1) comes before the step up (at 3).

The step up at \(x = 3\) only goes half way back: \(y = 0\) for \(x < 1\), \(-10\) for \(1 \leq x < 3\), and \(5 - 10 = -5\) for \(x \geq 3\).

The whole graph moves up by 10: \(y = 10\) for \(x < 1\), \(0\) for \(1 \leq x < 3\), and \(5\) for \(x \geq 3\).


Exercise 45-5

A staircase

The “Staircase” example with three hidden neurons: steps at \(x = -3\), \(0\) and \(3\), each of height 6. The output threshold \(\theta = 9\) centres the levels on zero: −9, −3, 3, 9.

0, 6, 12 and 18: the whole staircase moves up by 9.

The middle step disappears: \(y = 0\) for \(x < -3\), \(6\) for \(-3 \leq x < 3\), and \(12\) for \(x \geq 3\). Neuron \(h_2\) still switches on at \(x = 0\), but its contribution is multiplied by 0.

At \(x = 0\) the graph now steps down by 6: \(0\) for \(x < -3\), \(6\) for \(-3 \leq x < 0\), \(0\) for \(0 \leq x < 3\), and \(6\) again for \(x \geq 3\).

The last step disappears from the graph: \(h_3\) would only switch on at \(x = 6\), which is outside the plotted range. What is left is a bump of height 6 between \(x = -3\) and \(x = 0\), just like in Exercise 3.


Exercise 45-6

Smooth steps with the sigmoid

One hidden neuron with the sigmoid activation, starting from Flat. The sigmoid is a smooth version of the step: \(f(z) = 1 / (1 + e^{-z})\), which is 0.5 at \(z = 0\).

A smooth S-shaped curve rising from almost 0 on the left to almost 10 on the right, passing through \(y = 5\) at \(x = 0\).

The curve becomes much steeper and looks almost like a step at \(x = 0\). The weight controls how sharp the transition is.

The curve becomes very gradual: it rises from about 0.8 at \(x = -5\) to about 9.2 at \(x = 5\).

At \(x = 2\) (\(\theta_1/w_1 = 1/0.5\)), just as for a step. The curve is shifted to the right.


Exercise 45-7

Ramps with ReLU

One hidden neuron with the ReLU activation, starting from Flat. ReLU is \(f(z) = \max(0, z)\): zero for negative input, and the input itself otherwise.

A ramp: \(y = 0\) for \(x < 0\) and \(y = x\) for \(x \geq 0\), reaching 5 at the right edge. The point where it bends is called a kink.

The ramp becomes five times steeper and reaches 25 (the top of the plot) at \(x = 5\).

The kink moves to \(x = 1\) (\(\theta_1/w_1 = 5/5\)), and the ramp \(y = 5x - 5\) reaches 20 at \(x = 5\).

The ramp now goes down from the kink at \(x = 1\), reaching −20 at \(x = 5\).


Exercise 45-8

A peak from two ramps

Two hidden neurons with the ReLU activation, starting from Flat, with Show contributions ticked.

A ramp from 0 at \(x = 0\) up to 25 at \(x = 5\) (slope 5).

The ramp goes down instead: both neurons bend at \(x = 0\), and the slopes add up to \(5 - 10 = -5\), so the graph reaches −25 at \(x = 5\).

A peak: the graph rises with slope 5 from \(x = 0\), reaches 10 at \(x = 2\), then falls with slope −5, crossing zero at \(x = 4\) and reaching −5 at \(x = 5\). The second neuron only starts pulling the graph down from \(x = 2\).

The output now also goes through ReLU, so negative values become 0: the graph is a clean triangle from \(x = 0\) to \(x = 4\) with its top (10) at \(x = 2\), and 0 everywhere else.


Exercise 45-9

A threshold on the output

The “Bump” example again. Tick “Apply f at output”, but before you do, predict what the graph will look like.

The graph becomes flat at \(y = 1\). Inside the bump the output neuron receives \(10 - 0 = 10\), outside it receives \(0\). Both are \(\geq 0\), so the step function gives 1 everywhere.

A bump of height 1 between \(x = -1\) and \(x = 1\), 0 elsewhere (it is small on this axis; hover over the graph to check the values). The output neuron now receives \(10 - 5 = 5\) inside the bump and \(-5\) outside, so it only fires inside.

The graph is flat at 0. Inside the bump the output neuron receives \(3 - 5 = -2\); outside it receives \(-5\) (left) or \(3 - 10 - 5 = -12\) (right). It never reaches its threshold.

The bump comes back: inside it receives \(3 - 2 = 1 \geq 0\), outside \(-2\) or \(-9\). Only the inputs inside the bump make the output neuron fire.


Exercise 45-10

Make a bump of height 8 that runs from \(x = -2\) to \(x = 3\).

\(w_1 = w_2 = 1\), \(\theta_1 = -2\), \(\theta_2 = 3\), \(v_1 = 8\), \(v_2 = -8\), \(\theta = 0\).


Exercise 45-11

Make a staircase going down: 10 for \(x < -1\), 0 between −1 and 1, and −10 for \(x \geq 1\).

\(w_1 = w_2 = 1\), \(\theta_1 = -1\), \(\theta_2 = 1\), \(v_1 = v_2 = -10\), and \(\theta = -10\) to lift the whole graph by 10.


Exercise 45-12

\(w_1 = 1\), \(w_2 = -1\), \(\theta_1 = \theta_2 = 0\), \(v_1 = v_2 = 5\), \(\theta = 0\). One neuron makes the right half of the V, the other (with a negative weight) the left half.