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.
Follow these steps the first time you open the playground.
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.
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.
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.
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.
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;
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.
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.
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.
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.
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).
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.