Deep Learning › Neural Network Foundations › Day 197
Hands-on lab — Day 197: The Perceptron
- ← Back to the Day 197 lesson
- Open the hands-on files on GitHub — clone or download them from the public labs repository
- Local path in your clone:
labs/sections/deep-learning/day-197-the-perceptron/
Commands
Setup
pip install -r requirements/requirements.txt Run
python3 examples/the_perceptron_lib.py Test
./tests/run_tests.sh File tree
examples/test_the_perceptron_lib.py examples/the_perceptron_lib.py expected-output/examples-run.txt expected-output/FIELDS.md expected-output/measured-values.txt expected-output/starter-run.txt expected-output/test-run.txt metadata.yml README.md requirements/requirements.txt security.md starter/test_the_perceptron_lib.py starter/the_perceptron_lib.py tests/run_tests.sh tests/test_the_perceptron_lib.py troubleshooting.md
Lab README
Lab: Day 197 -- The Perceptron
Lesson
Day number: 197 of 365. Course: Course05-SS01 (Deep Learning - Neural Networks). Topic: The Artificial Perceptron and Linear Separability.
Purpose
Build Frank Rosenblatt's classic Artificial Perceptron and a two-layer Multi-Layer Perceptron (MLP) from scratch in pure NumPy. You will implement the Perceptron Learning Rule, train on linearly separable boolean logic gates (AND, OR), analyze the geometric failure on XOR parity, and solve XOR using a two-layer network.
Learning objectives
- Implement the Perceptron dot-product and Heaviside step activation math.
- Code the Perceptron Learning Rule for weight and bias adaptation.
- Verify finite-step convergence on linearly separable datasets.
- Construct a two-layer MLP that resolves the non-linear XOR parity problem.
Prerequisites
- Linear algebra (dot products, vector addition).
- Python 3.11+ with NumPy.
Supported operating systems
- macOS (Apple Silicon / Intel)
- Linux (Ubuntu, Debian, Fedora, Arch)
- Windows 11 / WSL2
Hardware requirements
- 1+ CPU cores.
- 512 MB RAM.
- 50 MB disk space.
Required software
- Python 3.11 or newer.
- pip package manager.
- virtualenv or venv module.
Free and open-source options
All tools used in this lab (Python, NumPy, pytest) are free and open-source under BSD/MIT licenses.
Installation
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements/requirements.txt
File structure
starter/the_perceptron_lib.py: Student scaffold file.examples/the_perceptron_lib.py: Complete reference implementation.tests/test_the_perceptron_lib.py: Pytest automated validation suite.expected-output/: Verified output logs and baseline values.
How to run
Execute the reference demonstration script:
python3 examples/the_perceptron_lib.py
What the commands do
- Trains Perceptron on AND gate truth table.
- Evaluates weight updates across epochs.
- Verifies classification convergence.
Expected output
Perceptron Demo: AND Gate Predictions = [0, 0, 0, 1], Epochs = 6
Validation steps
- Verify that the Perceptron achieves 100% accuracy on AND and OR gates.
- Confirm that
solve_xor_with_two_layersachieves 100% accuracy across all 4 XOR states. - Ensure all unit test assertions pass.
Tests
Run the test runner script:
./tests/run_tests.sh
Cleanup
find . -type d -name "__pycache__" -exec rm -rf {} +
find . -type d -name ".pytest_cache" -exec rm -rf {} +
Troubleshooting
- Infinite Loop on XOR: Ensure
max_epochsis finite because XOR is linearly non-separable.
Security notes
All neural computations execute strictly on local CPU memory.
Extension exercises
- Implement Adaline (Adaptive Linear Neuron) using LMS gradient updates.
- Solve 3-Input Parity (
x1 ^ x2 ^ x3) using a 2-layer network.
Navigation
- Lesson title: The Perceptron
- Day number: 197 of 365
- Lesson article: https://ai-roadmap-365.github.io/day-197-the-perceptron
- Lab files: everything you need is in this directory — follow “How to run” below.
- Browse the course locally: from the repository root, this lab also appears in the course website at
/labs/day-197-the-perceptronwhen the site is running.
Expected output
FIELDS.md
# Expected Output Fields: Day 197
- `AND Gate Predictions`: Output array on boolean AND input combinations.
- `Convergence Epochs`: Epoch count at which zero training errors occurred.
- `XOR Accuracy`: Accuracy score of 2-layer MLP on XOR truth table.
examples-run.txt
Perceptron Demo: AND Gate Predictions = [0, 0, 0, 1], Epochs = 6
measured-values.txt
AND Gate Predictions: [0, 0, 0, 1]
Convergence Epochs: 6
XOR Accuracy: 1.0000
starter-run.txt
Starter scaffold executed. Ready for student implementation.
test-run.txt
============================= test session starts ==============================
collected 2 items
tests/test_the_perceptron_lib.py::test_perceptron_learns_and_and_or_gates PASSED [ 50%]
tests/test_the_perceptron_lib.py::test_two_layer_mlp_solves_xor PASSED [100%]
============================== 2 passed in 0.08s ===============================
Source files
examples/test_the_perceptron_lib.py (781 bytes)
import pytest
import numpy as np
from examples.the_perceptron_lib import Perceptron, solve_xor_with_two_layers
def test_perceptron_learns_and_and_or_gates():
X = np.array([[0, 0], [1, 0], [0, 1], [1, 1]])
y_and = np.array([0, 0, 0, 1])
y_or = np.array([0, 1, 1, 1])
p_and = Perceptron(learning_rate=0.1, max_epochs=50)
p_and.fit(X, y_and)
assert np.array_equal(p_and.predict(X), y_and)
p_or = Perceptron(learning_rate=0.1, max_epochs=50)
p_or.fit(X, y_or)
assert np.array_equal(p_or.predict(X), y_or)
def test_two_layer_mlp_solves_xor():
truth_table = [
(0, 0, 0),
(1, 0, 1),
(0, 1, 1),
(1, 1, 0)
]
for x1, x2, expected in truth_table:
assert solve_xor_with_two_layers(x1, x2) == expected
examples/the_perceptron_lib.py (1958 bytes)
import numpy as np
class Perceptron:
def __init__(self, learning_rate: float = 0.1, max_epochs: int = 100):
self.lr = learning_rate
self.max_epochs = max_epochs
self.weights = None
self.bias = 0.0
self.errors_per_epoch = []
def predict(self, X: np.ndarray) -> np.ndarray:
z = np.dot(X, self.weights) + self.bias
return np.where(z >= 0.0, 1, 0)
def fit(self, X: np.ndarray, y: np.ndarray) -> "Perceptron":
n_samples, n_features = X.shape
self.weights = np.zeros(n_features, dtype=float)
self.bias = 0.0
self.errors_per_epoch = []
for epoch in range(self.max_epochs):
total_errors = 0
for i in range(n_samples):
xi = X[i]
target = y[i]
y_hat = 1 if (np.dot(xi, self.weights) + self.bias) >= 0.0 else 0
error = target - y_hat
if error != 0:
self.weights += self.lr * error * xi
self.bias += self.lr * error
total_errors += 1
self.errors_per_epoch.append(total_errors)
if total_errors == 0:
break
return self
def solve_xor_with_two_layers(x1: int, x2: int) -> int:
# Hidden Layer: NAND and OR
h_nand = 1 if (-2.0 * x1 + -2.0 * x2 + 3.0) >= 0.0 else 0
h_or = 1 if (2.0 * x1 + 2.0 * x2 - 1.0) >= 0.0 else 0
# Output Layer: AND of hidden gates
y_xor = 1 if (2.0 * h_nand + 2.0 * h_or - 3.0) >= 0.0 else 0
return y_xor
def run_perceptron_demo():
X = np.array([[0, 0], [1, 0], [0, 1], [1, 1]])
y_and = np.array([0, 0, 0, 1])
p = Perceptron(learning_rate=0.1, max_epochs=20)
p.fit(X, y_and)
preds = p.predict(X)
print(f"Perceptron Demo: AND Gate Predictions = {preds.tolist()}, Epochs = {len(p.errors_per_epoch)}")
return p, preds
if __name__ == "__main__":
run_perceptron_demo()
metadata.yml (427 bytes)
lesson_id: D197
day: 197
kind: lab
languages:
- python
setup_commands:
- 'pip install -r requirements/requirements.txt'
run_commands:
- 'python3 examples/the_perceptron_lib.py'
test_commands:
- './tests/run_tests.sh'
cleanup_commands:
- 'find . -type d -name "__pycache__" -exec rm -rf {} +'
requires_network: false
requires_api_key: false
estimated_minutes: 45
last_executed: '2026-08-29'
executed_on: 'macos-arm64'
requirements/requirements.txt (28 bytes)
numpy>=1.26.0
pytest>=8.0.0
starter/test_the_perceptron_lib.py (781 bytes)
import pytest
import numpy as np
from examples.the_perceptron_lib import Perceptron, solve_xor_with_two_layers
def test_perceptron_learns_and_and_or_gates():
X = np.array([[0, 0], [1, 0], [0, 1], [1, 1]])
y_and = np.array([0, 0, 0, 1])
y_or = np.array([0, 1, 1, 1])
p_and = Perceptron(learning_rate=0.1, max_epochs=50)
p_and.fit(X, y_and)
assert np.array_equal(p_and.predict(X), y_and)
p_or = Perceptron(learning_rate=0.1, max_epochs=50)
p_or.fit(X, y_or)
assert np.array_equal(p_or.predict(X), y_or)
def test_two_layer_mlp_solves_xor():
truth_table = [
(0, 0, 0),
(1, 0, 1),
(0, 1, 1),
(1, 1, 0)
]
for x1, x2, expected in truth_table:
assert solve_xor_with_two_layers(x1, x2) == expected
starter/the_perceptron_lib.py (622 bytes)
import numpy as np
class Perceptron:
def __init__(self, learning_rate: float = 0.1, max_epochs: int = 100):
self.lr = learning_rate
self.max_epochs = max_epochs
self.weights = None
self.bias = 0.0
def predict(self, X: np.ndarray) -> np.ndarray:
# TODO: Compute z = X.w + b and apply step activation
pass
def fit(self, X: np.ndarray, y: np.ndarray) -> "Perceptron":
# TODO: Implement Rosenblatt Perceptron Learning Rule
pass
def solve_xor_with_two_layers(x1: int, x2: int) -> int:
# TODO: Implement 2-layer manual MLP solving XOR
pass
tests/run_tests.sh (227 bytes)
#!/usr/bin/env bash
set -euo pipefail
echo "========================================"
echo "Running Day 197 Lab Test Suite"
echo "========================================"
pytest tests/ -v
echo "All tests passed successfully."
tests/test_the_perceptron_lib.py (781 bytes)
import pytest
import numpy as np
from examples.the_perceptron_lib import Perceptron, solve_xor_with_two_layers
def test_perceptron_learns_and_and_or_gates():
X = np.array([[0, 0], [1, 0], [0, 1], [1, 1]])
y_and = np.array([0, 0, 0, 1])
y_or = np.array([0, 1, 1, 1])
p_and = Perceptron(learning_rate=0.1, max_epochs=50)
p_and.fit(X, y_and)
assert np.array_equal(p_and.predict(X), y_and)
p_or = Perceptron(learning_rate=0.1, max_epochs=50)
p_or.fit(X, y_or)
assert np.array_equal(p_or.predict(X), y_or)
def test_two_layer_mlp_solves_xor():
truth_table = [
(0, 0, 0),
(1, 0, 1),
(0, 1, 1),
(1, 1, 0)
]
for x1, x2, expected in truth_table:
assert solve_xor_with_two_layers(x1, x2) == expected
Troubleshooting
Troubleshooting: Day 197 - The Perceptron
Common Issues
- Non-Convergence on Non-Separable Data:
- Cause: Single-layer perceptrons cannot converge on non-linearly separable datasets.
- Fix: Use multi-layer networks (MLPs) with hidden layer representations.
Security notes
Security & Privacy: Day 197 - The Perceptron
Security Guidance
- All neural computations execute locally without external network transmission.