Spaces:
Running
Running
File size: 12,358 Bytes
1b19efc fb5193e 1b19efc 69f60de 7043795 1b19efc 351e1a7 ef4c571 7bb6780 1b19efc ef4c571 1b19efc 69f60de 1b19efc ef4c571 dac4940 69f60de dac4940 1b19efc 3f21703 0f7d93c 3f21703 1b19efc 69f60de 7043795 1b19efc | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 | <!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Build a 2D dataset and use SGD to train a classifier one step at a time." />
<title>SGD Classifier Visualizer</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<main class="shell">
<header class="page-header">
<div>
<!--p class="eyebrow">Interactive machine learning</p--!>
<h1>SGD Classifier</h1>
<p class="subtitle">Draw a dataset, then watch the decision boundary move one SGD step at a time.</p>
</div>
<div id="runtime-status" class="status loading"><span></span>Loading Python runtime…</div>
</header>
<section class="workspace">
<div class="plot-card">
<div class="plot-toolbar">
<div>
<h2>Decision boundary</h2>
<!--p id="plot-instructions">Hover over a point to inspect its coordinates.</p--!>
</div>
<div class="legend" aria-label="Class legend">
<span><i class="dot dot-a"></i>Class A (+)</span>
<span><i class="dot dot-b"></i>Class B (-)</span>
<span><i class="batch-ring"></i>Next batch</span>
</div>
</div>
<div class="canvas-wrap">
<canvas id="plot" aria-label="Interactive classifier decision boundary"></canvas>
<div id="empty-hint" class="empty-hint">Select a class and click to place points</div>
</div>
<div class="plot-footer">
<span id="point-count">0 points</span>
<span id="step-count">Step 0</span>
<span id="batch-summary">No batch selected</span>
</div>
</div>
<aside class="control-card">
<nav class="tabs" aria-label="Visualizer sections">
<button id="configure-tab" class="tab active" type="button">Configure</button>
<button id="train-tab" class="tab" type="button">Train</button>
<button id="examples-tab" class="tab" type="button">Examples</button>
<button id="usage-tab" class="tab" type="button">Usage</button>
</nav>
<div id="configure-panel" class="tab-panel active">
<section class="control-section">
<div class="section-heading"><span>1</span><h2>Specify data</h2></div>
<div class="inline-field">
<label for="dataset-select">Type</label>
<select id="dataset-select">
<option value="easy-linear">Builtin linearly separable data (easy)</option>
<option value="hard-linear">Builtin linearly separable data (hard)</option>
<option value="nonlinear">Builtin non-linearly separable data</option>
<option value="custom">Custom data</option>
</select>
</div>
<div id="custom-data-controls" hidden>
<label>Point label</label>
<div class="segment" role="group" aria-label="Point label">
<button id="label-a" class="label-button active" type="button"><i class="dot dot-a"></i>Class A (+)</button>
<button id="label-b" class="label-button" type="button"><i class="dot dot-b"></i>Class B (-)</button>
</div>
<div class="button-row data-buttons">
<button id="undo" class="secondary" type="button">Undo</button>
<button id="redo" class="secondary" type="button">Redo</button>
<button id="clear" class="secondary danger" type="button">Clear</button>
</div>
</div>
</section>
<section class="control-section">
<div class="section-heading"><span>2</span><h2>Configure model</h2></div>
<div class="inline-field">
<label for="loss">Loss</label>
<select id="loss">
<option>perceptron</option>
<option>squared_error</option><option>log_loss</option>
<option>hinge</option><option>squared_hinge</option>
<option>huber</option><option>modified_huber</option>
<option>epsilon_insensitive</option><option>squared_epsilon_insensitive</option>
</select>
</div>
<div class="field-grid">
<div><label for="learning-rate">Learning rate</label><input id="learning-rate" type="number" value="1" min="0.000001" step="0.01" /></div>
<div><label for="batch-size">Batch size</label><input id="batch-size" type="number" value="1" min="1" step="1" /></div>
</div>
<label for="batch-selection">Mini-batch selection</label>
<select id="batch-selection">
<option value="random">Random subset</option>
<option value="permutation">Permutation · non-overlapping</option>
</select>
<p id="sampling-help" class="help">Each point is used once before the dataset is shuffled again.</p>
</section>
<section class="control-section additional-options-section">
<div class="section-heading"><span>3</span><h2>Additional options</h2></div>
<div class="field-grid">
<div><label for="random-seed">Random seed</label><input id="random-seed" type="number" value="42" min="0" max="4294967295" step="1" /></div>
<div><label for="animation-speed">Animation speed</label><select id="animation-speed"><option value="200" selected>Fast</option><option value="900">Normal</option><option value="1500">Slow</option></select></div>
</div>
</section>
</div>
<div id="train-panel" class="tab-panel">
<section class="control-section train-section">
<div class="metrics-panel">
<div class="metrics-heading"><h2>Metrics</h2><div><span class="metric-key loss-key"></span>Loss <span class="metric-key accuracy-key"></span>Accuracy</div></div>
<div class="metrics-chart-wrap">
<canvas id="metrics-chart" aria-label="Loss and accuracy over training steps"></canvas>
<div id="metrics-tooltip" class="metrics-tooltip" role="tooltip" hidden></div>
</div>
</div>
<div class="train-heading"><h2>Parameters</h2><span id="history-position">Step 0 of 0</span></div>
<div class="parameter-panel" aria-live="polite">
<div class="parameter-block">
<span>Class A parameters</span><small>Weight vector and bias for the positive class</small>
<code id="model-parameters">w_A = —<br>b_A = —</code>
</div>
<div class="parameter-block update-values">
<span>Pending Class A update</span><small>Negative learning rate × derivatives</small>
<code id="model-update">Δw_A = —<br>Δb_A = —</code>
</div>
</div>
<div class="history-buttons">
<button id="history-next" class="primary" type="button" disabled><span class="button-text">Next</span></button>
<button id="history-prev" class="secondary" type="button">Previous</button>
<button id="history-reset" class="secondary" type="button">Reset</button>
</div>
<div class="animation-buttons">
<button id="animate" class="secondary" type="button">Animate</button>
<button id="pause" class="secondary" type="button" disabled>Pause</button>
</div>
<p id="message" class="message">Add at least one point from each class to begin.</p>
</section>
</div>
<div id="examples-panel" class="tab-panel">
<section class="control-section examples-section">
<h2>Example scenarios</h2>
<p class="examples-intro">Load a scenario, then use Next or Animate in the Train tab to observe its behavior.</p>
<article class="example-card">
<button class="example-button" data-dataset="easy-linear" type="button">Perceptron – easy</button>
<p>This uses the easy linearly separable dataset and the perceptron loss. The decision boundary eventually converges to one with zero loss and perfect classification accuracy on the data.</p>
</article>
<article class="example-card">
<button class="example-button" data-dataset="hard-linear" type="button">Perceptron – hard</button>
<p>This uses the perceptron loss and hard linearly separable dataset. The decision boundary eventually converges to one with zero loss and perfect classification accuracy on the data.</p>
</article>
<article class="example-card">
<button class="example-button" data-dataset="nonlinear" type="button">Perceptron – nonseparable</button>
<p>This uses the perceptron loss and the non-linearly separable dataset. The decision boundary does not converge.</p>
</article>
<article class="example-card">
<button class="example-button" data-dataset="hard-linear" data-loss="squared_error" data-learning-rate="1" type="button">Adaline – hard (default learning rate)</button>
<p>This uses squared error and the hard linearly separable dataset with the default learning rate of 1. The parameters diverge and the decision boundary does not converge.</p>
</article>
<article class="example-card">
<button class="example-button" data-dataset="hard-linear" data-loss="squared_error" data-learning-rate="0.1" type="button">Adaline – hard (small learning rate)</button>
<p>This uses squared error and the hard linearly separable dataset with a small learning rate of 0.1.
The parameters and decision boundary eventually fluctuates slightly around a perfect classifier.</p>
</article>
<article class="example-card"> <button class="example-button" data-dataset="hard-linear" data-loss="log_loss" data-learning-rate="1" type="button">Logistic regression – hard</button>
<p>This uses log loss and the hard linearly separable dataset.
The parameters and decision boundary eventually fluctuates very slightly around a perfect classifer.</p>
</article>
</section>
</div>
<div id="usage-panel" class="tab-panel">
<section class="control-section usage-section">
<h2>Using the visualizer</h2>
<ol>
<li><strong>Choose data.</strong> Select a built-in dataset, or choose Custom data and click the plot to add Class A and Class B points.</li>
<li><strong>Configure SGD.</strong> Select a loss, learning rate, mini-batch size, and selection strategy. A fixed random seed reproduces the same batch order.</li>
<li><strong>Open Train.</strong> Points with amber rings form the mini-batch that will be used by the next update.</li>
<li><strong>Step through training.</strong> Next performs one SGD step. Previous and Reset inspect earlier states without deleting later history.</li>
<li><strong>Animate.</strong> Animate advances automatically at the configured speed; Pause stops it.</li>
</ol>
<h2>Reading the display</h2>
<ul>
<li>The solid line is the current decision boundary. The dotted line is the initial reference boundary.</li>
<li>Background colors show the predicted class regions.</li>
<li>The Parameters panel shows Class A's current weight and bias and its pending update.</li>
<li>The Metrics chart evaluates loss and accuracy on the entire dataset. Larger outlined markers identify the step currently displayed.</li>
<li>Hover over any point to inspect its class and coordinates.</li>
</ul>
</section>
</div>
</aside>
</section>
</main>
<script type="module" src="app.js"></script>
</body>
</html>
|