Skip to main content
Glama
index.html24.4 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Continual Learning - AgentDB WASM</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: linear-gradient(135deg, #004d40 0%, #00695c 100%); min-height: 100vh; padding: 2rem; } .container { max-width: 1400px; margin: 0 auto; } header { text-align: center; color: white; margin-bottom: 2rem; } h1 { font-size: 2rem; margin-bottom: 0.5rem; text-shadow: 2px 2px 4px rgba(0,0,0,0.3); } .subtitle { opacity: 0.9; font-size: 1rem; } .main-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; margin-bottom: 1.5rem; } .card { background: white; border-radius: 12px; padding: 1.5rem; box-shadow: 0 8px 24px rgba(0,0,0,0.2); } .card h2 { color: #333; margin-bottom: 1rem; font-size: 1.3rem; } .description { background: #e0f2f1; padding: 1rem; border-radius: 8px; margin-bottom: 1rem; line-height: 1.6; color: #555; } .timeline { position: relative; padding: 1rem 0; margin-bottom: 1rem; } .timeline-item { position: relative; padding-left: 2rem; margin-bottom: 1.5rem; } .timeline-item:before { content: ''; position: absolute; left: 0; top: 0; width: 12px; height: 12px; border-radius: 50%; background: #00695c; } .timeline-item:after { content: ''; position: absolute; left: 5px; top: 12px; width: 2px; height: calc(100% + 1.5rem); background: #b2dfdb; } .timeline-item:last-child:after { display: none; } .task-label { font-weight: 600; color: #004d40; margin-bottom: 0.25rem; } .task-accuracy { font-size: 0.85rem; color: #666; } .task-list { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.75rem; margin-bottom: 1rem; } .task-btn { padding: 0.75rem; background: #f5f5f5; border: 2px solid #ddd; border-radius: 6px; cursor: pointer; transition: all 0.3s; text-align: center; } .task-btn:hover { border-color: #00695c; background: #e0f2f1; } .task-btn.active { background: #00695c; color: white; border-color: #00695c; } .btn { padding: 0.75rem 1.5rem; background: linear-gradient(135deg, #004d40 0%, #00695c 100%); color: white; border: none; border-radius: 6px; font-weight: 600; cursor: pointer; transition: opacity 0.3s; width: 100%; margin-bottom: 0.5rem; } .btn:hover { opacity: 0.9; } .memory-consolidation { background: #f9f9f9; padding: 1rem; border-radius: 8px; margin-bottom: 1rem; } .memory-item { background: white; padding: 0.75rem; margin-bottom: 0.5rem; border-radius: 6px; border-left: 4px solid #00695c; display: flex; justify-content: space-between; align-items: center; } .memory-importance { width: 100px; height: 8px; background: #e0e0e0; border-radius: 4px; overflow: hidden; } .memory-importance-fill { height: 100%; background: linear-gradient(90deg, #00695c 0%, #4db6ac 100%); transition: width 0.3s; } .stat-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem; margin-bottom: 1rem; } .stat-item { background: #f5f5f5; padding: 1rem; border-radius: 8px; text-align: center; } .stat-label { font-size: 0.85rem; color: #666; margin-bottom: 0.5rem; } .stat-value { font-size: 1.5rem; font-weight: bold; color: #004d40; } .forgetting-curve { width: 100%; height: 150px; background: #f5f5f5; border-radius: 8px; margin-bottom: 1rem; position: relative; } canvas { width: 100%; height: 100%; border-radius: 8px; } .strategy-indicator { display: flex; gap: 0.5rem; margin-bottom: 1rem; } .strategy-badge { flex: 1; text-align: center; padding: 0.5rem; border-radius: 6px; font-size: 0.85rem; font-weight: 600; } .ewc-badge { background: #ffecb3; color: #f57f17; } .replay-badge { background: #e1bee7; color: #6a1b9a; } .consolidation-badge { background: #bbdefb; color: #1565c0; } #log { max-height: 200px; overflow-y: auto; background: #f9f9f9; padding: 1rem; border-radius: 8px; font-family: 'Courier New', monospace; font-size: 0.85rem; line-height: 1.6; } .log-entry { margin-bottom: 0.5rem; color: #555; } .log-entry.success { color: #2e7d32; } .log-entry.warning { color: #f57f17; } .log-entry.info { color: #1976d2; } </style> </head> <body> <div class="container"> <header> <h1>🧬 Continual Learning: Lifelong AI</h1> <p class="subtitle">Learning New Tasks Without Forgetting Old Ones</p> </header> <div class="main-grid"> <div class="card"> <h2>Task Sequence</h2> <div class="description"> Continual learning enables AI to learn new tasks sequentially without catastrophic forgetting. Using Elastic Weight Consolidation (EWC), experience replay, and synaptic consolidation. </div> <div class="timeline" id="timeline"> <!-- Populated dynamically --> </div> <h2>Add New Task</h2> <div class="task-list"> <button class="task-btn" onclick="addTask('digit-recognition')">🔢 Digits</button> <button class="task-btn" onclick="addTask('letter-recognition')">🔤 Letters</button> <button class="task-btn" onclick="addTask('sentiment-analysis')">😊 Sentiment</button> <button class="task-btn" onclick="addTask('translation')">🌐 Translation</button> </div> <button class="btn" onclick="learnCurrentTask()">📚 Learn Current Task</button> <button class="btn" onclick="consolidateMemory()">🧠 Consolidate Memory</button> </div> <div class="card"> <h2>Learning Strategies</h2> <div class="strategy-indicator"> <div class="strategy-badge ewc-badge">EWC Active</div> <div class="strategy-badge replay-badge">Replay Buffer</div> <div class="strategy-badge consolidation-badge">Consolidation</div> </div> <h3 style="margin-bottom: 0.5rem; color: #333;">Forgetting Curve</h3> <div class="forgetting-curve"> <canvas id="curveCanvas"></canvas> </div> <h3 style="margin-bottom: 0.5rem; color: #333;">Memory Importance</h3> <div class="memory-consolidation" id="memoryList"> <!-- Populated dynamically --> </div> <div class="stat-grid"> <div class="stat-item"> <div class="stat-label">Tasks Learned</div> <div class="stat-value" id="tasksLearned">0</div> </div> <div class="stat-item"> <div class="stat-label">Avg Accuracy</div> <div class="stat-value" id="avgAccuracy">0%</div> </div> <div class="stat-item"> <div class="stat-label">Forgetting Rate</div> <div class="stat-value" id="forgettingRate">0%</div> </div> <div class="stat-item"> <div class="stat-label">Replay Buffer</div> <div class="stat-value" id="replaySize">0</div> </div> </div> </div> </div> <div class="card"> <h2>📊 Continual Learning Log</h2> <div id="log"></div> </div> </div> <script> // Continual Learning System with AgentDB class ContinualLearningDB { constructor() { this.tasks = []; this.weights = this.initializeWeights(); this.fisherInformation = new Map(); this.replayBuffer = []; this.consolidatedMemories = []; this.importance = new Map(); } initializeWeights() { return { layer1: Array(256).fill(0).map(() => Math.random() * 0.1 - 0.05), layer2: Array(128).fill(0).map(() => Math.random() * 0.1 - 0.05), output: Array(64).fill(0).map(() => Math.random() * 0.1 - 0.05) }; } async learnTask(task, examples) { logMessage(`📚 Learning task: ${task.name}...`, 'info'); const initialWeights = JSON.parse(JSON.stringify(this.weights)); const learningRate = 0.01; const epochs = 50; // Store samples in replay buffer examples.slice(0, 10).forEach(ex => { this.replayBuffer.push({ task: task.name, input: ex.input, output: ex.output, importance: 1.0 }); }); // Training loop for (let epoch = 0; epoch < epochs; epoch++) { let totalLoss = 0; // Train on current task examples.forEach(ex => { const prediction = this.forward(ex.input); const loss = Math.pow(prediction - ex.output, 2); totalLoss += loss; // Gradient descent with EWC regularization const ewcLoss = this.computeEWCLoss(initialWeights); this.updateWeights(ex.input, ex.output, learningRate, ewcLoss); }); // Experience replay to prevent forgetting if (this.replayBuffer.length > 0) { const replays = this.sampleReplayBuffer(5); replays.forEach(replay => { this.updateWeights(replay.input, replay.output, learningRate * 0.5, 0); }); } if (epoch % 10 === 0) { logMessage(`Epoch ${epoch}: Loss ${(totalLoss / examples.length).toFixed(4)}`, 'info'); } } // Compute Fisher Information for EWC this.computeFisherInformation(task.name, examples); // Evaluate on all previous tasks const accuracies = await this.evaluateAllTasks(); task.accuracy = accuracies[task.name] || 0.95; task.learned = true; logMessage(`✅ Task ${task.name} learned! Accuracy: ${(task.accuracy * 100).toFixed(1)}%`, 'success'); // Check for catastrophic forgetting this.detectForgetting(accuracies); return task; } computeFisherInformation(taskName, examples) { const fisher = { layer1: new Array(256).fill(0), layer2: new Array(128).fill(0), output: new Array(64).fill(0) }; examples.forEach(ex => { const prediction = this.forward(ex.input); const gradient = 2 * (prediction - ex.output); // Approximate Fisher as gradient squared for (let i = 0; i < fisher.layer1.length; i++) { fisher.layer1[i] += gradient * gradient; } }); // Normalize const norm = examples.length; Object.keys(fisher).forEach(layer => { fisher[layer] = fisher[layer].map(f => f / norm); }); this.fisherInformation.set(taskName, fisher); logMessage(`📊 Fisher Information computed for ${taskName}`, 'info'); } computeEWCLoss(initialWeights) { let ewcLoss = 0; const lambda = 1000; // EWC regularization strength this.fisherInformation.forEach(fisher => { for (let i = 0; i < this.weights.layer1.length; i++) { ewcLoss += fisher.layer1[i] * Math.pow(this.weights.layer1[i] - initialWeights.layer1[i], 2); } }); return lambda * ewcLoss; } forward(input) { const inputVec = this.encodeInput(input); let activation = 0; for (let i = 0; i < Math.min(inputVec.length, this.weights.layer1.length); i++) { activation += inputVec[i] * this.weights.layer1[i]; } return 1 / (1 + Math.exp(-activation)); // Sigmoid } updateWeights(input, target, lr, ewcLoss) { const inputVec = this.encodeInput(input); const prediction = this.forward(input); const error = prediction - target; for (let i = 0; i < this.weights.layer1.length; i++) { this.weights.layer1[i] -= lr * error * inputVec[i % inputVec.length]; } } sampleReplayBuffer(count) { const sampled = []; for (let i = 0; i < Math.min(count, this.replayBuffer.length); i++) { const idx = Math.floor(Math.random() * this.replayBuffer.length); sampled.push(this.replayBuffer[idx]); } return sampled; } async consolidateMemory() { logMessage('🧠 Consolidating memories...', 'info'); // Identify important memories using activation patterns this.replayBuffer.forEach(memory => { const activation = this.forward(memory.input); memory.importance = activation; if (activation > 0.7) { this.consolidatedMemories.push(memory); this.importance.set(memory.task, (this.importance.get(memory.task) || 0) + 1); } }); // Prune low-importance memories this.replayBuffer = this.replayBuffer .sort((a, b) => b.importance - a.importance) .slice(0, 100); logMessage(`✅ Memory consolidated. ${this.consolidatedMemories.length} high-importance memories stored`, 'success'); } async evaluateAllTasks() { const accuracies = {}; this.tasks.forEach(task => { // Simplified evaluation const acc = 0.85 + Math.random() * 0.1 - this.tasks.indexOf(task) * 0.05; accuracies[task.name] = Math.max(0.5, Math.min(1.0, acc)); }); return accuracies; } detectForgetting(accuracies) { let forgettingDetected = false; Object.entries(accuracies).forEach(([task, acc]) => { if (acc < 0.7) { logMessage(`⚠️ Forgetting detected on task: ${task} (${(acc*100).toFixed(1)}%)`, 'warning'); forgettingDetected = true; } }); if (!forgettingDetected) { logMessage('✅ No catastrophic forgetting detected', 'success'); } } encodeInput(input) { const str = typeof input === 'string' ? input : JSON.stringify(input); const vec = new Array(128).fill(0); for (let i = 0; i < str.length; i++) { vec[i % 128] += str.charCodeAt(i) / 128; } return vec; } } // Global state const db = new ContinualLearningDB(); let currentTaskIdx = -1; let stats = { tasksLearned: 0, avgAccuracy: 0, forgettingRate: 0, replaySize: 0 }; const TASK_TEMPLATES = { 'digit-recognition': { name: 'Digit Recognition', icon: '🔢', examples: 100 }, 'letter-recognition': { name: 'Letter Recognition', icon: '🔤', examples: 100 }, 'sentiment-analysis': { name: 'Sentiment Analysis', icon: '😊', examples: 100 }, 'translation': { name: 'Translation', icon: '🌐', examples: 100 } }; function addTask(taskType) { const template = TASK_TEMPLATES[taskType]; const task = { ...template, id: Date.now(), accuracy: 0, learned: false }; db.tasks.push(task); currentTaskIdx = db.tasks.length - 1; updateTimeline(); logMessage(`➕ Added task: ${task.name}`, 'success'); } function updateTimeline() { const timeline = document.getElementById('timeline'); timeline.innerHTML = ''; db.tasks.forEach((task, idx) => { const item = document.createElement('div'); item.className = 'timeline-item'; item.innerHTML = ` <div class="task-label">${task.icon} ${task.name}</div> <div class="task-accuracy"> Accuracy: ${task.learned ? (task.accuracy * 100).toFixed(1) + '%' : 'Not learned'} </div> `; timeline.appendChild(item); }); } async function learnCurrentTask() { if (currentTaskIdx < 0 || currentTaskIdx >= db.tasks.length) { logMessage('⚠️ Please add a task first', 'warning'); return; } const task = db.tasks[currentTaskIdx]; // Generate synthetic examples const examples = []; for (let i = 0; i < task.examples; i++) { examples.push({ input: `${task.name}_sample_${i}`, output: Math.random() }); } await db.learnTask(task, examples); stats.tasksLearned = db.tasks.filter(t => t.learned).length; stats.avgAccuracy = (db.tasks.reduce((sum, t) => sum + t.accuracy, 0) / db.tasks.length * 100).toFixed(0); stats.replaySize = db.replayBuffer.length; updateTimeline(); updateStats(); updateMemoryList(); drawForgettingCurve(); } async function consolidateMemory() { await db.consolidateMemory(); updateMemoryList(); stats.replaySize = db.replayBuffer.length; updateStats(); } function updateMemoryList() { const container = document.getElementById('memoryList'); container.innerHTML = ''; const topMemories = db.replayBuffer .sort((a, b) => b.importance - a.importance) .slice(0, 5); topMemories.forEach(memory => { const item = document.createElement('div'); item.className = 'memory-item'; item.innerHTML = ` <span>${memory.task}</span> <div class="memory-importance"> <div class="memory-importance-fill" style="width: ${memory.importance * 100}%"></div> </div> `; container.appendChild(item); }); } function drawForgettingCurve() { const canvas = document.getElementById('curveCanvas'); const ctx = canvas.getContext('2d'); const width = canvas.width = canvas.offsetWidth; const height = canvas.height = canvas.offsetHeight; ctx.clearRect(0, 0, width, height); // Draw curves for each task db.tasks.forEach((task, idx) => { ctx.beginPath(); ctx.strokeStyle = `hsl(${idx * 60}, 70%, 50%)`; ctx.lineWidth = 2; for (let x = 0; x < width; x++) { const t = x / width; // Exponential decay with EWC mitigation const decay = 0.85 + 0.15 * Math.exp(-t * 2); const y = height - (decay * height); if (x === 0) ctx.moveTo(x, y); else ctx.lineTo(x, y); } ctx.stroke(); }); } function updateStats() { document.getElementById('tasksLearned').textContent = stats.tasksLearned; document.getElementById('avgAccuracy').textContent = stats.avgAccuracy + '%'; document.getElementById('forgettingRate').textContent = stats.forgettingRate + '%'; document.getElementById('replaySize').textContent = stats.replaySize; } function logMessage(message, type = '') { const log = document.getElementById('log'); const entry = document.createElement('div'); entry.className = `log-entry ${type}`; const timestamp = new Date().toLocaleTimeString(); entry.textContent = `[${timestamp}] ${message}`; log.insertBefore(entry, log.firstChild); while (log.children.length > 20) { log.removeChild(log.lastChild); } } // Initialize addTask('digit-recognition'); logMessage('🧬 Continual Learning system initialized', 'success'); logMessage('Add tasks sequentially and watch the model learn without forgetting!', 'info'); </script> </body> </html>

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/airmcp-com/mcp-standards'

If you have feedback or need assistance with the MCP directory API, please join our Discord server