GenAI Course · Module 3 · Session 9

Artificial Neural Networks

⏱ 13 min read🎯 Beginner friendly🖼 2 diagrams🧪 2 live demos🐍 Python code

Every model in this course, from a spam filter to GPT, is built from one tiny unit: the artificial neuron. In this session we build one by hand, connect many into layers, run a forward pass with real numbers, and count the parameters a network learns.

In this session

  • The perceptron: a neuron that learns a yes/no rule
  • Why one neuron cannot learn XOR
  • Multi-layer perceptrons and forward propagation
  • Weights, biases, layers and capacity
  • Counting parameters by hand and in PyTorch

01The perceptron

The perceptron (Frank Rosenblatt, 1958) is the simplest neural network: one neuron. It multiplies each input by a weight, adds a bias, and outputs 1 if the total is above zero.

x₁ incomew₁x₂ loanw₂x₃ yearsw₃Σ + bweighted sumactivationstep / sigmoid / ReLUoutputŷ
One artificial neuron: multiply each input by its weight, add them up with a bias, then pass the sum through an activation function.
🏦

Like a loan officer with a scorecard. Income gets +2 points per lakh, an existing loan −3 points, each year in the job +1. Add them up with a starting score (the bias); above the cut-off means approve. Training is simply finding good points (weights) from past decisions.

Here a perceptron learns the AND rule from four examples, using the classic update: if the prediction is wrong, nudge the weights towards the right answer.

perceptron.py
import numpy as np

# Learn the AND rule: output 1 only when both inputs are 1
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 0, 0, 1])

w, b, lr = np.zeros(2), 0.0, 0.1
for epoch in range(10):
    errors = 0
    for xi, target in zip(X, y):
        pred = int(xi @ w + b > 0)          # weighted sum, then a step
        update = lr * (target - pred)       # perceptron learning rule
        w += update * xi; b += update
        errors += int(update != 0)
    if errors == 0:
        print(f"learned in {epoch + 1} epochs: w={w}, b={b:.1f}"); break

print("predictions:", [int(x @ w + b > 0) for x in X])
learned in 6 epochs: w=[0.2 0.1], b=-0.2 predictions: [0, 0, 0, 1]
Demo · Can one perceptron learn it?

02Multi-layer perceptrons and forward propagation

Stack neurons in layers and the network can draw curved boundaries, solving XOR and much more. A multi-layer perceptron (MLP) has an input layer, one or more hidden layers and an output layer.

Input (3)Hidden 1 (4)Hidden 2 (4)Output (1)
A multi-layer perceptron (MLP): every neuron in one layer connects to every neuron in the next. Information flows left to right.

Forward propagation is just running the numbers from left to right: each layer computes activation(inputs @ W + b) and passes the result on. Here is a 3 → 4 → 1 network scoring one loan application:

mlp_forward.py
import numpy as np
np.random.seed(0)

def relu(z): return np.maximum(0, z)
def sigmoid(z): return 1 / (1 + np.exp(-z))

# one loan application: [income (lakh/yr), loan amount (lakh), years employed]
x_raw = np.array([12.0, 5.0, 3.0])
x = x_raw / np.array([10.0, 10.0, 10.0])            # scale inputs to a small range first

W1, b1 = np.random.randn(3, 4) * 0.5, np.zeros(4)    # layer 1: 3 inputs -> 4 neurons
W2, b2 = np.random.randn(4, 1) * 0.5, np.zeros(1)    # layer 2: 4 -> 1 output

h = relu(x @ W1 + b1)            # hidden layer
p = sigmoid(h @ W2 + b2)         # probability of approval
print("hidden layer:", h.round(2))
print("approval probability:", p.round(3))
print("same network on unscaled input:", sigmoid(relu(x_raw @ W1 + b1) @ W2 + b2).round(3))
print("parameters:", W1.size + b1.size + W2.size + b2.size)
hidden layer: [1.51 0.06 0.85 1.52] approval probability: [0.735] same network on unscaled input: [1.] parameters: 21
Demo · Forward pass, one layer at a time
Scale your inputs. The same network on raw numbers (12, 5, 3) outputs 1.0: the sums are so large that sigmoid saturates. Neural networks train best when inputs are small, typically between −1 and 1.

03Weights, biases, layers and capacity

PartWhat it doesLearned?
Weighthow much one input matters to one neuronyes
Biasshifts the neuron’s threshold up or downyes
Layera group of neurons working in parallelno: you design it
Widthneurons per layerno: you choose
Depthnumber of layersno: you choose

A layer with n_in inputs and n_out neurons has n_in × n_out weights plus n_out biases. PyTorch counts them for us:

param_count.py
import torch.nn as nn

model = nn.Sequential(
    nn.Linear(3, 64), nn.ReLU(),     # 3*64 weights + 64 biases
    nn.Linear(64, 64), nn.ReLU(),    # 64*64 + 64
    nn.Linear(64, 1), nn.Sigmoid(),  # 64*1 + 1
)
for name, p in model.named_parameters():
    print(f"{name:10s} {tuple(p.shape)}")
print("total:", sum(p.numel() for p in model.parameters()))
0.weight (64, 3) 0.bias (64,) 2.weight (64, 64) 2.bias (64,) 4.weight (1, 64) 4.bias (1,) total: 4481

Check by hand: (3×64 + 64) + (64×64 + 64) + (64×1 + 1) = 256 + 4,160 + 65 = 4,481. ✓

Capacity is how complex a pattern a network can learn. More neurons and layers mean more capacity, but also more risk of memorising the training data (overfitting, Session 13).

ModelParameters
Our loan MLP4,481
BERT-base110 million
Llama 3.1 8B8 billion
Largest open modelshundreds of billions

04Summary

05Quick quiz

1. What does a bias do?

2. Why can’t one perceptron learn XOR?

3. How many parameters in a layer with 10 inputs and 5 neurons?

4. Forward propagation means…

5. Why scale inputs?

06References

Created by Ajeetkumar