JOVANA
Explore Library Glossary Getting Started Three Levels Fields How it works Mission
Join the mission
All guides

From Pixels to a Neuron: The Smallest Learning Machine

Meet the artificial neuron — the tiny weighted-sum-and-squash unit that turns a grid of pixel numbers into the first spark of a decision.

Why vision needs a learning machine

In the earlier tracks you learned that a digital image is nothing mysterious — it is a grid of pixels, each a number, and that classical computer vision builds detectors out of hand-written rules: find edges where brightness jumps, threshold colors to pull out a red ball, slide a template across the image to match a shape. Those tools are genuinely useful, and you should keep them in your toolbox. But they share one fragile assumption: that you, the programmer, can spell out in advance exactly what the object looks like. The moment the lighting dims, the cat turns its head, the background gets cluttered, or the photo is taken from a new angle, the carefully tuned thresholds and templates quietly fall apart.

Here is the analogy worth holding onto. Imagine trying to teach a stranger over the phone to recognize a cat using only words: "it has pointed triangular ears, whiskers, fur, four legs, a tail…". You will never finish. A Sphynx cat has no fur. A folded-ear cat has no pointed ears. A sleeping cat shows no legs. Every rule you add needs ten exceptions, and the exceptions need exceptions. Hand-writing the rule for 'cat' is an infinite chore — and that is exactly the wall classical vision hits on hard, real-world images.

This whole track is built around a different bet. Instead of writing the rule ourselves, we will build a machine with a lot of internal numbers (we call them parameters) and then show it many labeled examples — pictures we have already marked as 'cat' or 'not cat'. The machine tunes its own numbers until its guesses match the labels. We stop dictating the rule and start dictating the goal; the rule is discovered automatically. The tiniest version of such a machine is a single artificial neuron, and building that one unit, piece by piece, is the entire job of this guide.

The goal: an input image goes in, and the machine outputs a label with a confidence — the rule that maps pixels to 'cat' is learned, not written.

A photo enters a box labeled 'classifier' and comes out as a category name with a probability score.

An image is just a tensor of numbers

Before a neuron can do anything with a picture, we have to remember what a picture is to a computer. A grayscale image is a 2D grid of brightness values, where each cell (each pixel) holds one number — conventionally from 0 (black) to 255 (white), with the in-between values being shades of gray. A color image is just three such grids stacked together: one for Red, one for Green, one for Blue. Mix those three intensities per pixel and you get any color on screen. There is nothing more to an image than these arrays of numbers.

Zoom in far enough and a grayscale image is literally a spreadsheet of numbers from 0 to 255.

A grayscale image magnified to show each pixel as a numeric brightness value in a grid.

We give these number-boxes a single tidy word: a tensor is just a box of numbers with a shape. The shape tells you how the numbers are arranged. A 28×28 grayscale digit (the famous MNIST format) is a tensor of shape (28, 28): 28 rows by 28 columns. A color photo is a tensor of shape (H, W, 3): height by width by three color channels. Don't let the fancy name intimidate you — for now, 'tensor' and 'a grid (or stack of grids) of numbers with a known shape' mean exactly the same thing. This idea has a glossary entry of its own: tensor representation.

A color image is three stacked grids — Red, Green, Blue — so its tensor shape is (H, W, 3).

A color photo separated into three layered grids labeled Red, Green, and Blue.

A neuron, though, wants its input as a single flat list — a one-dimensional vector — not a 2D grid. So we flatten: we read the grid out cell by cell, row by row, and lay the values down in one long line. Take the smallest interesting example, a tiny 2×2 grayscale patch with values a, b in the top row and c, d in the bottom row. Reading left-to-right, top-to-bottom gives the vector x = [a, b, c, d]. That's it — flattening is just 'unrolling the grid into a line'.

\begin{bmatrix} a & b \\ c & d \end{bmatrix} \;\longrightarrow\; \mathbf{x} = [\,a,\; b,\; c,\; d\,]

Flattening a 2×2 patch into a length-4 vector.

Read this map carefully, because everything downstream depends on it. On the left is the original 2×2 grid; on the right is the flat vector x. Each entry x_i is exactly one pixel's intensity: x_1 = a, x_2 = b, x_3 = c, x_4 = d. The vector's length n is just the total number of pixels: for an H×W grayscale image n = H × W, and for color you multiply by the channels, n = H × W × 3. A 28×28 digit therefore becomes a vector of length 28 × 28 = 784. The one phrase to lock in: 'pixel number i becomes input number x_i.' From this point on in the track, whenever we say 'an image' we really mean 'this long vector of numbers we can feed to a neuron.'

The artificial neuron: weighted sum plus bias

Now the star of the show. The artificial neuron is the atom out of which every network in this track is built — get this one unit, and you understand 90% of the machinery. Here is the picture to keep in your head: a neuron is a tiny voting panel. Each input pixel casts a vote, but votes are not equal — every pixel comes with a 'vote weight' that says how much that pixel matters, and whether it counts for the decision (a positive weight) or against it (a negative weight). The neuron tallies up all the weighted votes into a single score, then adds one extra constant — a baseline lean — called the bias.

Let's make it concrete with the smallest case: just two inputs. Suppose our flattened patch gave x = [x_1, x_2] = [0.8, 0.6] (two pixel intensities, scaled to the 0–1 range for tidiness). Suppose the neuron's weights are w = [w_1, w_2] = [0.5, -0.3] and its bias is b = 0.1. The first pixel is trusted (weight +0.5, counts in favor); the second pushes the other way (weight -0.3, counts against). We compute the weighted sum by hand: 0.5 × 0.8 = 0.40, then -0.3 × 0.6 = -0.18, and finally add the bias 0.1. Total: 0.40 − 0.18 + 0.10 = 0.32. That single number, 0.32, is the neuron's score for this input.

z \;=\; \mathbf{w}\cdot\mathbf{x} + b \;=\; \sum_{i=1}^{n} w_i\,x_i \;+\; b

The neuron's weighted sum (pre-activation score).

This is the same arithmetic you just did, written in general form. Symbol by symbol: x_i is the i-th input — one pixel value from the flattened image. w_i is that pixel's weight, a number whose size says how important the pixel is and whose sign says which way it pushes. The big Σ ('sum over i from 1 to n') is exactly the 'tally the weighted votes' step: it means w_1 x_1 + w_2 x_2 + … + w_n x_n. The dot w·x is just shorthand for that same sum. b is the bias, a constant lean added no matter what the inputs are — it shifts the whole score up or down, like a thumb on the scale. And z is the result: the pre-activation score, the neuron's raw opinion before we shape it. Plugging in our numbers — n = 2, w = [0.5, -0.3], x = [0.8, 0.6], b = 0.1 — gives z = (0.5)(0.8) + (-0.3)(0.6) + 0.1 = 0.32, exactly as before. The formula is nothing scarier than the multiply-add you can do on paper.

import numpy as np

# A single artificial neuron: weighted sum + bias, then an activation.
def neuron(x, w, b, activation):
    z = np.dot(w, x) + b      # pre-activation score: tally weighted votes, add lean
    return activation(z)      # final output a = g(z)  (next section)

def sigmoid(z):
    return 1.0 / (1.0 + np.exp(-z))

# Two pixel inputs, e.g. flattened from a tiny 1x2 patch, scaled to 0..1
x = np.array([0.8, 0.6])      # the x_i: pixel intensities
w = np.array([0.5, -0.3])     # the w_i: each pixel's learned weight (size + sign)
b = 0.1                       # the bias: a constant lean

z = np.dot(w, x) + b          # 0.5*0.8 + (-0.3)*0.6 + 0.1 = 0.32
print(z)                      # -> 0.32   (the raw score)
print(sigmoid(z))             # -> ~0.579 (squashed, previewed next section)
The whole neuron is one dot product plus a bias. Run it and you get z = 0.32, matching the hand calculation.
The neuron: inputs x_i each scaled by a weight w_i, summed, plus bias b, producing the score z.

A diagram of several inputs connecting through weighted edges into a single summing node that adds a bias and outputs z.

The activation function: adding the squash

Our score z is a fine start, but on its own it has a problem: it is purely linear. Double every input and (ignoring bias) z doubles too; the relationship is a flat, straight, proportional thing with no shape to it. Real decisions are rarely like that. A decision usually has a 'kick in' or a 'saturate' to it — below some level nothing happens, above it the answer turns on; or the answer is squeezed into a sensible range like 'a probability between 0 and 1.' To give the neuron that ability to bend, we pass z through an activation function: a fixed, non-linear shaper applied right after the weighted sum.

a = g(z)

The activation g turns the raw score z into the neuron's output a.

Read this as: take the pre-activation score z (the 0.32 we computed), feed it into a function g, and call the result a — the neuron's final output. The letter g is a placeholder for whichever shaper we pick; a is what actually leaves the neuron and gets passed onward (to the next layer, or out as the answer). The activation is the neuron's 'should I fire, and how strongly?' step: z is the raw tally of evidence, and a is the considered, shaped verdict. Two specific choices of g will follow you through this entire track, so let's meet both.

\sigma(z) = \dfrac{1}{1 + e^{-z}}

The sigmoid activation: squashes any z into the open interval (0, 1).

The sigmoid activation, written σ(z), squashes any real number into the range between 0 and 1, which makes its output read like a soft probability or a dimmer switch (not just on/off, but anything in between). The key piece is e^{-z}, where e ≈ 2.718 is a fixed constant. When z is very negative, −z is large and positive, so e^{-z} blows up huge; the denominator 1 + e^{-z} becomes enormous and the whole fraction is pushed toward 0. When z is large and positive, −z is large and negative, so e^{-z} shrinks toward 0; the denominator approaches 1 and σ(z) climbs toward 1. Right in the middle, at z = 0, we get e^0 = 1, so σ(0) = 1/(1+1) = 0.5. Plugging in our z = 0.32: e^{-0.32} ≈ 0.726, so σ(0.32) = 1/(1 + 0.726) ≈ 1/1.726 ≈ 0.579 — read as 'about 58% confident.' A strongly negative input like z = −2 gives σ(−2) ≈ 1/(1 + 7.39) ≈ 0.12, i.e. 'pretty confident: no.'

\mathrm{ReLU}(z) = \max(0,\, z)

The rectified linear unit: pass positives through, clamp negatives to zero.

The rectified linear unit, or ReLU, is even simpler and is the workhorse of modern vision. max(0, z) just means 'output the larger of 0 and z.' If z is positive, max(0, z) = z — it passes straight through, unchanged. If z is negative, max(0, z) = 0 — it gets clamped to zero. Think of it as a one-way valve: positive evidence flows freely, negative evidence is shut off entirely. For our z = 0.32, ReLU(0.32) = 0.32 (positive, so untouched). For z = −2, ReLU(−2) = 0 (negative, so silenced). Notice the contrast with sigmoid: sigmoid gently squeezes everything into (0,1), while ReLU leaves positives wide open and just kills negatives. Either way, the result is the neuron's final output a.

Sigmoid is a smooth S-curve flattening toward 0 and 1; ReLU is flat at zero for negatives then a straight ramp for positives.

Two plotted curves: an S-shaped sigmoid bounded between 0 and 1, and a ReLU that is zero for negative input then rises linearly.

A single neuron as a classifier — and its hard limit

Put the three pieces together — flatten the image into x, compute z = w·x + b, squash with a sigmoid — and you already have a working classifier. One artificial neuron with a sigmoid output reads any input and answers with a confidence between 0 and 1: outputs above 0.5 we call 'class 1' (say, 'cat'), outputs below 0.5 we call 'class 0' ('not cat'), and the exact value tells you how sure it is. The activation function is what makes that confidence reading possible. This is genuinely a complete, if tiny, machine-learning model.

To see what this classifier does, shrink the world to two pixel features, x_1 and x_2, so each image is just a dot on a 2D plane. Reusing w = [0.5, -0.3], b = 0.1, the neuron fires 'more cat' wherever the score z is positive and 'less cat' wherever z is negative. The frontier between the two — the exact set of points where the neuron is perfectly undecided — is where z = 0. On one side every point is pushed toward class 1; on the other side, toward class 0. The question is: what shape is that frontier?

\mathbf{w}\cdot\mathbf{x} + b = 0

The decision boundary: where the neuron's score is exactly zero.

This equation pins down the boundary. Points where w·x + b > 0 (that is, z > 0) sit on the class-1 side; points where w·x + b < 0 (z < 0) sit on the class-0 side; and the dividing line itself is exactly where it equals 0. With our numbers it reads 0.5·x_1 − 0.3·x_2 + 0.1 = 0. Solve for x_2 and you get x_2 = (0.5·x_1 + 0.1) / 0.3 — the equation of a straight line. And that is no accident: because w·x + b is linear in x (every x_i appears just once, multiplied by a constant, with nothing squared or multiplied together), the boundary is always a flat line in 2D, a flat plane in 3D, a flat hyperplane in general. A single neuron can only ever carve the input space with one perfectly straight cut.

A single neuron splits the plane with one straight line — points on each side get pushed toward one class.

A 2D scatter of points separated by a single straight decision line, one side shaded class 1 and the other class 0.

And here is the punchline that makes the rest of the track inevitable. A straight cut is wonderful when the two classes happen to fall on opposite sides of some line — but plenty of real patterns simply do not. The classic example is XOR: imagine class 1 sitting in the top-left and bottom-right corners, while class 0 sits in the top-right and bottom-left — two interleaved clusters arranged like a checkerboard. No single straight line can ever put both class-1 corners on one side and both class-0 corners on the other; try it and you always misclassify at least one cluster. This is the meaning of 'not linearly separable,' and it is the hard ceiling of a single neuron. The fix is the subject of guide 2: stack many neurons into layers, and their combined boundaries can bend, kink, and wrap around clusters that no straight line could ever separate. One brick has shown us its limit; next we build the wall.