Deep Learning 📂 Deep Learning Introduction · 2 of 3 22 min read

The Biological Neuron & McCulloch-Pitts Model

How a 1943 neuron sketch became the blueprint for every modern AI

Section 01

The Story That Started Everything

The Telegram That Changed Neuroscience
In 1943, a neurologist (Warren McCulloch) and a 17-year-old self-taught logician (Walter Pitts) published a paper called "A Logical Calculus of Ideas Immanent in Nervous Activity." Nobody had Wi-Fi, nobody had Python. They just had pencils, logic gates, and a burning question:

Can a brain cell be modelled as a mathematical function?

Their answer was yes — and it planted the seed for every neural network, every LLM, every self-driving car that exists today. It all starts with one humble biological cell.

Before building artificial neurons, we need to understand the real one. The biological neuron is the fundamental unit of the nervous system. The human brain contains roughly 86 billion of them, each connected to thousands of others — forming the most complex information-processing system we know of.


Section 02

Anatomy of a Biological Neuron

A neuron has three functional zones, each with a precise mathematical counterpart in the McCulloch-Pitts model. Understanding this mapping is the entire point of this tutorial.

🌿
Dendrites
Input receivers
Branch-like extensions that receive chemical signals from other neurons. Each dendrite connection has a different synaptic strength — some amplify signals, some suppress them. This is the biological origin of weighted inputs.
🔵
Soma (Cell Body)
Summation unit
The central hub. It collects all the signals coming in from the dendrites and adds them up. If the total crosses a threshold, it fires. If not, it stays silent. Pure accumulation — the biological weighted sum.
Axon
Binary output
The long "wire" that carries the neuron's decision to the next cell. It either fires an action potential (1) or it doesn't (0). No half-measures. This is the biological step activation function.
🧠 Biological Neuron → McCulloch-Pitts Mapping
w₁ = 0.8 w₂ = 0.4 w₃ = −0.5 w₄ = 1.0 x₁ x₂ x₃ x₄ SOMA Σ(wᵢxᵢ) + b weighted sum sum Threshold θ (theta) fire? Output 0 or 1 DENDRITES weighted inputs SOMA summation AXON binary output

Each dendrite carries a weighted input → soma sums them → axon fires if the sum exceeds threshold θ.


Section 03

The McCulloch-Pitts Neuron — The Maths

The Voting Committee
Imagine a committee of voters (inputs). Each voter carries a different weight of influence — a senior partner's vote counts as 0.8, an intern's as 0.2, and a dissenter's as −0.5. The chairman (soma) tallies all the weighted votes. If the total exceeds a quorum (threshold θ), the motion passes and the committee sends a "YES" signal down the wire (axon = 1). Otherwise, silence (axon = 0).

That's the entire McCulloch-Pitts model. No backprop, no learning — just logic hardwired into biology.

The McCulloch-Pitts neuron computes two things in sequence:

Step 1 — Weighted Sum
z = Σ(wᵢ · xᵢ) + b
Each input xᵢ is multiplied by its weight wᵢ. A bias b shifts the threshold. Sum everything together.
Step 2 — Step Activation
y = 1 if z ≥ θ, else 0
If the weighted sum z meets or exceeds the threshold θ, the neuron fires (output = 1). Otherwise it stays silent (output = 0).
💡
Why This Was Revolutionary in 1943

McCulloch and Pitts showed that a network of such neurons could compute any logical function — AND, OR, NOT, XOR. They proved a biological brain cell could, in principle, perform digital logic. This was the first mathematical proof that thought could be computed.


Section 04

Biological Parts → Model Parts

Biological Part Function in Nature MP Model Equivalent Modern DL Term
🌿 Dendrites Receive signals from other neurons x₁, x₂, … xₙ (inputs) Input features
🔗 Synapse Controls signal strength between cells w₁, w₂, … wₙ (weights) Trainable weights
🔵 Soma Accumulates all incoming signals z = Σ(wᵢxᵢ) + b Linear transformation
⚖️ Threshold Decides if the cell fires y = step(z − θ) Activation function
Axon Transmits the decision (fire/no fire) y ∈ {0, 1} Neuron output

Section 05

A Worked Example — AND Gate

Let's wire a McCulloch-Pitts neuron to behave like a logical AND gate. It should fire only when both inputs are 1.

🔧 Designing the AND Neuron
Inputs
x₁ and x₂ — each is 0 or 1
Weights
w₁ = 1, w₂ = 1 (equal influence)
Threshold
θ = 2 (both must vote yes)
Rule
Fire if z = w₁·x₁ + w₂·x₂ ≥ θ
x₁x₂ z = 1·x₁ + 1·x₂ z ≥ 2 ? Output y AND Truth
000 No00 ✓
011 No00 ✓
101 No00 ✓
112 Yes11 ✓
🎯
Perfect AND gate — with a single neuron

By choosing weights = 1 and threshold = 2, we've hardwired logic into biology. Change θ to 1 and you get an OR gate. Flip a weight to −2 and add threshold −1 and you get NOT. McCulloch and Pitts proved all of propositional logic can be expressed this way.


Section 06

Inhibitory Inputs — The Biological Veto

The Bouncer at the Door
In a real brain, some synapses are inhibitory — they actively suppress the neuron from firing. Think of a nightclub bouncer. No matter how many people are pushing to get in (excitatory inputs), if the bouncer says no (inhibitory input = 1), the door stays shut. McCulloch and Pitts modelled this with negative weights. An inhibitory signal with w = −10 will crush any sum, vetoing the neuron entirely.
✅ Without Inhibition
InputWeightContribution
x₁ = 1+1+1
x₂ = 1+1+1
z = 2Fires (θ=1.5)
🚫 With Inhibitory Input
InputWeightContribution
x₁ = 1+1+1
x₂ = 1+1+1
x₃ = 1−10−10
z = −8Silent

Section 07

Python Implementation

Basic McCulloch-Pitts Neuron

import numpy as np

def mcculloch_pitts(inputs, weights, threshold):
    """
    A single McCulloch-Pitts neuron.
    inputs    : list/array of binary inputs  [x1, x2, ...]
    weights   : list/array of synaptic weights [w1, w2, ...]
    threshold : firing threshold θ
    returns   : 1 (fire) or 0 (silent)
    """
    inputs  = np.array(inputs,  dtype=float)
    weights = np.array(weights, dtype=float)

    z = np.dot(weights, inputs)        # soma: weighted sum
    y = 1 if z >= threshold else 0    # axon: step activation
    return y, z                         # output + raw sum for inspection

# ── AND gate: w=[1,1], θ=2 ──────────────────────────────────
print("AND Gate Truth Table")
print("-" * 35)
for x1, x2 in [(0,0), (0,1), (1,0), (1,1)]:
    y, z = mcculloch_pitts([x1, x2], weights=[1,1], threshold=2)
    print(f"  x1={x1}, x2={x2}  →  z={z:.1f}  →  output={y}")

# ── OR gate: w=[1,1], θ=1 ───────────────────────────────────
print("\nOR Gate Truth Table")
print("-" * 35)
for x1, x2 in [(0,0), (0,1), (1,0), (1,1)]:
    y, z = mcculloch_pitts([x1, x2], weights=[1,1], threshold=1)
    print(f"  x1={x1}, x2={x2}  →  z={z:.1f}  →  output={y}")
OUTPUT
AND Gate Truth Table ----------------------------------- x1=0, x2=0 → z=0.0 → output=0 x1=0, x2=1 → z=1.0 → output=0 x1=1, x2=0 → z=1.0 → output=0 x1=1, x2=1 → z=2.0 → output=1 OR Gate Truth Table ----------------------------------- x1=0, x2=0 → z=0.0 → output=0 x1=0, x2=1 → z=1.0 → output=1 x1=1, x2=0 → z=1.0 → output=1 x1=1, x2=1 → z=2.0 → output=1

Object-Oriented Neuron — With Inhibitory Support

import numpy as np

class MPNeuron:
    """McCulloch-Pitts neuron with excitatory and inhibitory inputs."""

    def __init__(self, weights, threshold):
        self.weights   = np.array(weights, dtype=float)
        self.threshold = threshold

    def fire(self, inputs):
        x = np.array(inputs, dtype=float)
        z = np.dot(self.weights, x)
        return 1 if z >= self.threshold else 0, z

# ── Demo: NAND gate ─────────────────────────────────────────
# NAND = NOT AND → fires on every input combo EXCEPT (1,1)
# weights = [-1,-1], threshold = -1
nand = MPNeuron(weights=[-1, -1], threshold=-1)

print("NAND Gate")
for x1, x2 in [(0,0), (0,1), (1,0), (1,1)]:
    y, z = nand.fire([x1, x2])
    print(f"  ({x1},{x2})  z={z:+.0f}  → {y}")

# ── Demo: Inhibitory veto ────────────────────────────────────
# x3 is an inhibitory signal: weight = -10
# Even if x1=x2=1, x3=1 will silence the neuron
veto_neuron = MPNeuron(weights=[1, 1, -10], threshold=1.5)

print("\nInhibitory Veto Test")
tests = [(1,1,0), (1,1,1)]    # last: inhibitory fires
for x1, x2, x3 in tests:
    y, z = veto_neuron.fire([x1, x2, x3])
    label = "🔥 FIRES" if y else "🔕 SILENT"
    print(f"  x=({x1},{x2},{x3})  z={z:+.0f}  → {label}")
OUTPUT
NAND Gate (0,0) z= 0 → 1 (0,1) z=-1 → 1 (1,0) z=-1 → 1 (1,1) z=-2 → 0 Inhibitory Veto Test x=(1,1,0) z=+2 → 🔥 FIRES x=(1,1,1) z=-8 → 🔕 SILENT

Section 08

Limitations — Why MP Neurons Led to the Perceptron

🔒
No Learning
Hard limitation
Weights and threshold must be set by hand. The neuron cannot adjust its own weights based on experience. There is no training loop, no gradient — just hardcoded logic.
🔢
Binary Only
No real-valued inputs
Inputs must be 0 or 1. You cannot feed in a temperature of 36.7°C or a pixel value of 187. This made the original model useless for real sensor data without extensive binarisation.
Cannot Solve XOR
Linearly inseparable
A single MP neuron is a linear classifier. XOR is not linearly separable — no single straight line can divide its truth table. This limitation famously stalled AI research for a decade.
🚀
What Came Next

Frank Rosenblatt (1958) added learnable weights → the Perceptron. Rumelhart, Hinton & Williams (1986) added hidden layers and backpropagation → MLP. LeCun (1989) added convolutions → CNN. Vaswani et al. (2017) added attention → Transformer. Every step is just a more powerful version of what McCulloch and Pitts started with a pencil in 1943.


Section 09

The Family Tree — From Neuron to GPT

1943
McCulloch-Pitts Neuron
Binary inputs, fixed weights, step threshold. Can compute logic gates. Cannot learn.
1958
Perceptron — Rosenblatt
Real-valued inputs, learnable weights via the Perceptron Learning Rule. First trainable neuron.
1986
Multi-Layer Perceptron + Backprop
Stacked layers of neurons, differentiable activation (sigmoid, tanh), gradient descent. XOR is finally solved.
2012
Deep Learning — AlexNet
Deep CNNs with ReLU, GPU training, millions of parameters. Image recognition explodes.
2017
Transformer — Attention Is All You Need
Self-attention replaces recurrence. Billions of neurons. GPT, BERT, Claude. Still rooted in: weighted inputs → sum → activation.

Section 10

Golden Rules

🧠 McCulloch-Pitts — What to Remember Forever
1
Every modern neuron is a McCulloch-Pitts neuron at its core. No matter how complex — LSTM cell, transformer head, capsule — they all compute some version of y = f(Σ wᵢxᵢ + b). The biology never left the equation.
2
Weights are synapse strength. A large positive weight amplifies a signal. A large negative weight suppresses it. When you train a neural network, you are literally evolving artificial synaptic strengths — the same thing evolution did over millions of years for biological brains.
3
The activation function is the neuron's decision boundary. McCulloch-Pitts used a hard step function. Modern networks use sigmoid, ReLU, or GELU — all doing the same job: deciding how strongly to pass the signal forward.
4
A single neuron is a linear classifier. It draws one hyperplane in input space. That's enough for AND and OR, but not XOR. To solve non-linear problems, you need layers — which is exactly what deep learning adds.
5
The bias term b shifts the threshold. Instead of θ in the condition z ≥ θ, modern networks absorb θ into a learnable bias: z = Σ(wᵢxᵢ) + b and fire if z ≥ 0. Same maths, cleaner notation.