"use client"; import { motion } from "framer-motion"; import { COLORS, VizFrame } from "./common"; /** * Tiny network y = σ(w₂ · σ(w₁ x + b₁) + b₂) with chain-rule terms drawn * underneath each connection. */ export function BackpropChain({ width = 920, height = 360, }: { width?: number; height?: number; }) { const cy = 110; const stages = [ { x: 60, label: "x", note: "input" }, { x: 220, label: "z₁ = w₁x + b₁", note: "linear" }, { x: 410, label: "h = σ(z₁)", note: "activation" }, { x: 600, label: "z₂ = w₂h + b₂", note: "linear" }, { x: 790, label: "ŷ = σ(z₂)", note: "activation" }, { x: 880, label: "L(ŷ, y)", note: "loss" }, ]; return ( {/* Forward arrows */} {stages.map((s, i) => ( {s.label} {s.note} {i < stages.length - 1 ? ( ) : null} ))} forward {/* Backward gradient flow */} backward {/* Chain-rule label per arrow */} {[ { from: 5, to: 4, label: "∂L/∂ŷ" }, { from: 4, to: 3, label: "∂ŷ/∂z₂ = σ′(z₂)" }, { from: 3, to: 2, label: "∂z₂/∂h = w₂" }, { from: 2, to: 1, label: "∂h/∂z₁ = σ′(z₁)" }, { from: 1, to: 0, label: "∂z₁/∂x = w₁" }, ].map((edge, i) => { const a = stages[edge.from]; const b = stages[edge.to]; const x1 = a.x - 50; const x2 = b.x + 50; const y = cy + 70; return ( {edge.label} ); })} {/* Final derivatives */} ∂L/∂w₂ = (∂L/∂ŷ)(∂ŷ/∂z₂) · h      ∂L/∂w₁ = (∂L/∂ŷ)(∂ŷ/∂z₂)(w₂)(σ′(z₁)) · x ); }