Code / AI & ML Basics / Unit 3: Learning a line

Gradient descent Gradient descent

Lesson 8 of 13 · about 22 minutes · Walk downhill on the error, step by step.

⚡ 0 XP

Step 1 of 3

One step downhill

hours → marksy = m·x + c

Picture the MSE as a valley. Every (m, c) is a spot on the hillside; the best line is at the bottom. Blindfolded, you can still feel which way the ground slopes — so take a small step downhill. Repeat. That is gradient descent, the engine behind almost all modern AI.

The slope (gradient) of the MSE for a line:

  • err = (m × x + c) − y for each point
  • dm = average of 2 × err × x
  • dc = average of 2 × err

Then step against the slope: m = m − lr × dm and c = c − lr × dc.

lr (learning rate) is the step size. Too small: slow. Too big: you leap over the valley and the error explodes.

🎯 Challenge: One gradient-descent step +20 XP

Write gdStep(m, c, xs, ys, lr) that returns a new object { m, c } after one step. With n points: err = (m * x + c) - y; dm is the average of 2 * err * x; dc is the average of 2 * err; then m - lr * dm and c - lr * dc.

Try twice to unlock the solution (0/2)

script.jsCtrl ⏎
Console

Output from console.log appears here.

Checklist

Press Run to check your code.

  • One step from (0, 0) gives m = 1, c = 0.6
  • A perfect line does not move
  • A step lowers the error
Lesson notes (text version)

1. One step downhill

Picture the MSE as a valley. Every (m, c) is a spot on the hillside; the best line is at the bottom. Blindfolded, you can still feel which way the ground slopes — so take a small step downhill. Repeat. That is gradient descent, the engine behind almost all modern AI.

The slope (gradient) of the MSE for a line:

  • err = (m × x + c) − y for each point
  • dm = average of 2 × err × x
  • dc = average of 2 × err

Then step against the slope: m = m − lr × dm and c = c − lr × dc.

lr (learning rate) is the step size. Too small: slow. Too big: you leap over the valley and the error explodes.

Challenge: One gradient-descent step

Write gdStep(m, c, xs, ys, lr) that returns a new object { m, c } after one step. With n points: err = (m * x + c) - y; dm is the average of 2 * err * x; dc is the average of 2 * err; then m - lr * dm and c - lr * dc.

2. The training loop

Training is just taking many small steps:

  1. start with a silly line: m = 0, c = 0
  2. take one gdStep
  3. repeat a few thousand times

Each step the line tilts and lifts a little closer to the dots. After enough steps it settles at the bottom of the valley — the best-fit line. Real neural networks do exactly this, only with millions of numbers instead of two.

Challenge: Train the line

gdStep is ready. Write trainLine(xs, ys, lr, steps): start with m = 0 and c = 0, call gdStep steps times (each time using the new m and c), and return { m, c }.

3. Draw what the model learned

Numbers like m = 6.69 are hard to feel. A picture shows at once whether the line follows the dots.

On a canvas, y grows downwards, so toPixel(hours, marks) flips marks for you: 0 marks sits at the bottom. To draw the line, find the pixels of two points on it — at hours 0 and hours 7 — and join them with moveTo, lineTo and stroke.

Challenge: Plot the dots and the line

The model is trained for you (model.m, model.c). Complete the TODOs:

  1. Draw every student as a dot: beginPath, arc at toPixel(HOURS[i], MARKS[i]) with radius 4, then fill.
  2. Draw the line from hours 0 to hours 7: beginPath, moveTo, lineTo, stroke.
  3. Put the equation in #eq exactly as marks ≈ M × hours + C, with M and C from toFixed(1) (e.g. marks ≈ 6.7 × hours + 31.6).

Search by task, format or tool name.