Neuron Inline
The "hello world" of neural networks rendered as a hands-on toy: one neuron, two inputs x₁ and x₂, three knobs (W₁, W₂, bias). The learner turns the knobs and watches the decision boundary line sweep across a scatter plot of pre-labeled points; the line is the locus where W₁·x₁ + W₂·x₂ + bias = 0. Anything on one side is "class 1," anything on the other is "class 0." Misclassified points keep a soft pulsing error ring around them, so the goal — "find the angle and offset that separates the colors" — is unambiguous.
Single-neuron decision boundary classifier. 5 of 8 points classified correctly.
0.50
1.00
-1.50
0.50x₁ + 1.00x₂ − 1.50 = 0
Customize
Initial bias
-1.50
Layers
Installation
npx shadcn@latest add https://craftbits.dev/r/neuron-inline.jsonUsage
import { NeuronInline } from "@craft-bits/viz/neuron-inline";
<NeuronInline />Show every signal — accuracy meter, activation toggle, shaded background:
<NeuronInline showAccuracy showActivationToggle showShading />Constrain the controls (e.g. fix the weights, expose only the bias):
<NeuronInline controls={["bias"]} initial={{ w1: 1, w2: 1 }} />Provide your own dataset:
<NeuronInline
data={[
{ x1: 0.3, x2: 2.4, label: 1 },
{ x1: 2.6, x2: 0.4, label: 0 },
]}
/>Understanding the component
- The plot. A 340×340 SVG with origin at the bottom-left of the plot region.
x₁runs along the horizontal axis,x₂along the vertical, both spanning[-0.5, 3.5]. Eight labeled points are scattered at fixed positions; "class 1" uses the accent token, "class 0" uses the warning token. - The boundary line. We solve
W₁·x₁ + W₂·x₂ + bias = 0for the two points where the line enters and exits the visible region. Those four numbers are pushed throughuseMotionValue+useSpring(SPRINGS.smooth), so when the user nudges a slider the endpoints interpolate rather than snap. - The weight-vector arrow. A small green arrow rooted at
(1.5, 1.5)points in the direction(W₁, W₂)— the normal to the boundary line. Like the line, its tip is spring-interpolated. - Half-plane wash. When activation shading is off, a subtle accent-to-warning gradient is rotated behind the plot to line up with the boundary, telling the eye which side is "positive" at a glance.
- Activation shading (opt-in).
showShadingswaps the wash for a 16×16 grid of tiles colored bysigmoid(z)orrelu(z)/3, making the smoothness of sigmoid vs. the hinge of ReLU visually obvious. - Wrong-pulsing rings. Points the current weights misclassify get a pulsing error ring (driven by SVG
<animate>). Toggling onshowAccuracyadds an explicitN / Nreadout.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
controls | readonly ("w1" | "w2" | "bias")[] | ["w1", "w2", "bias"] | Which parameter sliders to expose, in order. |
initial | Partial<NeuronInlineState> | { w1: 0.5, w2: 1, bias: -1.5, activation: "sigmoid" } | Initial state. Doubles as the reset target. |
data | readonly NeuronInlineDataPoint[] | 8 canonical points | Labeled training points (x1/x2 in plot domain [-0.5, 3.5]). |
showActivationToggle | boolean | false | Render the sigmoid/relu toggle below the sliders. |
showShading | boolean | false | Render the activation-shaded grid behind the points. |
showEquation | boolean | true | Render the live W₁·x₁ + W₂·x₂ ± |b| = 0 equation. |
showAccuracy | boolean | false | Render per-point accuracy dots and N / N readout. |
showWeightArrow | boolean | true | Render the green weight-vector arrow. |
transition | Transition | SPRINGS.smooth | Override the boundary-line / arrow spring. |
onChange | (state) => void | — | Fires whenever any state knob changes. |
className | string | — | Merged onto the root via cn(). |
Accessibility
- The plot SVG is
role="img"with anaria-labelsummarising the current accuracy (Neuron boundary — N of M classified correctly); the count updates live as the user drags. - Each slider has a visible label, a numeric live readout, and an
aria-labelrepeating the current value. Sliders are reachable in tab order; the native range input handles keyboard adjustment. - The activation toggle uses
aria-pressedto convey the selected mode for screen readers. - All decorative SVG layers — half-plane wash, glow filters, axis ticks, legend, weight arrow, data points — are
aria-hidden, so the canonical reading is the title summary plus slider values. - Colour is never the only signal: misclassified points are marked by a pulsing error ring in addition to the warning hue, and the accuracy readout flips to a success colour only when every point is correctly classified.
- Motion: the boundary line and arrow use a spring (
SPRINGS.smooth) that respectsTransitionoverrides; consumers needing fully reduced motion can passtransition={{ duration: 0 }}.
Credits
- Extracted from:
craftingattention(app/src/lessons/primitives/math/NeuronInline.tsx). The source was wired into the curriculum — it importedSvgLabelfrom the lesson SVG primitives, hardcoded the eight training points, and tracked progress against the host lesson. The viz extract dropsSvgLabelfor raw<text>styled via the--cb-*token palette, exposesdataso any binary 2D classification task can be plugged in, re-keys every colour from CA's per-track palette to the semantic--cb-accent/--cb-warning/--cb-success/--cb-error/--cb-fg-*family, generalises the spring tuning toSPRINGS.smooth, and removes every lesson-specific prop in favour of a plainonChangecallback and a built-in reset that only surfaces once the state diverges frominitial.