Spaces:
Running
Running
// Complete Walkthrough Mode Implementation | |
// This replaces the incomplete walkthrough section in index.html | |
// Walkthrough Mode functionality | |
let walkthroughActive = false; | |
let walkthroughStep = 0; | |
let walkthroughTutorial = null; | |
let walkthroughTrainingSpeed = 2000; // Much slower training speed for walkthrough | |
let walkthroughInterval = null; | |
let walkthroughExplanationMode = false; | |
const walkthroughTutorials = { | |
basics: { | |
title: 'Neural Network Basics', | |
task: 'and', // Use AND gate for demonstration | |
steps: [ | |
{ | |
title: 'Welcome to Neural Networks! π§ ', | |
content: 'Neural networks are inspired by the human brain. They consist of layers of interconnected neurons that process information. We\'ll use a simple AND gate to learn how they work step by step!', | |
element: null, | |
position: 'center', | |
action: 'start' | |
}, | |
{ | |
title: 'Input Layer (Blue Circles)', | |
content: 'These blue circles are input neurons. For our AND gate, we have 2 inputs that can be either 0 or 1. Watch the numbers inside - they show the current input values being processed!', | |
element: '#networkCanvas', | |
position: 'right', | |
highlight: {x: 50, y: 50, width: 100, height: 200}, | |
action: 'highlight_inputs' | |
}, | |
{ | |
title: 'Hidden Layer (Green Circles)', | |
content: 'These green neurons are the "thinking" layer. They receive signals from inputs, multiply them by weights, add biases, and decide how "excited" to get. The numbers show their activation levels!', | |
element: '#networkCanvas', | |
position: 'left', | |
highlight: {x: 150, y: 50, width: 100, height: 200}, | |
action: 'highlight_hidden' | |
}, | |
{ | |
title: 'Output Layer (Purple Circle)', | |
content: 'This purple neuron gives us the final answer! For AND gate, it should output 1 only when BOTH inputs are 1. Right now it\'s making random guesses - that\'s why we need to train it!', | |
element: '#networkCanvas', | |
position: 'left', | |
highlight: {x: 250, y: 120, width: 100, height: 60}, | |
action: 'highlight_output' | |
}, | |
{ | |
title: 'Connections (Colored Lines)', | |
content: 'These lines are connections with "weights". Green lines are positive (excite the next neuron), red lines are negative (inhibit it). Thicker lines = stronger connections. The AI learns by adjusting these!', | |
element: '#networkCanvas', | |
position: 'right', | |
highlight: {x: 0, y: 0, width: 400, height: 300}, | |
action: 'highlight_weights' | |
}, | |
{ | |
title: 'Training Data', | |
content: 'Here\'s our training data! Each card shows: input values β expected output. The AI will see these examples and learn the AND gate pattern. Notice the "Raw" prediction - it starts random!', | |
element: '#taskOutput', | |
position: 'top', | |
highlight: {x: -10, y: -10, width: 'auto', height: 'auto'}, | |
action: 'highlight_data' | |
}, | |
{ | |
title: 'Let\'s Start Training!', | |
content: 'Now I\'ll start training VERY slowly so you can see every step. Watch how the neurons\' values change, connections strengthen/weaken, and the loss decreases as the AI learns!', | |
element: '#trainBtn', | |
position: 'top', | |
highlight: {x: -5, y: -5, width: 'auto', height: 'auto'}, | |
action: 'start_training' | |
} | |
] | |
}, | |
training: { | |
title: 'How Training Works', | |
task: 'xor', // Use XOR for complexity | |
steps: [ | |
{ | |
title: 'Welcome to AI Training! π―', | |
content: 'Training is how AI learns! We\'ll use the XOR gate - a challenging problem that requires the AI to think in complex ways. Let\'s see how the network learns step by step.', | |
element: null, | |
position: 'center', | |
action: 'start' | |
}, | |
{ | |
title: 'Forward Propagation', | |
content: 'Step 1: Forward pass! The input flows through the network like water through pipes. Each neuron receives inputs, multiplies by weights, adds bias, and applies activation. Watch the flow!', | |
element: '#networkCanvas', | |
position: 'right', | |
highlight: {x: 0, y: 0, width: 400, height: 300}, | |
action: 'demo_forward' | |
}, | |
{ | |
title: 'Making a Prediction', | |
content: 'The output neuron gives us a prediction! For XOR: 0,0β0, 0,1β1, 1,0β1, 1,1β0. Right now it\'s wrong - see the red "Wrong" status. The raw output should be close to the target!', | |
element: '#taskOutput', | |
position: 'top', | |
highlight: {x: -10, y: -10, width: 'auto', height: 'auto'}, | |
action: 'show_prediction' | |
}, | |
{ | |
title: 'Calculating Loss', | |
content: 'Loss measures how wrong we are! It\'s the difference between prediction and target, squared. High loss = very wrong. Low loss = very right. Watch this number in the stats panel!', | |
element: '#lossValue', | |
position: 'bottom', | |
highlight: {x: -10, y: -10, width: 'auto', height: 'auto'}, | |
action: 'show_loss' | |
}, | |
{ | |
title: 'Backpropagation Magic', | |
content: 'Step 2: Backward pass! The AI traces back through the network asking "who\'s responsible for this error?" and adjusts weights accordingly. This is backpropagation - the heart of deep learning!', | |
element: '#networkCanvas', | |
position: 'left', | |
highlight: {x: 0, y: 0, width: 400, height: 300}, | |
action: 'demo_backward' | |
}, | |
{ | |
title: 'Weight Updates', | |
content: 'The AI nudges each weight slightly in the direction that reduces error. Good connections get stronger, bad ones get weaker. Watch the line colors and thickness change!', | |
element: '#networkCanvas', | |
position: 'right', | |
highlight: {x: 0, y: 0, width: 400, height: 300}, | |
action: 'show_weight_updates' | |
}, | |
{ | |
title: 'Learning Progress', | |
content: 'Each training cycle is called an "epoch". Watch the loss chart - it should generally go down as the AI gets better! Sometimes it goes up temporarily - that\'s normal during learning.', | |
element: '#lossChart', | |
position: 'right', | |
highlight: {x: -10, y: -10, width: 'auto', height: 'auto'}, | |
action: 'show_progress' | |
}, | |
{ | |
title: 'Continuous Learning', | |
content: 'Now watch it train continuously! Each step: forward pass β calculate loss β backward pass β update weights β repeat. This is how all AI learns, from image recognition to chatbots!', | |
element: null, | |
position: 'center', | |
action: 'continuous_training' | |
} | |
] | |
}, | |
visualization: { | |
title: 'Understanding the Visualizations', | |
task: 'classification', // Use 2D classification for visual demo | |
steps: [ | |
{ | |
title: 'Reading AI Visualizations π', | |
content: 'Visualizations help us understand what\'s happening inside AI! We\'ll use 2D classification - separating red and blue points in space - to see how neural networks think.', | |
element: null, | |
position: 'center', | |
action: 'start' | |
}, | |
{ | |
title: 'Network Diagram - The Brain Map', | |
content: 'This shows the AI\'s structure! Circles = neurons (processing units), Lines = connections (information pathways). Colors show activity levels: bright = excited, dark = calm.', | |
element: '#networkCanvas', | |
position: 'right', | |
highlight: {x: 0, y: 0, width: 400, height: 300}, | |
action: 'explain_network' | |
}, | |
{ | |
title: 'Data Visualization - The Problem Space', | |
content: 'This 2D plot shows our data! Red dots should be classified as 0, blue dots as 1. The AI needs to learn an invisible boundary that separates them correctly.', | |
element: '#dataViz', | |
position: 'left', | |
highlight: {x: -10, y: -10, width: 'auto', height: 'auto'}, | |
action: 'explain_data_viz' | |
}, | |
{ | |
title: 'Training Progress Chart', | |
content: 'The loss chart shows learning over time! Starting high (confused), gradually decreasing (getting smarter). Flat periods mean it\'s thinking, sharp drops mean breakthroughs!', | |
element: '#lossChart', | |
position: 'right', | |
highlight: {x: -10, y: -10, width: 'auto', height: 'auto'}, | |
action: 'explain_loss_chart' | |
}, | |
{ | |
title: 'Prediction Cards - The Report Card', | |
content: 'Each card shows: the input β expected output. "Raw" = neuron\'s actual output (0-1), "Predicted" = final decision, Status = right/wrong. Green borders = correct predictions!', | |
element: '#taskOutput', | |
position: 'top', | |
highlight: {x: -10, y: -10, width: 'auto', height: 'auto'}, | |
action: 'explain_predictions' | |
}, | |
{ | |
title: 'Stats Panel - The Dashboard', | |
content: 'Epochs = training cycles completed, Loss = how wrong we are, Accuracy = % correct predictions, Current = which example we\'re processing now. These tell the whole story!', | |
element: '.stats-grid', | |
position: 'bottom', | |
highlight: {x: -10, y: -10, width: 'auto', height: 'auto'}, | |
action: 'explain_stats' | |
}, | |
{ | |
title: 'Watching It All Together', | |
content: 'Now watch everything update in harmony! Network neurons fire, data points get classified, loss decreases, accuracy increases. You\'re seeing the birth of artificial intelligence!', | |
element: null, | |
position: 'center', | |
action: 'full_demo' | |
} | |
] | |
}, | |
logic: { | |
title: 'Logic Gates Deep Dive', | |
task: 'xor', // Start with XOR as the most interesting | |
steps: [ | |
{ | |
title: 'Logic Gates - AI\'s Building Blocks π', | |
content: 'Logic gates are the foundation of all computing! We\'ll explore how neural networks learn AND, OR, and the famous XOR gate - the problem that sparked the deep learning revolution!', | |
element: null, | |
position: 'center', | |
action: 'start' | |
}, | |
{ | |
title: 'The XOR Challenge', | |
content: 'XOR (exclusive or) outputs 1 when inputs are different. Seems simple, but it stumped early AI for decades! It\'s not "linearly separable" - you can\'t draw a straight line to separate the outputs.', | |
element: '#taskOutput', | |
position: 'top', | |
highlight: {x: -10, y: -10, width: 'auto', height: 'auto'}, | |
action: 'explain_xor' | |
}, | |
{ | |
title: 'Why XOR Needs Deep Networks', | |
content: 'Look at our network: 2β12β8β1. We need these hidden layers! Each layer transforms the data, and together they can solve XOR. Single-layer networks can\'t do this!', | |
element: '#networkCanvas', | |
position: 'right', | |
highlight: {x: 0, y: 0, width: 400, height: 300}, | |
action: 'explain_depth' | |
}, | |
{ | |
title: 'Layer 1: Feature Detection', | |
content: 'The first hidden layer (12 neurons) learns to detect patterns in the input. Some neurons might learn "both inputs high", others "both inputs low", etc. These become building blocks!', | |
element: '#networkCanvas', | |
position: 'left', | |
highlight: {x: 100, y: 50, width: 80, height: 200}, | |
action: 'explain_layer1' | |
}, | |
{ | |
title: 'Layer 2: Combination Logic', | |
content: 'The second hidden layer (8 neurons) combines the features from layer 1. It might learn rules like "if feature A is active but feature B isn\'t, then activate". This creates complex logic!', | |
element: '#networkCanvas', | |
position: 'right', | |
highlight: {x: 200, y: 80, width: 80, height: 140}, | |
action: 'explain_layer2' | |
}, | |
{ | |
title: 'Output: The Final Decision', | |
content: 'The output neuron combines all the complex features into a final decision. It learns to say "yes" (1) when the XOR pattern is detected, "no" (0) otherwise. Magic!', | |
element: '#networkCanvas', | |
position: 'left', | |
highlight: {x: 300, y: 120, width: 80, height: 60}, | |
action: 'explain_output' | |
}, | |
{ | |
title: 'Training Process', | |
content: 'Watch as the network slowly learns XOR! Early on, it makes random guesses. Gradually, it discovers the pattern. You\'ll see the accuracy climb from 25% (random) to 100% (perfect)!', | |
element: '#accuracyValue', | |
position: 'bottom', | |
highlight: {x: -10, y: -10, width: 'auto', height: 'auto'}, | |
action: 'demo_training' | |
}, | |
{ | |
title: 'The Learning Moment', | |
content: 'There\'s often a "eureka moment" where the AI suddenly "gets it" - loss drops rapidly, accuracy jumps! This is the network discovering the XOR pattern. It\'s like watching intelligence emerge!', | |
element: '#lossChart', | |
position: 'right', | |
highlight: {x: -10, y: -10, width: 'auto', height: 'auto'}, | |
action: 'show_breakthrough' | |
} | |
] | |
} | |
}; | |
// Walkthrough DOM elements | |
const walkthroughOverlay = document.getElementById('walkthroughOverlay'); | |
const walkthroughHighlight = document.getElementById('walkthroughHighlight'); | |
const walkthroughPopup = document.getElementById('walkthroughPopup'); | |
const walkthroughTitle = document.getElementById('walkthroughTitle'); | |
const walkthroughContent = document.getElementById('walkthroughContent'); | |
const walkthroughProgress = document.getElementById('walkthroughProgress'); | |
const walkthroughStepSpan = document.getElementById('walkthroughStep'); | |
const walkthroughTotal = document.getElementById('walkthroughTotal'); | |
const walkthroughIndicator = document.getElementById('walkthroughIndicator'); | |
const walkthroughPrev = document.getElementById('walkthroughPrev'); | |
const walkthroughNext = document.getElementById('walkthroughNext'); | |
const walkthroughSkip = document.getElementById('walkthroughSkip'); | |
// Start walkthrough function | |
function startWalkthrough(tutorialId) { | |
const tutorial = walkthroughTutorials[tutorialId]; | |
if (!tutorial) return; | |
walkthroughActive = true; | |
walkthroughTutorial = tutorial; | |
walkthroughStep = 0; | |
walkthroughExplanationMode = true; | |
// Load the tutorial task if specified | |
if (tutorial.task) { | |
currentCategory = 'fundamentals'; // Most tutorials use fundamentals | |
selectTask(tutorial.task); | |
// Wait a moment for task to load | |
setTimeout(() => { | |
showWalkthroughStep(); | |
}, 500); | |
} else { | |
showWalkthroughStep(); | |
} | |
// Hide walkthrough mode menu | |
document.getElementById('walkthroughMode').style.display = 'none'; | |
// Show indicator | |
walkthroughIndicator.style.display = 'block'; | |
} | |
// Show current walkthrough step | |
function showWalkthroughStep() { | |
if (!walkthroughTutorial || walkthroughStep >= walkthroughTutorial.steps.length) { | |
endWalkthrough(); | |
return; | |
} | |
const step = walkthroughTutorial.steps[walkthroughStep]; | |
// Update progress | |
walkthroughProgress.style.display = 'block'; | |
walkthroughStepSpan.textContent = walkthroughStep + 1; | |
walkthroughTotal.textContent = walkthroughTutorial.steps.length; | |
// Update popup content | |
walkthroughTitle.textContent = step.title; | |
walkthroughContent.textContent = step.content; | |
// Handle special actions | |
if (step.action) { | |
executeWalkthroughAction(step.action); | |
} | |
// Position popup and highlight | |
if (step.element) { | |
positionWalkthroughElements(step); | |
} else { | |
// Center popup for intro steps | |
centerWalkthroughPopup(); | |
walkthroughHighlight.style.display = 'none'; | |
} | |
// Show overlay and popup | |
walkthroughOverlay.style.display = 'block'; | |
walkthroughPopup.style.display = 'block'; | |
// Update buttons | |
walkthroughPrev.style.display = walkthroughStep > 0 ? 'block' : 'none'; | |
walkthroughNext.textContent = walkthroughStep === walkthroughTutorial.steps.length - 1 ? 'Finish' : 'Next'; | |
} | |
// Position walkthrough elements | |
function positionWalkthroughElements(step) { | |
const element = document.querySelector(step.element); | |
if (!element) return; | |
const rect = element.getBoundingClientRect(); | |
const popup = walkthroughPopup; | |
// Position highlight | |
if (step.highlight) { | |
walkthroughHighlight.style.display = 'block'; | |
if (step.highlight.width === 'auto') { | |
walkthroughHighlight.style.left = (rect.left - 10) + 'px'; | |
walkthroughHighlight.style.top = (rect.top - 10) + 'px'; | |
walkthroughHighlight.style.width = (rect.width + 20) + 'px'; | |
walkthroughHighlight.style.height = (rect.height + 20) + 'px'; | |
} else { | |
walkthroughHighlight.style.left = (rect.left + step.highlight.x) + 'px'; | |
walkthroughHighlight.style.top = (rect.top + step.highlight.y) + 'px'; | |
walkthroughHighlight.style.width = step.highlight.width + 'px'; | |
walkthroughHighlight.style.height = step.highlight.height + 'px'; | |
} | |
} else { | |
walkthroughHighlight.style.display = 'none'; | |
} | |
// Position popup based on position preference | |
popup.className = 'walkthrough-popup ' + step.position; | |
const popupRect = popup.getBoundingClientRect(); | |
let left, top; | |
switch (step.position) { | |
case 'top': | |
left = rect.left + rect.width / 2 - popupRect.width / 2; | |
top = rect.top - popupRect.height - 20; | |
break; | |
case 'bottom': | |
left = rect.left + rect.width / 2 - popupRect.width / 2; | |
top = rect.bottom + 20; | |
break; | |
case 'left': | |
left = rect.left - popupRect.width - 20; | |
top = rect.top + rect.height / 2 - popupRect.height / 2; | |
break; | |
case 'right': | |
left = rect.right + 20; | |
top = rect.top + rect.height / 2 - popupRect.height / 2; | |
break; | |
default: | |
centerWalkthroughPopup(); | |
return; | |
} | |
// Keep popup on screen | |
left = Math.max(10, Math.min(left, window.innerWidth - popupRect.width - 10)); | |
top = Math.max(10, Math.min(top, window.innerHeight - popupRect.height - 10)); | |
popup.style.left = left + 'px'; | |
popup.style.top = top + 'px'; | |
} | |
// Center walkthrough popup | |
function centerWalkthroughPopup() { | |
const popup = walkthroughPopup; | |
popup.className = 'walkthrough-popup center'; | |
popup.style.left = '50%'; | |
popup.style.top = '50%'; | |
popup.style.transform = 'translate(-50%, -50%)'; | |
} | |
// Execute special walkthrough actions | |
function executeWalkthroughAction(action) { | |
switch (action) { | |
case 'start': | |
// Reset network and prepare for demonstration | |
if (currentTask && network) { | |
reset(); | |
} | |
break; | |
case 'start_training': | |
// Start very slow training for educational purposes | |
if (!isTraining && currentTask) { | |
trainBtn.click(); | |
} | |
break; | |
case 'demo_forward': | |
// Slow down even more to show forward propagation | |
walkthroughTrainingSpeed = 3000; | |
break; | |
case 'demo_backward': | |
// Highlight the backward pass concept | |
addWalkthroughExplanation('Backpropagation traces the error backwards through each connection, calculating how much each weight contributed to the mistake.'); | |
break; | |
case 'show_weight_updates': | |
// Highlight weight changes | |
addWalkthroughExplanation('Watch the connection lines change! Thicker lines = stronger weights, colors show positive (green) vs negative (red) influence.'); | |
break; | |
case 'continuous_training': | |
// Return to normal-ish speed but still educational | |
walkthroughTrainingSpeed = 1000; | |
break; | |
case 'explain_network': | |
// Add network explanation overlay | |
addWalkthroughExplanation('Bright neurons are highly activated (excited), dark neurons are inactive (calm). The patterns show how information flows!'); | |
break; | |
case 'explain_xor': | |
// Special explanation for XOR challenge | |
addWalkthroughExplanation('XOR is special! Unlike AND/OR, you cannot draw a single straight line to separate the correct outputs. This requires complex thinking!'); | |
break; | |
case 'demo_training': | |
// Start training and monitor for breakthrough moments | |
if (!isTraining && currentTask) { | |
trainBtn.click(); | |
monitorTrainingProgress(); | |
} | |
break; | |
} | |
} | |
// Add temporary explanation overlay | |
function addWalkthroughExplanation(text) { | |
const explanation = document.createElement('div'); | |
explanation.style.cssText = ` | |
position: fixed; | |
bottom: 100px; | |
left: 50%; | |
transform: translateX(-50%); | |
background: rgba(16, 185, 129, 0.95); | |
color: white; | |
padding: 1rem 2rem; | |
border-radius: 0.5rem; | |
font-size: 0.9rem; | |
max-width: 400px; | |
text-align: center; | |
z-index: 10003; | |
animation: fadeInOut 4s ease-in-out; | |
`; | |
explanation.textContent = text; | |
document.body.appendChild(explanation); | |
setTimeout(() => { | |
if (explanation.parentNode) { | |
explanation.parentNode.removeChild(explanation); | |
} | |
}, 4000); | |
} | |
// Add CSS animation for explanations | |
const walkthroughStyle = document.createElement('style'); | |
walkthroughStyle.textContent = ` | |
@keyframes fadeInOut { | |
0% { opacity: 0; transform: translateX(-50%) translateY(20px); } | |
10% { opacity: 1; transform: translateX(-50%) translateY(0); } | |
90% { opacity: 1; transform: translateX(-50%) translateY(0); } | |
100% { opacity: 0; transform: translateX(-50%) translateY(-20px); } | |
} | |
`; | |
document.head.appendChild(walkthroughStyle); | |
// Monitor training for educational moments | |
function monitorTrainingProgress() { | |
if (!walkthroughActive) return; | |
const checkProgress = () => { | |
if (!isTraining || !walkthroughActive) return; | |
// Look for breakthrough moments (rapid loss decrease) | |
if (lossHistory.length > 10) { | |
const recent = lossHistory.slice(-5); | |
const older = lossHistory.slice(-10, -5); | |
const recentAvg = recent.reduce((a, b) => a + b) / recent.length; | |
const olderAvg = older.reduce((a, b) => a + b) / older.length; | |
if (olderAvg > 0.5 && recentAvg < 0.1) { | |
addWalkthroughExplanation('π Breakthrough moment! The AI just discovered the pattern - watch the loss plummet!'); | |
} | |
} | |
// Check for high accuracy achievements | |
if (accuracy > 0.9 && epoch > 50) { | |
addWalkthroughExplanation('π― Excellent! The AI has mastered this pattern with over 90% accuracy!'); | |
} | |
setTimeout(checkProgress, 2000); | |
}; | |
setTimeout(checkProgress, 5000); | |
} | |
// Navigation functions | |
function nextWalkthroughStep() { | |
walkthroughStep++; | |
showWalkthroughStep(); | |
} | |
function prevWalkthroughStep() { | |
if (walkthroughStep > 0) { | |
walkthroughStep--; | |
showWalkthroughStep(); | |
} | |
} | |
function endWalkthrough() { | |
walkthroughActive = false; | |
walkthroughTutorial = null; | |
walkthroughStep = 0; | |
walkthroughExplanationMode = false; | |
walkthroughTrainingSpeed = 2000; // Reset to slow but not too slow | |
// Hide walkthrough UI | |
walkthroughOverlay.style.display = 'none'; | |
walkthroughPopup.style.display = 'none'; | |
walkthroughHighlight.style.display = 'none'; | |
walkthroughProgress.style.display = 'none'; | |
walkthroughIndicator.style.display = 'none'; | |
// Clear any intervals | |
if (walkthroughInterval) { | |
clearInterval(walkthroughInterval); | |
walkthroughInterval = null; | |
} | |
// Show completion message | |
addWalkthroughExplanation('π Walkthrough complete! You now understand neural networks better. Try exploring other tasks!'); | |
// Return to normal training speed when walkthrough ends | |
setTimeout(() => { | |
walkthroughTrainingSpeed = 100; // Back to normal speed | |
}, 5000); | |
} | |
// Event listeners for walkthrough | |
walkthroughNext.addEventListener('click', nextWalkthroughStep); | |
walkthroughPrev.addEventListener('click', prevWalkthroughStep); | |
walkthroughSkip.addEventListener('click', endWalkthrough); | |
// Keyboard navigation for walkthrough | |
document.addEventListener('keydown', (e) => { | |
if (!walkthroughActive) return; | |
if (e.key === 'ArrowRight' || e.key === ' ') { | |
e.preventDefault(); | |
nextWalkthroughStep(); | |
} else if (e.key === 'ArrowLeft') { | |
e.preventDefault(); | |
prevWalkthroughStep(); | |
} else if (e.key === 'Escape') { | |
e.preventDefault(); | |
endWalkthrough(); | |
} | |
}); | |
// Enhanced training step for walkthrough mode | |
function walkthroughTrainStep() { | |
if (!walkthroughActive) { | |
trainStep(); // Use normal training | |
return; | |
} | |
// Detailed step-by-step training for education | |
const sample = currentTask.data[currentSample]; | |
// 1. Forward propagation with detailed explanation | |
const output = network.forward(sample.input); | |
activations = [...network.activations]; | |
if (walkthroughExplanationMode && epoch % 10 === 0) { | |
const explanation = `Step ${epoch}: Processing ${sample.label}. ` + | |
`Input: [${sample.input.join(', ')}] β ` + | |
`Hidden activations β ` + | |
`Output: ${output[0].toFixed(3)} (target: ${sample.target[0]})`; | |
console.log(explanation); // For developers who open console | |
} | |
// 2. Calculate loss with explanation | |
const result = network.trainBatch([sample]); | |
currentLoss = result.loss; | |
weightChanges = result.weightChanges; | |
// 3. Update tracking variables | |
lossHistory.push(result.loss); | |
if (lossHistory.length > 100) lossHistory.shift(); | |
// 4. Calculate predictions for all samples | |
const newPredictions = currentTask.data.map(data => { | |
const output = network.forward(data.input); | |
const rawOutput = output[0]; | |
let predicted, correct; | |
if (currentTask.isRegression) { | |
predicted = rawOutput.toFixed(2); | |
let tolerance = 0.1; | |
if (currentTask.title.includes('Autoencoder')) { | |
tolerance = 0.2; | |
const allOutputs = network.forward(data.input); | |
let totalError = 0; | |
for (let j = 0; j < data.target.length; j++) { | |
totalError += Math.abs(allOutputs[j] - data.target[j]); | |
} | |
const avgError = totalError / data.target.length; | |
correct = avgError < tolerance; | |
} else { | |
correct = Math.abs(rawOutput - data.target[0]) < tolerance; | |
} | |
} else { | |
predicted = rawOutput >= 0.5 ? 1 : 0; | |
const target = data.target[0]; | |
correct = predicted === target; | |
} | |
return { | |
...data, | |
output: rawOutput, | |
predicted: predicted, | |
correct: correct | |
}; | |
}); | |
predictions = newPredictions; | |
// 5. Update metrics | |
const correct = newPredictions.filter(p => p.correct).length; | |
accuracy = correct / newPredictions.length; | |
const totalLoss = newPredictions.reduce((sum, p) => | |
sum + Math.pow(p.target[0] - p.output, 2), 0) / newPredictions.length; | |
avgLoss = totalLoss; | |
currentSample = (currentSample + 1) % currentTask.data.length; | |
epoch++; | |
// 6. Update UI | |
updateUI(); | |
// 7. Special walkthrough feedback | |
if (walkthroughActive && epoch % 20 === 0) { | |
const accuracyPercent = (accuracy * 100).toFixed(1); | |
if (accuracy > 0.8) { | |
addWalkthroughExplanation(`π Great progress! ${accuracyPercent}% accuracy - the AI is learning the pattern!`); | |
} else if (accuracy > 0.5) { | |
addWalkthroughExplanation(`π Learning... ${accuracyPercent}% accuracy. Watch the weights adapt!`); | |
} | |
} | |
} | |
// Override the original trainStep function when in walkthrough mode | |
const originalTrainStep = trainStep; | |
trainStep = function() { | |
if (walkthroughActive) { | |
walkthroughTrainStep(); | |
} else { | |
originalTrainStep(); | |
} | |
}; | |
// Override training button behavior for walkthrough mode | |
const originalTrainBtnClick = trainBtn.onclick; | |
trainBtn.addEventListener('click', (e) => { | |
if (walkthroughActive) { | |
// Use much slower speed in walkthrough mode | |
isTraining = !isTraining; | |
if (isTraining) { | |
trainBtn.innerHTML = ` | |
<svg class="icon" fill="currentColor" viewBox="0 0 24 24"> | |
<path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/> | |
</svg> | |
Pause Training | |
`; | |
trainBtn.className = 'btn btn-pause'; | |
trainInterval = setInterval(trainStep, walkthroughTrainingSpeed); | |
} else { | |
trainBtn.innerHTML = ` | |
<svg class="icon" fill="currentColor" viewBox="0 0 24 24"> | |
<path d="M8 5v14l11-7z"/> | |
</svg> | |
Start Training | |
`; | |
trainBtn.className = 'btn btn-start'; | |
clearInterval(trainInterval); | |
} | |
e.stopPropagation(); | |
return false; | |
} | |
}); | |
console.log('π Walkthrough mode enhanced! Users can now learn step-by-step how neural networks work.'); | |