Skip to content
ZogleAGI Lab

Neural network fundamentals

Neural Networks From Zero: Two Tiny Examples, Every Step Explained

Where neural networks are used, why almost every use reduces to predicting a number or choosing a category, and how a single neuron learns both. Every term is defined before it is used, and every step is shown with real numbers.

15 min read

Neural Networks From Zero: Two Tiny Examples, Every Step Explained

Part 1: The big picture

Where neural networks are used

Real useWhat goes inWhat comes out
Price estimate for a housesize, rooms, location (numbers)a price (a number)
Spam filterfeatures of an email (numbers)spam or not spam
Face unlockpixel values of a photothis is you or not
Weather forecastpast temperatures, pressuretomorrow's temperature
Chat assistantthe words so far, as numbersthe next word

Every row has the same shape: numbers go in, a decision or a number comes out. Photos, text and sound all get converted to numbers first.

Two kinds of output

Look at the "comes out" column. There are only two kinds:

  1. A number. Price, temperature. This is called regression.
  2. A choice between categories. Spam or not, you or not, which next word. This is called classification. The simplest case is yes/no.

Even the chat assistant is classification: it chooses one word out of a list of thousands.

Why this article uses exactly these two

The two kinds of output need slightly different parts inside the network. If we understand one example of each, we understand the full picture. Everything else is a bigger version.

Example AExample B
KindRegression (output is a number)Classification (output is yes/no)
Datax=1,2,3→y=3,5,7x=1,2,3 \rightarrow y=3,5,7AND gate (below)
Hidden ruley=2x+1y = 2x+1output is 1 only when both inputs are 1

Why such tiny data

So that every number can be checked by hand. Real networks do exactly the same steps with millions of numbers.


Part 2: The problem: learning from examples instead of rules

Normally, a programmer writes the rule: "multiply by 2, add 1."

Here the rule is hidden. We only have examples, and the computer must find the rule.

Example A: examples

Input xxCorrect output yy
13
25
37

Example B: examples (AND gate)

Input 1Input 2Correct output
000
010
100
111

Words we will use:

  • Input: the numbers we give the model.
  • Output: the number the model gives back.
  • Target: the correct output from the examples. We write it yy in A and tt in B.
  • Prediction: what the model outputs. We write it y^\hat y in A and pp in B.

Part 3: What is a "model"?

A model is a rule with adjustable numbers inside it. Start with the simplest rule that can fit Example A:

y^=w⋅x+b\hat y = w \cdot x + b

The two adjustable numbers are called parameters:

  • ww (weight): multiplies the input. It controls how strongly the input affects the output.
  • bb (bias): added at the end. It shifts the output up or down regardless of input.

Why we need both

Try input x=2x=2 with different parameters:

wwbbOutput y^=2w+b\hat y = 2w+bCorrect is 5
000far
204close, still short by 1
215correct

With only ww, we could not get exactly 5 and also 3 and 7 for the other inputs. The bias gives the second adjustable number. Learning means finding the right ww and bb.

This is already a neuron

A neuron is this exact thing: take inputs, multiply each by its weight, add them up, add the bias. The result of that arithmetic is called the weighted sum, and we write it zz:

z=w1x1+w2x2+⋯+bz = w_1x_1 + w_2x_2 + \dots + b

For Example A there is one input, so z=wx+bz = wx+b. That is the entire neuron for regression.

Example B needs two changes

Change 1: two inputs. The AND gate has two inputs, so we have two weights:

z=w1x1+w2x2+bz = w_1x_1 + w_2x_2 + b

Change 2: the output must be a probability. For yes/no we want a number between 0 and 1 (0 = surely no, 1 = surely yes, 0.5 = unsure). But zz can be any number, like -7 or 13. We need something that converts any number into the range 0 to 1.

That something is called an activation function: a function applied to zz after the weighted sum. The one we use is sigmoid:

σ(z)=11+e−z\sigma(z) = \frac{1}{1+e^{-z}}

You do not need to memorise the formula. Look at what it does:

zz-4-2024
σ(z)\sigma(z)0.0180.1190.5000.8810.982

Large negative zz becomes close to 0. Zero becomes exactly 0.5. Large positive zz becomes close to 1. So sigmoid turns any number into a probability.

Example A has no activation function, because a price or a value can be any number.

Summary of the two neurons

Example AExample B
Weighted sumz=wx+bz = wx+bz=w1x1+w2x2+bz = w_1x_1+w_2x_2+b
Activationnonesigmoid
Predictiony^=z\hat y = zp=σ(z)p = \sigma(z)
Parametersw,bw, bw1,w2,bw_1, w_2, b

Part 4: The learning loop

Learning is the same 5-step loop in both examples:

  1. Forward pass: make a prediction with the current parameters.
  2. Loss: measure how wrong it is.
  3. Gradient: find which direction to change each parameter.
  4. Update: change the parameters in that direction.
  5. Repeat.

We will do one full pass of this loop by hand on one sample:

  • A: x=2x=2, target y=5y=5
  • B: x=(1,1)x=(1,1), target t=1t=1

Step 0: Starting values

All parameters start at 0.

Example AExample B
Parametersw=0, b=0w=0,\ b=0w1=0, w2=0, b=0w_1=0,\ w_2=0,\ b=0

Why start with wrong values? The model has not seen anything yet, so no values are known to be right. Any starting point works for a single neuron. (For bigger networks, starting values need to differ, but that is a later topic.)

Step 1: Forward pass

Forward pass means: push the input through the neuron to get a prediction. "Forward" because numbers flow from input to output.

Example AExample B
Weighted sumz=0⋅2+0=0z = 0\cdot2 + 0 = 0z=0⋅1+0⋅1+0=0z = 0\cdot1+0\cdot1+0 = 0
Predictiony^=0\hat y = 0p=σ(0)=0.5p = \sigma(0) = 0.5
Target51

Both predictions are wrong. But "wrong" is just a feeling. The computer needs a number that says how wrong. That is the next step.

Step 2: Loss

The loss is a single number measuring how far the prediction is from the target. Lower is better, and 0 means perfect.

Example A: squared error

L=(y^−y)2L = (\hat y - y)^2

Our values: (0−5)2=25(0-5)^2 = 25.

Why squared? Two reasons. The difference could be negative (predicting 8 when the target is 5 gives -(-3)), and squaring makes it positive. Squaring also makes big mistakes count much more than small ones: off by 1 costs 1, off by 4 costs 16.

Loss for sample x=2,y=5x=2, y=5 with b=0b=0 and different ww:

ww01234
Prediction 2w2w02468
Loss259119

The loss is lowest near w=2.5w=2.5 (where the prediction would be exactly 5). That is where we want to end up.

Example B: binary cross-entropy

L=−[tln⁡p+(1−t)ln⁡(1−p)]L = -[t\ln p + (1-t)\ln(1-p)]

When the target is t=1t=1, this becomes L=−ln⁡pL = -\ln p. Look at what it does:

Prediction pp (target is 1)0.990.90.50.10.01
Loss −ln⁡p-\ln p0.0100.1050.6932.3034.605

If the model is confident and right, loss is tiny. If it is unsure (0.5), loss is 0.693. If it is confident and wrong (0.01 when the answer is 1), loss is huge.

Why not use squared error here too? Cross-entropy punishes confident wrong answers much harder, which is exactly the mistake a classifier must avoid. It also gives better learning signals with sigmoid (this shows up in Step 3).

Our values: −ln⁡(0.5)=0.693-\ln(0.5) = 0.693. This is the loss of a pure coin flip. The model knows nothing yet.

Step 3: Gradient

Now we know how wrong the model is. The question is: how should we change ww and bb to reduce the loss?

We could try every possible value, but with millions of parameters that is impossible. Instead we use the gradient.

What the gradient is. The gradient of the loss with respect to a parameter says: if I increase this parameter a tiny bit, how much does the loss change? It is the slope.

Check with real numbers (Example A). Current w=0w=0, loss 25. Increase ww by 0.01:

w=0w=0w=0.01w=0.01
Prediction 2w2w00.02
Loss25(0.02−5)2=24.8004(0.02-5)^2 = 24.8004

Loss changed by −0.1996-0.1996 for a change of +0.01+0.01, so the slope is about −0.1996/0.01=−19.96-0.1996/0.01 = -19.96, roughly -20.

  • A negative gradient means: increasing the parameter decreases the loss. So increase it.
  • A positive gradient means the opposite: decrease the parameter.
  • A large gradient means the loss is very sensitive to that parameter.

We can get this exactly, without trying values, using the chain rule:

If A depends on B, and B depends on C, then how fast A changes with C = (how fast A changes with B) × (how fast B changes with C).

In our case, loss depends on the prediction, and the prediction depends on ww.

Example A

LinkCalculationValue
Loss changes with prediction2(y^−y)=2(0−5)2(\hat y - y) = 2(0-5)-10
Prediction changes with wwy^=wx+b\hat y = wx+b, so slope is xx2
Prediction changes with bbslope is 11
Gradient for ww−10×2-10 \times 2-20
Gradient for bb−10×1-10\times 1-10

The -20 matches our hand-check of about -19.96.

Example B

LinkCalculationValue
Loss changes with zzfor sigmoid with cross-entropy this simplifies to p−t=0.5−1p-t = 0.5-1-0.5
zz changes with w1w_1slope is x1x_11
zz changes with w2w_2slope is x2x_21
zz changes with bbslope is 11
Gradients−0.5×1-0.5\times1 each-0.5, -0.5, -0.5

The pattern. In both examples:

gradient of a weight=(error signal)×(input that weight multiplies)\text{gradient of a weight} = (\text{error signal}) \times (\text{input that weight multiplies})

A's error signal is 2(y^−y)2(\hat y - y) and B's is p−tp-t. The rest is identical. That is why the same learning method works for both. (The sigmoid + cross-entropy pair is chosen so the error signal is the clean p−tp-t.)

Why input matters. If an input is 0, its weight gets gradient 0. That weight did not contribute to the prediction, so it is not blamed.

Step 4: Update

Move each parameter against its gradient (opposite direction, since the gradient points toward higher loss):

parameter←parameter−lr×gradient\text{parameter} \leftarrow \text{parameter} - \text{lr} \times \text{gradient}

Learning rate (lr) is a number we choose. It controls how big a step we take.

Example A (lr = 0.01)Example B (lr = 1)
ww0−0.01⋅(−20)=0.20 - 0.01\cdot(-20) = 0.2w1=0−1⋅(−0.5)=0.5w_1 = 0-1\cdot(-0.5) = 0.5, w2=0.5w_2 = 0.5
bb0−0.01⋅(−10)=0.10 - 0.01\cdot(-10) = 0.10−1⋅(−0.5)=0.50 - 1\cdot(-0.5) = 0.5

Why not just jump straight to the answer? The gradient only tells the local slope, not the exact destination. A step too large overshoots. Example A with lr = 0.3 instead of 0.01:

Value
New ww0−0.3⋅(−20)=60 - 0.3\cdot(-20) = 6
New bb0−0.3⋅(−10)=30 - 0.3\cdot(-10) = 3
New prediction6⋅2+3=156\cdot2+3 = 15
New loss(15−5)2=100(15-5)^2 = 100, worse than the starting 25

Too small a learning rate learns very slowly. Too large overshoots. It is a number you tune.

Step 5: Check that it worked

Run the same sample again with the new parameters.

Example AExample B
New weighted sum0.2⋅2+0.1=0.50.2\cdot2+0.1 = 0.50.5+0.5+0.5=1.50.5+0.5+0.5 = 1.5
New prediction0.5σ(1.5)=0.818\sigma(1.5) = 0.818
Target51
New loss(0.5−5)2=20.25(0.5-5)^2 = 20.25−ln⁡(0.818)=0.201-\ln(0.818) = 0.201
Old loss250.693

Both losses dropped after one update. That is the whole idea.


Part 5: Repeating on all the data

One step on one sample only improves that sample. The real loop does this:

  1. Run every sample through the model.
  2. Compute the gradient for each sample, then average them.
  3. Update the parameters once using that average.
  4. Repeat.

Why average? If the update followed only one sample, it could damage the others. The average moves in a direction that helps the whole dataset.

One full pass over all samples is called an epoch.

Example A (lr = 0.05, 3 samples)

EpochwwbbLoss
11.1330.5005.489
52.0060.8890.0098
202.0350.9210.0009
1002.0130.9700.00013
2002.0040.9910.00001

Hidden rule was w=2,b=1w=2, b=1. The model reached w=2.004w=2.004, b=0.991b=0.991 without being told.

Notice the loss falls fast at first and then slowly. As the model gets close, gradients get smaller, so steps get smaller.

Example B (lr = 1, 4 samples)

Epochw1=w2w_1=w_2bbLossOutputs for (0,0), (0,1), (1,0), (1,1)
10.000-0.2500.6380.438, 0.438, 0.438, 0.438
100.514-1.2630.4600.221, 0.321, 0.321, 0.442
1003.049-4.7910.1430.008, 0.149, 0.149, 0.787
10007.414-11.2940.0170.000, 0.020, 0.020, 0.972

Look at epoch 1: the weights did not move, only the bias did. Sample (1,0) pushes w1w_1 down and sample (1,1) pushes it up by the same amount, so the average cancels. After the bias changes, the outputs differ and the weights begin to move.


Part 6: Using the trained model

Example A: feed x=4x=4, a value the model never saw.

Prediction: 2.004⋅4+0.991=9.0072.004\cdot4+0.991 = 9.007. The correct answer is 9. The model learned the rule, not a lookup table.

Example B: outputs after training are 0.000, 0.020, 0.020, 0.972. Choose a threshold of 0.5 (above it we say yes, below it no). That gives 0, 0, 0, 1, which is exactly the AND gate.


Part 7: Same and different

PartSame in A and B?Why
Weighted sumSameboth combine inputs with weights and a bias
ActivationDifferentA's output can be any number; B's must be a probability
LossDifferentA measures distance; B measures confident mistakes
Gradient pattern (error × input)Samethe chain rule works the same way
Update ruleSamestep against the gradient
Learning rateDifferenttuned per problem

Part 8: What a single neuron cannot do

A single neuron separates the data with one straight line. AND is separable by one line. XOR (output 1 when inputs differ) is not. To solve XOR, we stack neurons into layers, where the first layer's outputs become the second layer's inputs. The same loop still trains it, only the chain rule gets longer. The follow-up experiment tests this.

Glossary

TermMeaning
Parameteran adjustable number inside the model
Weighta parameter multiplying one input
Biasa parameter added at the end
Weighted sum (zz)inputs × weights, added up, plus bias
Activation functionfunction applied to zz (e.g. sigmoid)
Predictionthe model's output
Targetthe correct output
Lossone number: how wrong the prediction is
Gradientslope of the loss with respect to a parameter
Learning ratesize of each update step
Epochone pass over all training samples
Regressionpredicting a number
Classificationpredicting a category

Full code

python
import numpy as np
sig = lambda z: 1/(1+np.exp(-z))

# Example A: regression, y = 2x + 1
x = np.array([1, 2, 3.]); y = np.array([3, 5, 7.])
w = b = 0.; lr = 0.05
for epoch in range(200):
    p = w*x + b                      # forward pass
    d = 2*(p - y)/len(x)             # error signal, averaged
    w -= lr*(d*x).sum()              # gradient = error x input, then update
    b -= lr*d.sum()
print(w, b, w*4 + b)

# Example B: AND gate
X = np.array([[0,0],[0,1],[1,0],[1,1.]]); t = np.array([0,0,0,1.])
w = np.zeros(2); b = 0.; lr = 1.
for epoch in range(1000):
    p = sig(X@w + b)                 # forward pass
    d = (p - t)/4                    # error signal, averaged
    w -= lr*X.T@d                    # gradient = error x input, then update
    b -= lr*d.sum()
print(w, b, sig(X@w + b).round(3))

Try: change lr to 0.3 in Example A and watch the loss blow up, like the overshoot table in Step 4.

  • neural networks
  • regression
  • classification
  • gradient descent
  • loss
  • beginner

More from the lab

  • Cover image for “Gradient Descent: The One Loop Behind Every AI, From a Tiny Model to an LLM”

    Gradient Descent: The One Loop Behind Every AI, From a Tiny Model to an LLM

    Gradient descent is the loop that trains almost every AI model, including large language models. We run it on two tiny examples with real numbers: finding one best number, and teaching a model to pick the right next word. Then we see what changes when the same loop is scaled up to an LLM.

    9 min read

  • Cover image for “What Is a Neuron? Trying 7 Kinds on 3 Tiny Puzzles”
    Experiment · EXP-001

    What Is a Neuron? Trying 7 Kinds on 3 Tiny Puzzles

    A neuron is a tiny calculator: it takes numbers in, adds them up with weights, and gives one number out. We try 7 kinds of neuron, from the simplest to a small group of neurons, on three tiny puzzles (AND, OR, XOR). The kind of neuron barely mattered. What mattered was having more than one neuron working together.

    6 min read

    FoundationalCompleted