Skip to content
Machine Learning
Regression 7 min read

Linear Regression & Gradient Descent

Fit your first model by hand, understand loss functions, and watch gradient descent find the best weights automatically.

Download notebook Open Google ColabIn Colab: File → Upload notebook → pick the downloaded file.

Linear regression is the "hello world" of machine learning — but almost every idea you'll use later (weights, bias, loss, gradient descent) shows up here first, in its simplest form. In this lesson you'll fit a line by hand, define what "best fit" means mathematically, and then let gradient descent do the work for you.

The model: a line with two knobs

A linear model predicts a number as a weighted sum of the input plus an offset:

ŷ = w·x + b

  • w (weight / slope) — how much the prediction changes when x increases by 1
  • b (bias / intercept) — the prediction when x = 0

Training a model just means finding good values for these two knobs. Try it yourself — move the sliders until the line goes through the middle of the cloud:

Linear regression playground

Move the weight (slope) and bias (intercept) to fit ŷ = w·x + b. Lower MSE = better fit.

051015200246810
ŷ =0.40·x + 3.50MSE23.762

You probably ended up somewhere near w ≈ 1.6, b ≈ 1.2 — and you likely used the dashed residual lines to guide you. That intuition — "make the vertical gaps small" — is exactly what the loss function formalizes.

The loss: measuring "how wrong"

For each point, the residual is the gap between truth and prediction, y − ŷ. The mean squared error (MSE) averages the squared residuals:

MSE = (1/n) Σ (yᵢ − ŷᵢ)²

Squaring does two useful things: errors can't cancel each other out, and big misses are punished much more than small ones. Let's compute it ourselves — run this right here in your browser:

Python — runs in your browser

Lower loss = better fit. Training is now an optimization problem: find the (w, b) pair that minimizes MSE.

Gradient descent: rolling downhill

Imagine the loss as a landscape where every location is a (w, b) choice and the altitude is the MSE. Gradient descent starts anywhere and repeatedly takes a small step downhill:

w ← w − η · ∂L/∂w and b ← b − η · ∂L/∂b

where η (the learning rate) controls the step size. Watch how the choice of η changes everything — try a tiny value, then crank it up past 0.7:

Gradient descent, step by step

Each step moves against the gradient: x ← x − η·∇L(x). Try η = 0.7 and watch it bounce.

012345
x-2.800L(x)2.917∇L(x)-4.125

Three regimes to remember:

  • η too small — converges, but painfully slowly
  • η just right — smooth, fast descent to the minimum
  • η too large — overshoots the valley and bounces or diverges

Where do the gradients come from?

For MSE they have closed forms: ∂L/∂w = (2/n) Σ (ŷᵢ − yᵢ)·xᵢ and ∂L/∂b = (2/n) Σ (ŷᵢ − yᵢ). Deep learning frameworks like PyTorch compute gradients automatically for any model — that's what "autograd" means.

Implementing gradient descent from scratch

Fifteen lines of NumPy are enough. This is the same algorithm the playground's "Auto-fit" button runs:

Python — runs in your browser

Notice b converges more slowly than w — the bias gradient doesn't get the "leverage" of being multiplied by x. Feature scaling (a later lesson) fixes exactly this kind of imbalance.

The scikit-learn way

In practice you won't hand-roll gradient descent for linear regression — scikit-learn solves it directly:

Python — runs in your browser

Same answer, one line of fitting. LinearRegression uses a closed-form solution (ordinary least squares); gradient descent matters when models get too big for closed forms — which is every neural network you'll ever train.

Check your understanding

4 questions · free
  1. Q1.In ŷ = w·x + b, what happens to predictions if you increase b by 2?

  2. Q2.Why does MSE square the residuals instead of just averaging them?

  3. Q3.You set the learning rate very high and the loss starts growing every step. What's happening?

  4. Q4.Gradient descent updates w with w ← w − η·∂L/∂w. Why subtract the gradient?

Exercise: Gradient descent on a different dataset

Generate a dataset with a negative slope — y = -2x + 8 plus Gaussian noise (σ = 0.8) for 40 points with x between 0 and 5. Fit it two ways: with your own gradient-descent loop, and with scikit-learn's LinearRegression. Do the two answers agree to two decimal places?

Next up: what happens when a straight line isn't enough — polynomial regression, and the overfitting trap that comes with it.