Softmax Inline

Inline softmax explorer designed to sit in prose flow. No widget chrome — just a row of draggable luminous bars, optional inline controls, and a thin readout summary.

Each bar represents one logit z_i; drag it vertically (or focus and press arrow keys) to update the temperature-scaled softmax in real time. Toggle the max trick to see what happens to exp(z / T) without the textbook subtract-the-max stabilisation — switch precision to "float16" and the float16 cap (65504) is reachable without astronomical logits, so the failure mode becomes visible.

Softmax explorer with draggable logit bars.
2.0z₁1.000.591.0z₂0.370.220.3z₃0.180.11-0.5z₄0.080.05-1.0z₅0.050.03
logits = [2.0, 1.0, 0.3, -0.5, -1.0] · T = 1.0 · max trick ON
probs = [0.59, 0.22, 0.11, 0.05, 0.03]z₁ leads at 59%
Customize
Distribution
skewed
Controls
Seed values
1.0
Precision

Installation

npx shadcn@latest add https://craftbits.dev/r/softmax-inline.json

Usage

import { SoftmaxInline } from "@craft-bits/viz/softmax-inline";
 
<SoftmaxInline logits={[2, 1, 0.3, -0.5, -1]} />

Expose the temperature slider:

<SoftmaxInline
  logits={[2, 1, 0.3, -0.5, -1]}
  showTemperature
  initialTemperature={1}
/>

Teach numerical stability with the max-trick toggle in float16:

<SoftmaxInline
  logits={[12, 8, 4, 1, -1]}
  showTemperature
  showMaxTrick
  precision="float16"
/>

Understanding the component

  1. Luminous SVG bars. Each bar's height encodes |z_i| against a zero line; positive logits rise, negative ones drop. Fill opacity tracks the softmax probability so the eye reads the distribution before reading numbers.
  2. Spring drag. Bar y, height, and fillOpacity animate with SPRINGS.snap so a rapid drag still settles smoothly; reduced-motion users snap instantly.
  3. Max-trick toggle. When ON, the implementation subtracts max(z / T) before exp(). When OFF, every logit is exp()-ed raw — precision="float16" then visibly overflows on logits ≳ 11 and the value labels turn red.
  4. Two precision modes. float64 is the JS default. float16 simulates the IEEE-754 half cap (65504) so overflow is reachable without 700+ magnitude logits.
  5. Per-bar readout. Below each bar: the exp value, the probability, and a thin probability fill bar so the user can compare relative scale.
  6. Summary footer. Both the raw logit vector and the resulting prob vector print in tabular monospace; the current argmax highlights in accent.

Props

PropTypeDefaultDescription
logitsreadonly number[][2, 1, 0.3, -0.5, -1]Initial logits.
labelsreadonly string[]z₁..z_NPer-bar labels.
colorsreadonly string[]token paletteCSS color strings cycled across bars.
showTemperaturebooleanfalseRender the temperature slider.
showMaxTrickbooleanfalseRender the max-trick toggle.
initialTemperaturenumber1Seed value for the slider.
initialMaxTrickbooleantrueSeed value for the toggle.
captionReactNodeCaption below the readout summary.
frozenbooleanfalseDisable bar drag and keyboard.
precision"float64" | "float16""float64"Float precision for exp().
zMinnumber-5Lower bound on logit range.
zMaxnumber5Upper bound on logit range.
transitionTransitionSPRINGS.snapOverride bar transition.
onLogitsChange(logits: readonly number[]) => voidFires after every drag or keyboard nudge.
classNamestringMerged onto the root via cn().

Accessibility

  • Every bar is a role="slider" with aria-valuemin / aria-valuemax / aria-valuenow / aria-valuetext, aria-orientation="vertical", and an aria-label carrying logit + probability.
  • Keyboard: / nudge by 0.1, / nudge by −0.1, hold Shift to step by 1.0. Bars are tab-reachable when not frozen.
  • The SVG is role="group"; decorative artefacts (zero line, exp / prob legends, glow filter) are aria-hidden.
  • Colour is never the only signal — every logit prints in tabular monospace and the overflow warning fires independent of bar colour.
  • Motion respects prefers-reduced-motion: reduce automatically — motion/react snaps to target instead of animating.

Credits

  • Extracted from: craftingattention (app/src/lessons/primitives/viz/SoftmaxInline.tsx). Dropped the lesson chrome (SvgLabel, LabeledSlider, lesson palette tokens like --color-bar-1 / --color-fail-400 / --color-ink-200 / --color-surface-elevated), remapped surfaces to var(--cb-*) semantic tokens so consumer themes repaint freely, swapped the project-local SPRINGS.snug for the canonical SPRINGS.snap, replaced the lesson-only LabeledSlider with an inline native <input type="range">, and added the colors, labels, transition, and onLogitsChange props.