🌙 30-Day AI Ramadan Series  ·  Day 3 of 30
Deep Dive · Feb 21, 2026 · 14 min read · Foundations

How Models Actually Learn:
Loss, Gradient Descent & Optimization

Every ML model — from a spam filter to GPT-4 — learns by doing the same thing: measuring how wrong it is, then nudging itself to be less wrong. Here's exactly how that works.

← Back to Blog ☰ Categories

You're blindfolded on a hilly landscape. Your goal: reach the lowest valley.
You can't see anything. But you can feel the ground beneath your feet.
You take a small step in whichever direction feels most downhill.
Then another. Then another.

Eventually — step by step — you find the bottom.
That is gradient descent. That is how every ML model learns.

01 — What Does "Learning" Actually Mean?

When we say a model "learns," we mean something very specific: it adjusts its internal numbers — called parameters or weights — until its predictions become as accurate as possible on the training data.

Before training, these weights are random. The model makes terrible predictions. After training, the weights have been tuned so that predictions are good. The process of tuning them is called optimization, and it is driven entirely by a loss function.

Think of it like tuning a guitar. Each string (weight) starts out of tune. You tighten or loosen each one — just a little at a time — guided by the sound it makes (the loss). You stop when the guitar sounds right (loss is low). The model does exactly this, but with millions of strings tuned simultaneously, thousands of times.

02 — The Loss Function: Measuring How Wrong You Are

A loss function is a mathematical formula that takes your model's prediction and the correct answer, and returns a single number: the error. Lower loss = better predictions. The goal of training is to minimize this number.

🏹 Analogy

You're learning archery. You shoot at a target. The loss function measures how far from the bullseye your arrow landed. 50cm away → very high loss. 5cm away → low loss. Bullseye → zero loss. Your job is to adjust your technique — arm position, grip, breath, release — to minimize that distance over many attempts. The loss function is the scoreboard. Without it, you'd have no idea if you were improving.

Different problems use different loss functions. The two most important ones to know:

MSE — Mean Squared Error
Used for regression (predicting a number). Takes each error, squares it (penalizing large mistakes more heavily), then averages. If your model predicts a house price of $300k but the real answer is $350k, the error is $50k — squared and averaged across all examples.
Cross-Entropy Loss
Used for classification (predicting a category). Measures how confident and correct the model's probability estimate is. A confident wrong prediction is penalized very heavily. A cautious correct prediction is penalized lightly. This pushes the model to be both accurate and appropriately confident.

03 — Gradient Descent: The Optimization Engine

Once we can measure error (loss), we need a way to reduce it. That mechanism is gradient descent.

The gradient is the slope of the loss function at the model's current position. It answers the question: "If I increase this weight slightly, does the loss go up or down — and by how much?" The gradient always points uphill (toward higher loss). So we go in the opposite direction — downhill — to reduce the loss. This is exactly the blindfolded hiker from the opening: you feel the slope, and step downhill.

1
Forward pass. Feed training data through the model with the current weights. Get predictions.
The model is just doing math — multiplying inputs by weights and passing them through functions. At the start, those weights are random, so the predictions are terrible.
2
Compute loss. Compare predictions to the true labels using the loss function. Get a single number representing total error across all training examples.
3
Compute gradients (backpropagation). This is where the magic happens. For each weight, calculate how much it contributed to the total loss — its gradient. In neural networks, this is done using backpropagation: the error signal travels backwards through the network, layer by layer. Think of it like tracing blame — which weights were most responsible for the wrong prediction?
You don't need to understand the calculus behind backpropagation. What matters is the concept: each weight gets a score — its gradient — that says "increase this weight and the loss goes up by X" or "decrease this weight and the loss drops by Y."
4
Update weights. Adjust every weight in the opposite direction of its gradient, scaled by the learning rate:
new_weight = old_weight − learning_rate × gradient
Each weight moves just a little in the direction that reduces the loss.
5
Repeat. Do this thousands or millions of times. Each full pass through the training data is called an epoch. With each epoch, the loss decreases and the predictions improve — until the model converges on a good solution.

04 — The Learning Rate: The Most Important Number You'll Tune

The learning rate (written as α or lr) controls how large each weight update step is. It is the single most impactful hyperparameter in training — and the one engineers spend the most time tuning.

Too high (e.g. 1.0)
Steps are too large — the model overshoots the minimum, bounces wildly around it, and may never converge. Like trying to balance on a tightrope by making huge jumps.
Too low (e.g. 0.000001)
Steps are tiny — training takes forever. May also get stuck in a poor local minimum and never escape it. Like trying to cross a room by moving one millimetre at a time.
Well-chosen (e.g. 0.001)
Steady, reliable descent toward a good minimum. Fast enough to be practical, careful enough not to overshoot. This value isn't universal — the right lr depends entirely on your model, data, and optimizer.
Typical range
1e-4 to 1e-2 for most tasks. Large language models often use a learning rate schedule — starting higher and gradually decaying — rather than a single fixed value.
⚠️ Common Misconception

There is no universally "correct" learning rate. A value that works perfectly for one model and dataset may cause another to diverge completely. Always treat it as something to tune — start with 1e-3 as a baseline, watch your loss curve, and adjust from there.

05 — Gradient Descent in Pure NumPy

Here is the complete training loop in about 15 lines of Python — no frameworks, no abstractions. Every major library (PyTorch, TensorFlow, sklearn) does exactly this internally, just faster and with automatic differentiation.

import numpy as np

# Toy dataset: learn y = 2x + 1 from noisy observations
np.random.seed(42)
X = np.random.randn(100)
y = 2 * X + 1 + np.random.randn(100) * 0.3  # true relationship + noise

# Initialize weights at zero — the model knows nothing yet
w, b = 0.0, 0.0   # weight and bias
lr    = 0.01       # learning rate

for epoch in range(1000):
    y_pred = w * X + b                    # Step 1: forward pass
    loss   = np.mean((y_pred - y) ** 2)  # Step 2: MSE loss

    # Step 3: gradients — how does loss change if we nudge w or b?
    dw = np.mean(2 * (y_pred - y) * X)   # dLoss/dw
    db = np.mean(2 * (y_pred - y))        # dLoss/db

    # Step 4: update — move opposite to the gradient
    w -= lr * dw
    b -= lr * db

print(f"Learned: w={w:.3f}, b={b:.3f}")
# → Learned: w≈2.000, b≈1.000  ✓  (recovered the true relationship)

The model started knowing nothing (w=0, b=0). After 1000 steps of gradient descent, it recovered the exact relationship hidden in the data — y = 2x + 1. This is the essence of machine learning.

💡 What just happened?

Each of the 1000 iterations ran all 5 steps of the training loop. Each time, the model got slightly better. By epoch 1000, the gradients were nearly zero — meaning the loss couldn't decrease any further in that direction. That's convergence. The model "learned."

06 — How Much Data Per Update?

The training loop we've seen computes the gradient using the entire dataset before making each update. That works — but with large datasets, waiting to see every example before taking one step is painfully slow. Engineers choose how many examples to use per update, giving rise to three variants:

Batch GD
Full dataset
Computes the gradient over all training examples before updating once. Smooth and accurate, but very slow on large datasets. What the NumPy example above does.
SGD
1 example at a time
Updates weights after every single training example. Very fast per step, but noisy — one example gives a rough estimate of the true gradient, so the loss bounces around erratically before settling.
Mini-Batch GD
The practical standard
Updates after a small random subset — a batch — of examples (typically 32, 64, or 128). Balances speed and stability. This is what almost everyone uses. When people say "SGD" in modern ML, they usually mean this.
🧭 The intuition

Imagine navigating an unfamiliar city to find the lowest elevation. Batch GD asks every single resident for directions before taking one step — very accurate, but you'll wait all day. SGD asks one random person and immediately walks — fast, but that one person might be wrong. Mini-batch GD asks a small group, averages their directions, then walks. Fast enough to keep moving, accurate enough to not get lost.

Beyond how many examples per update, there's also the question of how to apply the update itself. The basic rule — weight = weight − lr × gradient — gives every weight the same step size on every update. That's like telling every member of a hiking group to take exactly the same stride length, regardless of whether they're on flat ground or a steep cliff. It works, but it's not efficient.

Adam (Adaptive Moment Estimation) is smarter. Think of it as each weight keeping a personal notebook. In that notebook it records: "How have my recent updates been going? Am I consistently heading in the same direction, or am I bouncing back and forth?" If a weight has been moving steadily in the same direction — it's making confident progress — Adam lets it take bigger steps. If a weight keeps changing direction and seems uncertain — Adam slows it down and makes it more careful. The result: faster overall convergence, and far less sensitivity to the initial learning rate you pick. This is why Adam is the default starting point for almost every training project today.

🔗 Connection to Modern AI

Large language models are trained with Adam and mini-batch gradient descent, using a learning rate that starts higher and gradually decays over the course of training. The training loop is the same 5-step process from this article — just running on thousands of GPUs for weeks. The concepts are identical. Only the scale changes.

07 — The Hidden Problem: Local vs Global Minima

Here's something that bothered mathematicians for a long time about gradient descent: it only follows the slope downhill from wherever it starts. It has no map. It can't see the full landscape. It just feels the ground under its feet and takes the next step.

This creates a genuine problem. Imagine you're dropped blindfolded onto a mountain range. You follow the slope downhill faithfully — step by step — and eventually reach flat ground. You take off your blindfold. You're in a valley. But looking around, you can see there's a much deeper valley on the other side of a ridge you never crossed. You found a bottom — but not the bottom.

In ML terms: the valley you found is a local minimum — a point where the loss is lower than anything nearby, so gradient descent stops there. The deepest valley in the entire landscape is the global minimum — the theoretically best solution. Gradient descent is not guaranteed to find it.

🏔️ Visualizing the landscape

Picture a landscape with several valleys of different depths:

  • Global minimum — the single deepest valley. The absolute best solution. What we'd ideally reach.
  • Local minimum — a valley that looks like the bottom from where you're standing, but isn't. Gradient descent can get trapped here because every nearby step would go up, not down — so it stops, thinking it's done.
  • Saddle point — flat ground that isn't a valley at all. Downhill in one direction, uphill in another. Gradient descent can slow to a crawl here, confused about which way to go.

So does this mean gradient descent is broken? Not in practice. Here's why:

First, a good enough solution is usually good enough. In most real problems — predicting prices, classifying images, filtering spam — a local minimum that achieves 94% accuracy is perfectly useful, even if the global minimum might give 95%. The difference rarely justifies the cost of finding it.

Second, the mini-batch noise actually helps. Because mini-batch GD uses a random subset of data each time, its loss curve is slightly noisy — it bounces a little rather than descending perfectly smoothly. This noise can accidentally knock the model out of a shallow local minimum and into a better one. What looks like a flaw turns out to be a feature.

Third, Adam has a built-in escape mechanism. When Adam notices that a weight keeps reversing direction — a sign it may be stuck near a local minimum — it reduces that weight's step size, which ironically makes the updates more consistent and can help navigate the landscape more carefully.

💬 For You to Consider

Given all of this — why do you think training the same model twice, with different random starting weights, sometimes produces very different results? And why might that be fine?

08 — Coming Up Next

Tomorrow — Day 4: Linear Regression. The simplest model that uses everything you just learned. One loss function, one gradient descent loop, one straight line — and it teaches more about ML than almost any other algorithm.

09 — Go Deeper

▶ 3Blue1Brown: Gradient Descent, How Neural Networks Learn
YouTube · 21 min · The definitive visual explanation of exactly this topic. The animation of the loss landscape makes the concept click in a way words can't.

▶ 3Blue1Brown: What is Backpropagation Really Doing?
YouTube · 14 min · Builds directly on the gradient descent video — shows how the error signal travels backwards to assign blame to each weight. No calculus required to follow the intuition.

▶ Coursera: Deep Learning Specialization — Andrew Ng
5-course specialization · The gold standard for learning the math behind gradient descent, backpropagation, and optimization — explained step by step with the clarity Andrew Ng is known for. Audit for free.

🧠 Check Your Understanding
1. What is a loss function, and what does it return?
A loss function takes a model's prediction and the correct answer, and returns a single number representing how wrong the prediction was. Lower is better. The goal of training is to minimize this number across all training examples. Examples: MSE for regression, Cross-Entropy for classification.
2. Explain gradient descent in plain language — no equations.
Gradient descent is a method for finding the minimum of a function by repeatedly moving in the direction that reduces it. At each step, you calculate the slope (gradient) of the loss at the current position — which tells you which direction is "uphill." You then move a small step in the opposite direction — downhill. Repeat thousands of times until the loss stops decreasing.
3. What happens if the learning rate is too high? Too low?
Too high: each update step is so large that the model overshoots the minimum. The loss bounces up and down and may actually increase — the model fails to converge. Too low: each step is so tiny that training takes an extremely long time, and the model risks getting stuck in a poor local minimum and never escaping. The right learning rate is problem-specific and found by experimentation.
4. What is the difference between Batch GD, Mini-Batch GD, and SGD?
They differ in how many training examples are used to compute each gradient update. Batch GD uses the entire dataset — accurate but slow. SGD uses one example at a time — fast but noisy. Mini-Batch GD uses a small random subset (e.g. 32 or 64 examples) — the practical middle ground used in almost all real-world training.
5. What is a local minimum, and why is it a problem for gradient descent?
A local minimum is a point in the loss landscape that is lower than everything immediately around it — so gradient descent stops there, believing it has found the best solution. But it may have only found a small valley, not the deepest one (the global minimum). In practice this is often acceptable — a local minimum that performs well enough is perfectly useful — and techniques like mini-batch noise and Adam help navigate around shallow traps.
6. What does Adam improve over plain gradient descent?
Plain gradient descent applies the same learning rate to every weight on every step. Adam tracks the update history for each weight and adapts the step size individually — larger nudges for weights that haven't moved much, smaller ones for weights that keep changing. This makes training converge faster and makes the process less sensitive to the initial learning rate you choose.
⚡ Quick Recap — How Models Learn
  1. Weights — Internal numbers the model adjusts during training. Start random, end up tuned.
  2. Loss function — Measures the error between prediction and truth. One number. Lower is better.
  3. Gradient — The slope of the loss at the current weights. Points uphill. We go the opposite way.
  4. Gradient descent — The 5-step loop: forward pass → compute loss → compute gradients → update weights → repeat.
  5. Learning rate — Controls step size. Too large = overshoot. Too small = too slow. Must be tuned.
  6. Local minimum — A point lower than its immediate neighbors, where GD can get stuck. Not necessarily the best solution overall.
  7. Global minimum — The theoretically lowest point in the entire loss landscape. What we aim for, but don't always need.
  8. Batch GD / Mini-Batch / SGD — Three ways to decide how many examples to use per update. Mini-batch is the practical standard.
  9. Epoch — One full pass through the training data. Training runs for many epochs.
  10. Adam — A smarter update rule: each weight adapts its own step size based on its recent history. Faster and more robust than plain GD.
🎯 Interview Questions
  1. What is a loss function? Give two examples.
    A loss function quantifies the error between predictions and true labels. MSE (Mean Squared Error) is used for regression; Cross-Entropy loss is used for classification.
  2. Explain gradient descent in plain language.
    Gradient descent iteratively adjusts model weights in the direction that reduces the loss, using the gradient (slope) to determine which direction is "downhill" at each step.
  3. What happens if the learning rate is too high or too low?
    Too high: the model overshoots the minimum and the loss may diverge or oscillate. Too low: training is very slow and may get stuck in a poor solution.
  4. What is the difference between Batch GD, Mini-Batch GD, and SGD?
    Batch GD computes gradients over the full dataset — stable but slow. SGD uses one example at a time — fast but noisy. Mini-Batch GD uses a small random subset per update — the practical balance used in almost all real projects.
  5. What is a local minimum, and why does it matter?
    A local minimum is a point where the loss is lower than everything immediately surrounding it, causing gradient descent to stop — even if a better solution exists elsewhere in the landscape. In practice, local minima are often good enough, and techniques like mini-batch noise and Adam help avoid the worst ones.
  6. What does Adam improve over plain gradient descent?
    Adam adapts the learning rate per weight based on gradient history, rather than applying a single fixed rate to all weights equally. This makes training faster and less sensitive to the initial learning rate choice.
📎 Attachments & Further Reading

No attachments for this topic yet.

#GradientDescent#LossFunction#Optimization#Backpropagation#LearningRate#Foundations#30DaysOfAI#Ramadan2026
← Day 2 The ML Pipeline