Softmax Temperature Viz
Bar chart of temperature-scaled softmax with two modes. Explore lets the learner drag each bar vertically to change its logit, scrub the temperature slider, and toggle the max trick (subtract max(z / T) before exp) to watch exp() actually overflow when the trick is off. Predict runs six MCQ rounds on softmax intuition — temperature halving, shift-invariance, argmax limit at extreme T, sign flip, uniform input, near-zero T — and morphs the chart from question state to the reveal state so the answer is visible alongside the explanation.
Softmax temperature visualisation with 6 predict rounds.
cat leads. Drag bars to change logits, slide temperature to control how decisive the mapping is.
1.00
Customize
Distribution
skewed
1.00
Stability
Mode
explore
Installation
npx shadcn@latest add https://craftbits.dev/r/softmax-temperature-viz.jsonUsage
import { SoftmaxTemperatureViz } from "@craft-bits/viz/softmax-temperature-viz";
<SoftmaxTemperatureViz />Override the initial logits, palette, and starting mode:
<SoftmaxTemperatureViz
initialLogits={[3.0, 1.5, 0.5, 0.0, -0.5]}
labels={["cat", "dog", "fox", "fish", "bird"]}
defaultMode="predict"
onPredictComplete={({ correct, total }) => {
console.log(`${correct} / ${total}`);
}}
/>Drop in a custom predict bank:
<SoftmaxTemperatureViz
predictRounds={[
{
q: "Does doubling T make the distribution flatter or sharper?",
opts: ["Sharper", "Flatter"],
answer: -1,
logits: [2, 1, 0, -1],
T: 1,
revealT: 2,
maxTrick: true,
reveal: "Higher T compresses the gap between scaled logits, flattening the distribution toward uniform.",
},
]}
/>Understanding the component
- Temperature-scaled softmax. Each bar is
exp(z_i / T)normalised by the sum of all exponentials. Lowering T amplifies the gap between logits before normalisation — the highest one wins outright. Raising T compresses gaps, so every class limits to1 / N. - Draggable bars. In explore mode each bar carries
role="slider". Drag vertically with the pointer, orTabto a bar and use the arrow keys (Shiftsteps by1.0, plain steps by0.1) to change its logit. The chart animates withSPRINGS.snapon every nudge; reduced-motion users snap instantly. - Max-subtraction trick. When ON, the implementation subtracts the per-row maximum scaled logit before
exp(the log-sum-exp trick). When OFF, large logits or tiny T push the exponential past the float64 limit and produceInfinity— theexprow turns red and an overflow callout fades in. - Per-bar readout. Below each bar: the
expvalue, the probability, and a thin probability fill bar so the user can compare relative scale even when the largest bar saturates the chart. - Predict mode. Six canned rounds test softmax intuition. The chart shows the question's logit/T state while the learner picks an option; after
Check, the chart morphs (whenrevealLogitsorrevealTis set) so the answer is visible, not just told. AScoreDotsrow tracks per-round correctness andDoneCardsummarises the run. - Narration. A polite live region carries a state-aware narration: which class dominates, whether the distribution is near-uniform or near-argmax, and a specific overflow hint when the max trick is off and
exp()has actually blown up.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
initialLogits | readonly number[] | [2, 1, 0.3, -0.5, -1] | Initial logits for explore mode. |
labels | readonly string[] | z₁..z_N | Per-bar labels. |
colors | readonly string[] | accent/info/success/warning/error | CSS colour strings cycled across bars. |
initialTemperature | number | 1 | Initial T for explore mode. |
initialMaxTrick | boolean | true | Initial max-trick state for explore mode. |
zMin | number | -5 | Lower bound on draggable logit range. |
zMax | number | 5 | Upper bound on draggable logit range. |
tempRange | readonly [number, number] | [0.1, 5] | Slider extents. |
predictRounds | readonly SoftmaxTemperatureVizPredictRound[] | 6 rounds | Override the predict-mode question bank. |
defaultMode | SoftmaxTemperatureVizMode | "explore" | Mode visible on first render. |
transition | Transition | SPRINGS.snap | Override the spring for bar transitions. |
onModeChange | (mode) => void | — | Fires when the active mode changes. |
onPredictComplete | (score) => void | — | Fires when the learner finishes all predict rounds. |
className | string | — | Merged onto the root via cn(). |
Accessibility
- The mode strip is a
role="group"witharia-pressedon eachModeButton, so screen-reader users can announce and switch modes via keyboard. - Every bar is a
role="slider"witharia-valuemin/aria-valuemax/aria-valuenowand anaria-labelof"z₁: logit 2.0, probability 0.50"so colour is never the only signal. - Keyboard: bars are reachable via
Tab;↑/→nudge by0.1,↓/←nudge by−0.1, holdShiftto step by1.0. The temperature slider is a native<input type="range">. - A polite live region carries the narration so assistive-tech users hear which class dominates, when the distribution is near-uniform, and when overflow has occurred.
- Option buttons in predict mode expose
aria-pressedfor selection and use a coloured border + background alongside aFeedbackBadgeso correctness is never colour-only. - Every interactive control has a ≥ 32×32px hit area.
- Motion respects
prefers-reduced-motion: reduce.
Credits
- Extracted from:
craftingattention(app/src/lessons/primitives/viz/SoftmaxTemperatureViz.tsx). The source was a lesson primitive that consumedModeStrip/ChallengeBtn/FeedbackBadge/ScoreDots/DoneCard/usePredictRoundsfrom the lesson'sConstructionPrimitivesmodule,TogglePillandLabeledSliderchrome fromcomponents/ui, anSvgLabelprimitive, and palette tokens like--color-bar-1..5/--color-success-500/--color-fail-500/--color-ink-200. The viz extract drops every project-specific dependency — it inlines token-styledModeButton/OptionButton/PrimaryButton/SecondaryButton/FeedbackBadge/ScoreDots/DoneCardand a native<input type="range">so the component has no source-project imports. The inline{ type: "spring", stiffness: 340, damping: 28 }is replaced bySPRINGS.snapfrom@craft-bits/core/motion; the per-bar palette is remapped to a five-step default cycle of--cb-accent/--cb-info/--cb-success/--cb-warning/--cb-errorwith acolorsprop override. Hard-coded narration is preserved butlessonId/phaseId/cardIndexprops are stripped, and the question bank is exposed aspredictRoundsso consumers can swap it.onModeChangeandonPredictCompletecallbacks lift score state out of the component.