Gradient Flow Viz

A backward-pass animation. Each column is a layer of neurons; a single wave glides from the loss-side (rightmost) toward the input (leftmost), painting the active layer in --cb-warning and tagging it with the gradient magnitude reaching that layer. Sibling of GradientDecayExplorer, which renders the same per-layer magnitude story as a static bar chart — GradientFlowViz adds the dynamic feel of backprop: the user sees the gradient travel.

Backward gradient wave at layer 4 of 4 (output). Gradient magnitude 1.00.
Gradient wave · backwardlayer 04 / 04 · |∂L| 1.00
|∂L| 1.00inputhidden 1hidden 2output
Customize
Architecture
3-4-4-2
Playback
500

Installation

npx shadcn@latest add https://craftbits.dev/r/gradient-flow-viz.json

Usage

import { GradientFlowViz } from "@craft-bits/core";
 
<GradientFlowViz layers={[3, 4, 4, 2]} />

Drive the wave from your own training loop:

<GradientFlowViz
  layers={[3, 4, 4, 2]}
  gradients={[0.0008, 0.012, 0.18, 1]}
/>

Drive the cursor from outside (controlled mode) — e.g. sync to a scroll position:

const [layer, setLayer] = useState(0);
 
<GradientFlowViz
  layers={[3, 4, 2]}
  currentLayer={layer}
  onCurrentLayerChange={setLayer}
  playing={false}
/>

Understanding the component

  1. Cursor 0 is the loss side. currentLayer = 0 lights the rightmost column (where backprop starts); currentLayer = depth − 1 lights the input layer. The wave travels right → left as the cursor advances — the direction gradients flow during backprop.
  2. One wave, three weights. The active column is fully lit; the two neighbours ahead of the wave glow at 55% and 25% intensity, so the eye can read the wave's direction even at slow paint speeds. Layers further away dim to a static rest state.
  3. --cb-warning is the wave colour. Warning (not accent) because the textbook story this viz teaches is vanishing gradients — the wave shrinks as it travels away from the loss. The default synthesised gradients follow 0.55^(depth − 1 − l) so the magnitudes you see on autoplay actually do shrink as the wave moves left.
  4. SPRINGS.smooth on the halo. Each layer's halo opacity and node fades use the smooth spring from @craft-bits/core/motion. prefers-reduced-motion: reduce parks the cursor at the input layer with no autoplay and no per-layer transition.
  5. setInterval, not RAF. The wave's cadence is set by playSpeed (default 500ms) — a setInterval advances the cursor and the spring resolves between ticks. Floored at 80ms so the spring always has enough time to settle visibly.
  6. Auto layout from layers alone. Node positions are derived from the layers shape — change the depth and the diagram re-flows. No coordinates to maintain.

Props

PropTypeDefaultDescription
layersreadonly number[]Neuron count per layer (left → right). Required.
gradientsreadonly number[]Gradient magnitude per layer. Synthesised (vanishing series) when omitted.
currentLayernumberControlled wave cursor. 0 = loss-side. Pair with onCurrentLayerChange.
defaultCurrentLayernumber0Uncontrolled initial cursor.
onCurrentLayerChange(layer) => voidFires when the cursor advances.
playingbooleantrueWhether the wave auto-advances backward.
playSpeednumber500Milliseconds between wave advances. Floored at 80.
transitionTransitionSPRINGS.smoothSpring for the halo / node fades.
classNamestringMerged onto the root <div> via cn().

Accessibility

  • The figure is role="figure" with an aria-labelledby that names the chart "Gradient wave · backward".
  • An aria-live="polite" summary announces the current layer, its semantic label (input / hidden N / output), and the gradient magnitude whenever the wave advances.
  • Color is never the only signal — the active layer is also tagged with a textual |∂L| magnitude.
  • The direction marker ("← gradients ←") above the diagram is aria-hidden to avoid double-announcement.
  • prefers-reduced-motion: reduce parks the wave on the input layer with no autoplay and no per-layer animation; the gradient readout for that layer stays fully visible.

Credits

  • Extracted from: craftingattention (app/src/lessons/primitives/viz/GradientFlowViz.tsx). The source mixed an LCG-seeded forward simulation, an Explore/Predict mode strip with a six-question quiz pool, narration heuristics, an RMS bar chart, and the ConstructionPrimitives widget chrome (ModeStrip, ChallengeBtn, FeedbackBadge, ScoreDots, DoneCard). The library extract distils to the dynamic essence: a backward-travelling wave through the layers with per-layer gradient magnitude. Stripped the simulation, the modes, the predict rounds, the activation/scale sliders, and the RMS axis; replaced project tokens (var(--color-warn-400)) with --cb-warning and inline SPRINGS.snappy with SPRINGS.smooth from @craft-bits/core/motion. Sibling to GradientDecayExplorer (static bar chart) and BackpropFlow (forward+backward layer cursor).