mirror of
https://github.com/MLSysBook/TinyTorch.git
synced 2026-06-03 23:21:06 -05:00
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.
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
|
||||
378
milestones/MILESTONE_NARRATIVE_FLOW.md
Normal file
378
milestones/MILESTONE_NARRATIVE_FLOW.md
Normal file
@@ -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.
|
||||
Reference in New Issue
Block a user