ML Playground

Click the canvas to place data points, train a model, and watch it draw the boundary between classes. Then open the instructions below to change how the machine thinks.

for Room 204
machine learning lab
Left-click: add point  ·  Right-click: remove nearest point 0 points

Follow these steps the first time you open the playground.

  1. Pick Class A or Class B above the canvas, then click anywhere on the white canvas to drop points of that color. Add at least 4–5 points for each class, in two roughly separate areas.
  2. Choose an algorithm: K-Nearest Neighbors looks at the closest existing points to guess a new one's class. Perceptron tries to draw one straight line that separates the two classes. Neural Net passes that line through a hidden layer of neurons first, which lets it bend into a curve.
  3. For KNN, drag the k slider then press Classify with KNN. For Perceptron, press Train perceptron to search for a dividing line, or Train one epoch to step through it one round at a time. For Neural Net, choose how many hidden neurons to use and press Train neural network.
  4. Watch the canvas shade itself gold or light-tan — that shading is the model's prediction for every point in that region, not just the ones you clicked.
  5. Use Load linear sample or Load circular sample to try pre-made datasets, or Clear all to start over.

This entire page is one HTML file. Right-click it and choose "View Page Source," or open it in a code editor, to find the spots below and change how the machine behaves.

1. Make KNN more (or less) stubborn

A small k lets a single nearby point flip the prediction; a large k smooths the boundary but can ignore small clusters. Try k = 1 and k = 15 on the circular sample and compare.

Find: let kValue = 3; near the top of the script, or just drag the slider — the slider changes the same variable live.

2. Prove a straight line isn't always enough

Load the circular sample and train the Perceptron. It will never fully separate the two rings, because no single straight line can. This is the classic limit of linear models — ask your teacher about "non-linearly separable data."

Find: function trainPerceptronEpoch() — this is where the line's slope and position get nudged after every mistake.

3. Change the distance KNN uses

KNN currently measures "closeness" with straight-line (Euclidean) distance. Change the function below to use Manhattan distance (sum of the horizontal and vertical distance) instead, and see whether the boundary changes shape.

Find: function distance(a, b) and edit the return line.

4. Speed up or sharpen the shading

The colored regions are computed on a grid, not per-pixel, to stay fast. Lower the number for a sharper (slower) picture, or raise it to make the model recompute faster on an older laptop.

Find: const GRID_STEP = 8;

5. Add a third class

Give CLASS_COLORS a third color, add a matching button next to Class A/B in the HTML with data-class="2", and update the KNN vote-counting so it tallies three labels instead of two. Perceptron and this Neural Net both only work for two classes, so this challenge pairs best with KNN.

Find: const CLASS_COLORS near the top of the script, and the .class-picker buttons in the HTML above the canvas.

6. Give the neural network more room to think

Train it on the circular sample with only 2 hidden neurons, then again with 16. More hidden neurons can bend the boundary into a more complex shape — but too many, trained too long, can start memorizing quirks of your exact points instead of the general pattern (a preview of "overfitting").

Find: the Hidden neurons slider, or function nnInit(hiddenSize) in the script.

7. Swap the hidden layer's activation function

The hidden neurons currently squash their input with Math.tanh. Try replacing it with a ReLU (Math.max(0, z)) and update its derivative in the backprop step to match. Does the boundary look different?

Find: function nnForward(model, x) and the derivative line inside function nnTrainEpoch.

8. Change how far back the generative model "remembers"

In the Generative AI Lab, context length is the only thing the network sees before guessing the next character. Set it to 2 and generate, then set it to 8 and generate the same seed. Shorter context tends to wander; longer context repeats the training text more literally. Real models use thousands of tokens of context instead of a handful of characters.

Find: the Context length slider, or genaiEncodeContext() in the script.

9. Turn the "creativity" dial

Temperature divides the network's raw scores before turning them into probabilities. A low temperature (0.1) makes the model almost always pick the single most likely next character; a high one (1.5) flattens the odds so it takes bigger risks and can produce nonsense. This is the same knob many AI chat tools expose as "temperature."

Find: function genaiSoftmax(logits, temperature).

Generative AI Lab

The Neural Net above answers one question: which class does this point belong to? A generative model like the one behind ChatGPT answers a different question, using the exact same kind of network: given the text so far, what letter (or word) is likely to come next? It turns that answer into a probability for every possible next character, samples one, glues it onto the text, and repeats — that loop is called autoregressive generation. Train the tiny network below on your own text and watch it do the same thing, one character at a time.

1. Training text

Paste in your own text (a paragraph, a poem, some notes) and press train.

2. Generate

Train the network first.