From 05fcee5b9a74497a7096b29fbfc7ff4b6826fc86 Mon Sep 17 00:00:00 2001 From: Vijay Janapa Reddi Date: Tue, 30 Sep 2025 16:37:57 -0400 Subject: [PATCH] fix: Add missing box import and remove duplicate prints in Milestone 02 - Added 'from rich import box' import - Removed duplicate Step 1 prints from generate_xor_data() - Created MILESTONE_NARRATIVE_FLOW.md with 5-Act structure New structure creates clear narrative flow: - Act 1: The Challenge (problem + data) - Act 2: The Setup (architecture + hyperparams) - Act 3: The Experiment (training) - Act 4: The Diagnosis (results + insights) - Act 5: The Reflection (accomplishment + meaning) Visual separators between acts for clarity. --- milestones/02_xor_crisis_1969/xor_solved.py | 7 +- milestones/MILESTONE_NARRATIVE_FLOW.md | 378 ++++++++++++++++++++ 2 files changed, 379 insertions(+), 6 deletions(-) create mode 100644 milestones/MILESTONE_NARRATIVE_FLOW.md diff --git a/milestones/02_xor_crisis_1969/xor_solved.py b/milestones/02_xor_crisis_1969/xor_solved.py index 9b792637..0c695378 100755 --- a/milestones/02_xor_crisis_1969/xor_solved.py +++ b/milestones/02_xor_crisis_1969/xor_solved.py @@ -64,6 +64,7 @@ import numpy as np from rich.console import Console from rich.table import Table from rich.panel import Panel +from rich import box # Add project root to path sys.path.insert(0, os.getcwd()) @@ -80,8 +81,6 @@ console = Console() def generate_xor_data(n_samples=100): """Generate XOR dataset with slight noise.""" - console.print("\n[bold]Step 1:[/bold] Generating XOR dataset...") - # Generate each XOR case with repetition samples_per_case = n_samples // 4 @@ -109,10 +108,6 @@ def generate_xor_data(n_samples=100): X = X[indices] y = y[indices] - console.print(f" βœ“ Created [bold]{n_samples}[/bold] XOR samples") - console.print(f" βœ“ Problem: [bold yellow]NOT linearly separable[/bold yellow]") - console.print(f" βœ“ Solution: [bold green]Use hidden layers![/bold green]") - return Tensor(X), Tensor(y) diff --git a/milestones/MILESTONE_NARRATIVE_FLOW.md b/milestones/MILESTONE_NARRATIVE_FLOW.md new file mode 100644 index 00000000..19d949b4 --- /dev/null +++ b/milestones/MILESTONE_NARRATIVE_FLOW.md @@ -0,0 +1,378 @@ +# Milestone Narrative Flow + +## 🎭 The Complete Story Arc + +Each milestone should tell a complete story with 5 clear acts: + +--- + +## ACT 1: THE CHALLENGE 🎯 +**"Here's the problem we're solving"** + +```python +# 1A. Opening - Set the stage +console.print(Panel.fit( + "[bold cyan]🎯 {YEAR} - {Historical Milestone}[/bold cyan]\n\n" + "[dim]{What problem are we solving?}[/dim]\n" + "[dim]{Why does it matter?}[/dim]", + title="πŸ”₯ {Event Name}", + border_style="cyan", + box=box.DOUBLE +)) + +# 1B. The Data - What we're working with +console.print("\n[bold]πŸ“Š The Data:[/bold]") +console.print(" β€’ Dataset: {name}") +console.print(" β€’ Samples: {count}") +console.print(" β€’ Challenge: {what makes this hard}") +``` + +**Visual Separator:** +```python +console.print("\n" + "─" * 70 + "\n") +``` + +--- + +## ACT 2: THE SETUP πŸ—οΈ +**"Here's what we're building to solve it"** + +```python +# 2A. Architecture - Visual diagram +console.print("[bold]πŸ—οΈ The Architecture:[/bold]") +console.print(""" +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Input │───▢│ Process │───▢│ Output β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +""") + +# 2B. Components breakdown +console.print("\n[bold]πŸ”§ Components:[/bold]") +console.print(" β€’ Layer 1: {purpose}") +console.print(" β€’ Layer 2: {purpose}") +console.print(" β€’ Total parameters: {count}") + +# 2C. Hyperparameters +console.print("\n[bold]βš™οΈ Hyperparameters:[/bold]") +console.print(" β€’ Learning rate: {lr}") +console.print(" β€’ Epochs: {epochs}") +console.print(" β€’ Batch size: {batch_size}") +``` + +**Visual Separator:** +```python +console.print("\n" + "─" * 70 + "\n") +``` + +--- + +## ACT 3: THE EXPERIMENT πŸ”¬ +**"Here's what happens when we train"** + +```python +# 3A. Before Training - Baseline +console.print("[bold]πŸ“Œ Before Training:[/bold]") +console.print(" Initial accuracy: {acc_before:.1f}% (random guessing)") +console.print(" Initial loss: {loss_before:.4f}") + +# 3B. Training Progress +console.print("\n[bold]πŸ”₯ Training in Progress...[/bold]") +console.print("[dim](Watch the model learn!)[/dim]\n") + +# Show progress every N epochs +for epoch in range(epochs): + if epoch % (epochs // 10) == 0: + console.print(f"Epoch {epoch:3d}/{epochs} " + f"Loss: {loss:.4f} " + f"Accuracy: {acc:.1f}%") + +console.print("\n[green]βœ… Training Complete![/green]") +``` + +**Visual Separator:** +```python +console.print("\n" + "─" * 70 + "\n") +``` + +--- + +## ACT 4: THE DIAGNOSIS πŸ“Š +**"Here's what we learned from the results"** + +```python +# 4A. Results Table - The transformation +console.print("[bold]πŸ“Š The Results:[/bold]\n") + +table = Table(title="Training Outcome", box=box.ROUNDED) +table.add_column("Metric", style="cyan", width=20) +table.add_column("Before", style="yellow") +table.add_column("After", style="green") +table.add_column("Change", style="magenta") + +table.add_row("Loss", f"{loss_before:.4f}", f"{loss_after:.4f}", + f"↓ {loss_before - loss_after:.4f}") +table.add_row("Accuracy", f"{acc_before:.1f}%", f"{acc_after:.1f}%", + f"↑ {acc_after - acc_before:.1f}%") + +console.print(table) + +# 4B. Sample Predictions - Proof it works +console.print("\n[bold]πŸ” Sample Predictions:[/bold]") +console.print("[dim](Seeing is believing!)[/dim]\n") + +for i in range(10): + true_val = y_test[i] + pred_val = predictions[i] + status = "βœ“" if pred_val == true_val else "βœ—" + color = "green" if pred_val == true_val else "red" + console.print(f" {status} True: {true_val}, Predicted: {pred_val}", + style=color) + +# 4C. Key Insights - What this tells us +console.print("\n[bold]πŸ’‘ Key Insights:[/bold]") +console.print(" β€’ Insight 1: {observation}") +console.print(" β€’ Insight 2: {observation}") +console.print(" β€’ Insight 3: {observation}") +``` + +**Visual Separator:** +```python +console.print("\n" + "─" * 70 + "\n") +``` + +--- + +## ACT 5: THE REFLECTION 🌟 +**"Here's what you accomplished and what it means"** + +```python +console.print(Panel.fit( + "[bold green]πŸŽ‰ Success! {What You Did}![/bold green]\n\n" + + f"Final accuracy: [bold]{accuracy:.1f}%[/bold]\n\n" + + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n" + + "[bold]πŸ’‘ What YOU Just Accomplished:[/bold]\n" + " βœ“ {Specific achievement 1}\n" + " βœ“ {Specific achievement 2}\n" + " βœ“ {Specific achievement 3}\n" + " βœ“ {Specific achievement 4}\n\n" + + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n" + + "[bold]πŸŽ“ Why This Matters:[/bold]\n" + " {Historical significance}\n" + " {Technical significance}\n" + " {Connection to modern AI}\n\n" + + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n" + + "[bold]πŸ“Œ The Key Insight:[/bold]\n" + " {Main technical/conceptual takeaway}\n" + " {Limitation or tradeoff}\n\n" + + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n" + + "[bold]πŸš€ What's Next:[/bold]\n" + "[dim]Milestone {N+1} will {preview next challenge}[/dim]", + + title="🌟 {YEAR} {Milestone} Complete", + border_style="green", + box=box.DOUBLE +)) +``` + +--- + +## πŸ“ Complete Example + +```python +def main(): + # ═══════════════════════════════════════════════════════════ + # ACT 1: THE CHALLENGE + # ═══════════════════════════════════════════════════════════ + + console.print(Panel.fit( + "[bold cyan]🎯 1957 - The First Neural Network[/bold cyan]\n\n" + "[dim]Can a machine learn from examples to classify data?[/dim]\n" + "[dim]Frank Rosenblatt's perceptron attempts to answer this![/dim]", + title="πŸ”₯ 1957 Perceptron Revolution", + border_style="cyan", + box=box.DOUBLE + )) + + console.print("\n[bold]πŸ“Š The Data:[/bold]") + X, y = generate_data(100) + console.print(" β€’ Dataset: Linearly separable 2D points") + console.print(f" β€’ Samples: {len(X.data)}") + console.print(" β€’ Challenge: Learn decision boundary from examples") + + console.print("\n" + "─" * 70 + "\n") + + # ═══════════════════════════════════════════════════════════ + # ACT 2: THE SETUP + # ═══════════════════════════════════════════════════════════ + + console.print("[bold]πŸ—οΈ The Architecture:[/bold]") + console.print(""" + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ Input β”‚ β”‚ Weights β”‚ β”‚ Output β”‚ + β”‚ (x₁, xβ‚‚) │───▢│ w₁·x₁ + wβ‚‚Β·x₂│───▢│ Ε· β”‚ + β”‚ 2 features β”‚ β”‚ + bias β”‚ β”‚ binary β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + """) + + console.print("[bold]πŸ”§ Components:[/bold]") + console.print(" β€’ Single layer: Maps 2D input β†’ 1D output") + console.print(" β€’ Linear transformation: Weighted sum") + console.print(" β€’ Total parameters: 3 (2 weights + 1 bias)") + + console.print("\n[bold]βš™οΈ Hyperparameters:[/bold]") + console.print(" β€’ Learning rate: 0.1") + console.print(" β€’ Epochs: 100") + console.print(" β€’ Optimizer: Gradient descent") + + console.print("\n" + "─" * 70 + "\n") + + # ═══════════════════════════════════════════════════════════ + # ACT 3: THE EXPERIMENT + # ═══════════════════════════════════════════════════════════ + + model = Perceptron(2, 1) + acc_before = evaluate(model, X, y) + + console.print("[bold]πŸ“Œ Before Training:[/bold]") + console.print(f" Initial accuracy: {acc_before:.1f}% (random guessing)") + console.print(" Model has random weights - no knowledge yet") + + console.print("\n[bold]πŸ”₯ Training in Progress...[/bold]") + console.print("[dim](Watch gradient descent optimize the weights!)[/dim]\n") + + history = train(model, X, y, epochs=100, lr=0.1) + + console.print("\n[green]βœ… Training Complete![/green]") + + console.print("\n" + "─" * 70 + "\n") + + # ═══════════════════════════════════════════════════════════ + # ACT 4: THE DIAGNOSIS + # ═══════════════════════════════════════════════════════════ + + acc_after, predictions = evaluate(model, X, y, return_preds=True) + + console.print("[bold]πŸ“Š The Results:[/bold]\n") + + table = Table(title="Training Outcome", box=box.ROUNDED) + table.add_column("Metric", style="cyan", width=20) + table.add_column("Before", style="yellow") + table.add_column("After", style="green") + table.add_column("Change", style="magenta") + + table.add_row("Accuracy", f"{acc_before:.1f}%", f"{acc_after:.1f}%", + f"↑ {acc_after - acc_before:.1f}%") + + console.print(table) + + console.print("\n[bold]πŸ” Sample Predictions:[/bold]") + console.print("[dim](First 10 samples)[/dim]\n") + + for i in range(10): + true_val = int(y.data[i]) + pred_val = int(predictions[i]) + status = "βœ“" if pred_val == true_val else "βœ—" + color = "green" if pred_val == true_val else "red" + console.print(f" {status} True: {true_val}, Predicted: {pred_val}", + style=color) + + console.print("\n[bold]πŸ’‘ Key Insights:[/bold]") + console.print(" β€’ The model LEARNED from data (not programmed!)") + console.print(" β€’ Weights changed from random β†’ meaningful values") + console.print(" β€’ Simple gradient descent found the solution") + + console.print("\n" + "─" * 70 + "\n") + + # ═══════════════════════════════════════════════════════════ + # ACT 5: THE REFLECTION + # ═══════════════════════════════════════════════════════════ + + console.print(Panel.fit( + "[bold green]πŸŽ‰ Success! Your Perceptron Learned to Classify![/bold green]\n\n" + + f"Final accuracy: [bold]{acc_after:.1f}%[/bold]\n\n" + + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n" + + "[bold]πŸ’‘ What YOU Just Accomplished:[/bold]\n" + " βœ“ Built the FIRST neural network (1957 Rosenblatt)\n" + " βœ“ Implemented forward pass with YOUR Tensor\n" + " βœ“ Used gradient descent to optimize weights\n" + " βœ“ Watched machine learning happen in real-time!\n\n" + + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n" + + "[bold]πŸŽ“ Why This Matters:[/bold]\n" + " This is the FOUNDATION of all neural networks.\n" + " Every model from GPT-4 to AlphaGo uses this same\n" + " core idea: adjust weights via gradients to minimize error.\n\n" + + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n" + + "[bold]πŸ“Œ The Key Insight:[/bold]\n" + " The architecture is simple (~10 lines of code).\n" + " The MAGIC is the training loop: Forward β†’ Loss β†’ Backward β†’ Update\n" + " \n" + " [yellow]Limitation:[/yellow] Single layers can only solve linearly separable problems.\n\n" + + "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n" + + "[bold]πŸš€ What's Next:[/bold]\n" + "[dim]Milestone 02 shows what happens when data ISN'T linearly separable...\n" + "The XOR problem that killed AI for 17 years![/dim]", + + title="🌟 1957 Perceptron Complete", + border_style="green", + box=box.DOUBLE + )) +``` + +--- + +## 🎨 Visual Design Principles + +### Separator Lines +Use horizontal rules between acts: +```python +console.print("\n" + "─" * 70 + "\n") +``` + +### Section Headers +Consistent emoji + bold format: +```python +console.print("[bold]πŸ”§ Components:[/bold]") +console.print("[bold]πŸ“Š The Results:[/bold]") +``` + +### Sub-sections +Use dim text for context: +```python +console.print("[dim](Watch the model learn!)[/dim]") +``` + +### Internal Separators in Final Panel +Use unicode line in celebration panel: +```python +"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n" +``` + +--- + +## 🎯 The Student Journey + +**Act 1:** "Oh, I understand the problem!" +**Act 2:** "I see what we're building to solve it!" +**Act 3:** "It's actually working - look at the progress!" +**Act 4:** "Here's the proof - numbers and examples!" +**Act 5:** "WOW - I just accomplished something REAL!" + +Each act builds on the previous, creating a complete narrative arc that students can follow and feel proud of completing.