Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Agent Training - Quantum Music Synthesizer</title> | |
| <link rel="icon" type="image/x-icon" href="/static/favicon.ico"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/animejs/lib/anime.iife.min.js"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <style> | |
| :root { | |
| --quantum-purple: #6e45e2; | |
| --quantum-teal: #88d3ce; | |
| --quantum-pink: #ff2a6d; | |
| --quantum-blue: #05d9e8; | |
| --quantum-dark: #0c0f1f; | |
| --quantum-darker: #080a1a; | |
| } | |
| .quantum-bg { | |
| background: linear-gradient(135deg, var(--quantum-dark), var(--quantum-darker)); | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .quantum-bg::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| background: | |
| radial-gradient(circle at 10% 20%, rgba(110, 69, 226, 0.1) 0%, transparent 20%), | |
| radial-gradient(circle at 90% 80%, rgba(136, 211, 206, 0.1) 0%, transparent 20%), | |
| radial-gradient(circle at 50% 50%, rgba(5, 217, 232, 0.05) 0%, transparent 30%); | |
| z-index: 0; | |
| } | |
| .quantum-card { | |
| background: rgba(255, 255, 255, 0.05); | |
| backdrop-filter: blur(10px); | |
| border: 1px solid rgba(255, 255, 255, 0.1); | |
| border-radius: 16px; | |
| transition: all 0.3s ease; | |
| } | |
| .quantum-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 10px 30px rgba(110, 69, 226, 0.2); | |
| border-color: rgba(110, 69, 226, 0.3); | |
| } | |
| .quantum-header { | |
| background: rgba(12, 15, 31, 0.8); | |
| backdrop-filter: blur(10px); | |
| position: sticky; | |
| top: 0; | |
| z-index: 100; | |
| border-bottom: 1px solid rgba(255, 255, 255, 0.05); | |
| } | |
| .quantum-nav a { | |
| position: relative; | |
| padding: 8px 0; | |
| } | |
| .quantum-nav a::after { | |
| content: ''; | |
| position: absolute; | |
| bottom: 0; | |
| left: 0; | |
| width: 0; | |
| height: 2px; | |
| background: var(--quantum-blue); | |
| transition: width 0.3s ease; | |
| } | |
| .quantum-nav a:hover::after { | |
| width: 100%; | |
| } | |
| .training-progress { | |
| height: 12px; | |
| background: rgba(255, 255, 255, 0.1); | |
| border-radius: 6px; | |
| overflow: hidden; | |
| } | |
| .progress-bar { | |
| height: 100%; | |
| background: linear-gradient(90deg, var(--quantum-purple), var(--quantum-teal)); | |
| border-radius: 6px; | |
| width: 0%; | |
| transition: width 0.5s ease; | |
| } | |
| .metric-card { | |
| background: rgba(26, 30, 45, 0.7); | |
| border: 1px solid rgba(110, 69, 226, 0.2); | |
| border-radius: 12px; | |
| padding: 1.5rem; | |
| } | |
| .neural-network { | |
| position: relative; | |
| height: 300px; | |
| background: rgba(10, 12, 25, 0.7); | |
| border-radius: 12px; | |
| overflow: hidden; | |
| border: 1px solid rgba(110, 69, 226, 0.2); | |
| } | |
| .neuron { | |
| position: absolute; | |
| width: 20px; | |
| height: 20px; | |
| border-radius: 50%; | |
| background: var(--quantum-purple); | |
| box-shadow: 0 0 10px rgba(110, 69, 226, 0.5); | |
| } | |
| .connection { | |
| position: absolute; | |
| height: 2px; | |
| background: rgba(136, 211, 206, 0.3); | |
| transform-origin: left; | |
| } | |
| .quantum-btn { | |
| background: linear-gradient(45deg, var(--quantum-purple), var(--quantum-teal)); | |
| border: none; | |
| border-radius: 30px; | |
| padding: 12px 20px; | |
| font-weight: 600; | |
| transition: all 0.3s ease; | |
| color: white; | |
| } | |
| .quantum-btn:hover { | |
| transform: translateY(-3px); | |
| box-shadow: 0 5px 20px rgba(110, 69, 226, 0.4); | |
| } | |
| .log-entry { | |
| padding: 0.75rem; | |
| border-bottom: 1px solid rgba(255, 255, 255, 0.05); | |
| font-family: monospace; | |
| font-size: 0.9rem; | |
| } | |
| .log-entry:last-child { | |
| border-bottom: none; | |
| } | |
| .log-info { color: #05d9e8; } | |
| .log-success { color: #88d3ce; } | |
| .log-warning { color: #ffcc00; } | |
| .log-error { color: #ff2a6d; } | |
| </style> | |
| </head> | |
| <body class="bg-gray-900 text-white min-h-screen"> | |
| <div class="quantum-bg min-h-screen"> | |
| <!-- Header --> | |
| <header class="quantum-header container mx-auto py-4 px-4"> | |
| <div class="flex justify-between items-center"> | |
| <h1 class="text-3xl font-bold">Quantum Music Synthesizer</h1> | |
| <nav class="quantum-nav"> | |
| <ul class="flex space-x-8"> | |
| <li><a href="index.html" class="hover:text-purple-300 font-medium">Home</a></li> | |
| <li><a href="synthesizer.html" class="hover:text-purple-300 font-medium">Synthesizer</a></li> | |
| <li><a href="quantum.html" class="hover:text-purple-300 font-medium">Quantum</a></li> | |
| <li><a href="visualization.html" class="hover:text-purple-300 font-medium">Visualization</a></li> | |
| <li><a href="about.html" class="hover:text-purple-300 font-medium">About</a></li> | |
| <li><a href="api.html" class="hover:text-purple-300 font-medium">API</a></li> | |
| <li><a href="agent.html" class="hover:text-purple-300 font-medium">Agent</a></li> | |
| </ul> | |
| </nav> | |
| </div> | |
| </header> | |
| <!-- Agent Training Section --> | |
| <section class="container mx-auto py-16 px-4"> | |
| <h1 class="text-4xl font-bold text-center mb-4">Agent Training Dashboard</h1> | |
| <p class="text-xl text-center mb-12 text-gray-300">Monitor and control AI agent training for quantum music composition</p> | |
| <div class="max-w-6xl mx-auto"> | |
| <!-- Training Controls --> | |
| <div class="quantum-card p-8 mb-8"> | |
| <div class="grid grid-cols-1 md:grid-cols-2 gap-8"> | |
| <div> | |
| <h2 class="text-2xl font-bold mb-4">Training Controls</h2> | |
| <div class="space-y-4"> | |
| <div> | |
| <label class="block mb-2">Epochs</label> | |
| <input type="range" min="1" max="1000" value="100" class="w-full slider"> | |
| <div class="flex justify-between text-sm mt-1"> | |
| <span>1</span> | |
| <span id="epoch-value">100</span> | |
| <span>1000</span> | |
| </div> | |
| </div> | |
| <div> | |
| <label class="block mb-2">Learning Rate</label> | |
| <input type="range" min="0.0001" max="0.1" step="0.0001" value="0.001" class="w-full slider"> | |
| <div class="flex justify-between text-sm mt-1"> | |
| <span>0.0001</span> | |
| <span id="lr-value">0.001</span> | |
| <span>0.1</span> | |
| </div> | |
| </div> | |
| <div class="flex space-x-4 pt-4"> | |
| <button id="start-training" class="quantum-btn flex-1"> | |
| <i data-feather="play" class="inline mr-2"></i>Start Training | |
| </button> | |
| <button id="pause-training" class="quantum-btn flex-1" disabled> | |
| <i data-feather="pause" class="inline mr-2"></i>Pause | |
| </button> | |
| <button id="stop-training" class="quantum-btn flex-1" disabled> | |
| <i data-feather="square" class="inline mr-2"></i>Stop | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| <div> | |
| <h2 class="text-2xl font-bold mb-4">Training Progress</h2> | |
| <div class="space-y-6"> | |
| <div> | |
| <div class="flex justify-between mb-2"> | |
| <span>Overall Progress</span> | |
| <span id="progress-percent">0%</span> | |
| </div> | |
| <div class="training-progress"> | |
| <div class="progress-bar" id="overall-progress"></div> | |
| </div> | |
| </div> | |
| <div> | |
| <div class="flex justify-between mb-2"> | |
| <span>Current Epoch</span> | |
| <span id="current-epoch">0/100</span> | |
| </div> | |
| <div class="training-progress"> | |
| <div class="progress-bar" id="epoch-progress"></div> | |
| </div> | |
| </div> | |
| <div class="grid grid-cols-2 gap-4"> | |
| <div class="metric-card"> | |
| <h3 class="font-bold text-lg mb-2">Loss</h3> | |
| <div class="text-2xl font-bold" id="loss-value">0.0000</div> | |
| </div> | |
| <div class="metric-card"> | |
| <h3 class="font-bold text-lg mb-2">Accuracy</h3> | |
| <div class="text-2xl font-bold" id="accuracy-value">0.00%</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Neural Network Visualization --> | |
| <div class="quantum-card p-8 mb-8"> | |
| <h2 class="text-2xl font-bold mb-6">Neural Network Architecture</h2> | |
| <div class="neural-network" id="network-viz"> | |
| <!-- Neurons and connections will be generated by JavaScript --> | |
| </div> | |
| </div> | |
| <!-- Training Logs --> | |
| <div class="quantum-card p-8"> | |
| <h2 class="text-2xl font-bold mb-6">Training Logs</h2> | |
| <div class="bg-gray-800/50 rounded-lg p-4 h-64 overflow-y-auto font-mono text-sm" id="training-logs"> | |
| <div class="log-entry log-info">[INFO] Initializing quantum music composition agent...</div> | |
| <div class="log-entry log-info">[INFO] Loading dataset: Quantum harmonic sequences</div> | |
| <div class="log-entry log-info">[INFO] Model architecture: LSTM-Transformer hybrid</div> | |
| <div class="log-entry log-info">[INFO] Ready for training. Adjust parameters and click Start.</div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <!-- Footer --> | |
| <footer class="container mx-auto py-8 px-4 text-center border-t border-gray-800"> | |
| <p class="text-gray-400">Powered by QuantumToolbox.jl, Amazon Braket, and Lindblad Solvers</p> | |
| </footer> | |
| </div> | |
| <script> | |
| feather.replace(); | |
| // DOM Elements | |
| const epochValue = document.getElementById('epoch-value'); | |
| const lrValue = document.getElementById('lr-value'); | |
| const overallProgress = document.getElementById('overall-progress'); | |
| const epochProgress = document.getElementById('epoch-progress'); | |
| const progressPercent = document.getElementById('progress-percent'); | |
| const currentEpoch = document.getElementById('current-epoch'); | |
| const lossValue = document.getElementById('loss-value'); | |
| const accuracyValue = document.getElementById('accuracy-value'); | |
| const trainingLogs = document.getElementById('training-logs'); | |
| const startBtn = document.getElementById('start-training'); | |
| const pauseBtn = document.getElementById('pause-training'); | |
| const stopBtn = document.getElementById('stop-training'); | |
| // Slider event listeners | |
| document.querySelectorAll('input[type="range"]')[0].addEventListener('input', function() { | |
| epochValue.textContent = this.value; | |
| }); | |
| document.querySelectorAll('input[type="range"]')[1].addEventListener('input', function() { | |
| lrValue.textContent = parseFloat(this.value).toFixed(4); | |
| }); | |
| // Training simulation variables | |
| let trainingInterval; | |
| let isTraining = false; | |
| let isPaused = false; | |
| let currentEpochNum = 0; | |
| let totalEpochs = parseInt(document.querySelectorAll('input[type="range"]')[0].value); | |
| let logCounter = 0; | |
| // Log messages for simulation | |
| const logMessages = [ | |
| "[INFO] Starting epoch {epoch}...", | |
| "[INFO] Processing quantum harmonic sequences...", | |
| "[INFO] Updating weights with learning rate {lr}", | |
| "[INFO] Loss decreased to {loss}", | |
| "[WARNING] Gradient norm approaching threshold", | |
| "[INFO] Completed epoch {epoch} in {time}ms", | |
| "[INFO] Validation accuracy: {acc}%", | |
| "[INFO] Saving checkpoint..." | |
| ]; | |
| // Start training | |
| startBtn.addEventListener('click', function() { | |
| if (!isTraining) { | |
| isTraining = true; | |
| isPaused = false; | |
| startBtn.disabled = true; | |
| pauseBtn.disabled = false; | |
| stopBtn.disabled = false; | |
| // Reset values | |
| currentEpochNum = 0; | |
| totalEpochs = parseInt(document.querySelectorAll('input[type="range"]')[0].value); | |
| updateProgress(); | |
| // Add log entry | |
| addLogEntry("[INFO] Starting training session...", "log-info"); | |
| // Start training interval | |
| trainingInterval = setInterval(runTrainingStep, 500); | |
| } else if (isPaused) { | |
| isPaused = false; | |
| pauseBtn.innerHTML = '<i data-feather="pause" class="inline mr-2"></i>Pause'; | |
| feather.replace(); | |
| trainingInterval = setInterval(runTrainingStep, 500); | |
| } | |
| }); | |
| // Pause training | |
| pauseBtn.addEventListener('click', function() { | |
| if (!isPaused) { | |
| isPaused = true; | |
| clearInterval(trainingInterval); | |
| pauseBtn.innerHTML = '<i data-feather="play" class="inline mr-2"></i>Resume'; | |
| feather.replace(); | |
| addLogEntry("[INFO] Training paused", "log-info"); | |
| } else { | |
| isPaused = false; | |
| pauseBtn.innerHTML = '<i data-feather="pause" class="inline mr-2"></i>Pause'; | |
| feather.replace(); | |
| trainingInterval = setInterval(runTrainingStep, 500); | |
| addLogEntry("[INFO] Training resumed", "log-info"); | |
| } | |
| }); | |
| // Stop training | |
| stopBtn.addEventListener('click', function() { | |
| isTraining = false; | |
| isPaused = false; | |
| clearInterval(trainingInterval); | |
| startBtn.disabled = false; | |
| pauseBtn.disabled = true; | |
| stopBtn.disabled = true; | |
| pauseBtn.innerHTML = '<i data-feather="pause" class="inline mr-2"></i>Pause'; | |
| feather.replace(); | |
| addLogEntry("[INFO] Training stopped by user", "log-info"); | |
| }); | |
| // Run a single training step | |
| function runTrainingStep() { | |
| if (currentEpochNum >= totalEpochs) { | |
| clearInterval(trainingInterval); | |
| isTraining = false; | |
| startBtn.disabled = false; | |
| pauseBtn.disabled = true; | |
| stopBtn.disabled = true; | |
| addLogEntry("[INFO] Training completed successfully!", "log-success"); | |
| return; | |
| } | |
| currentEpochNum++; | |
| // Simulate progress | |
| const epochProgressValue = Math.min(100, Math.floor(Math.random() * 30) + 70); | |
| epochProgress.style.width = epochProgressValue + '%'; | |
| // Simulate metrics | |
| const loss = Math.max(0, (1 - currentEpochNum/totalEpochs) * (0.5 + Math.random() * 0.5)).toFixed(4); | |
| const accuracy = Math.min(100, (currentEpochNum/totalEpochs) * (80 + Math.random() * 20)).toFixed(2); | |
| // Update UI | |
| lossValue.textContent = loss; | |
| accuracyValue.textContent = accuracy + '%'; | |
| currentEpoch.textContent = `${currentEpochNum}/${totalEpochs}`; | |
| updateProgress(); | |
| // Add log entry | |
| if (logCounter % 3 === 0) { | |
| const randomLog = logMessages[Math.floor(Math.random() * logMessages.length)]; | |
| const formattedLog = randomLog | |
| .replace('{epoch}', currentEpochNum) | |
| .replace('{lr}', lrValue.textContent) | |
| .replace('{loss}', loss) | |
| .replace('{acc}', accuracy) | |
| .replace('{time}', Math.floor(Math.random() * 2000) + 500); | |
| const logTypes = ['log-info', 'log-success', 'log-warning']; | |
| const logType = logTypes[Math.floor(Math.random() * logTypes.length)]; | |
| addLogEntry(formattedLog, logType); | |
| } | |
| logCounter++; | |
| } | |
| // Update overall progress | |
| function updateProgress() { | |
| const progress = (currentEpochNum / totalEpochs) * 100; | |
| overallProgress.style.width = progress + '%'; | |
| progressPercent.textContent = Math.round(progress) + '%'; | |
| } | |
| // Add log entry | |
| function addLogEntry(message, type) { | |
| const logEntry = document.createElement('div'); | |
| logEntry.className = `log-entry ${type}`; | |
| logEntry.textContent = `${new Date().toLocaleTimeString()} ${message}`; | |
| trainingLogs.appendChild(logEntry); | |
| trainingLogs.scrollTop = trainingLogs.scrollHeight; | |
| } | |
| // Create neural network visualization | |
| function createNetworkVisualization() { | |
| const container = document.getElementById('network-viz'); | |
| container.innerHTML = ''; | |
| // Create layers | |
| const layers = [ | |
| { neurons: 8, x: 50 }, | |
| { neurons: 12, x: 150 }, | |
| { neurons: 16, x: 250 }, | |
| { neurons: 12, x: 350 }, | |
| { neurons: 8, x: 450 } | |
| ]; | |
| // Store neuron positions | |
| const neuronPositions = []; | |
| // Create neurons | |
| layers.forEach((layer, layerIndex) => { | |
| const layerNeurons = []; | |
| for (let i = 0; i < layer.neurons; i++) { | |
| const neuron = document.createElement('div'); | |
| neuron.className = 'neuron'; | |
| // Position neurons vertically | |
| const y = 30 + (i * (240 / Math.max(1, layer.neurons - 1))); | |
| neuron.style.left = (layer.x - 10) + 'px'; | |
| neuron.style.top = (y - 10) + 'px'; | |
| container.appendChild(neuron); | |
| layerNeurons.push({ x: layer.x, y: y }); | |
| } | |
| neuronPositions.push(layerNeurons); | |
| }); | |
| // Create connections | |
| for (let l = 0; l < neuronPositions.length - 1; l++) { | |
| const currentLayer = neuronPositions[l]; | |
| const nextLayer = neuronPositions[l + 1]; | |
| currentLayer.forEach(neuron => { | |
| nextLayer.forEach(nextNeuron => { | |
| const connection = document.createElement('div'); | |
| connection.className = 'connection'; | |
| // Calculate distance and angle | |
| const dx = nextNeuron.x - neuron.x; | |
| const dy = nextNeuron.y - neuron.y; | |
| const length = Math.sqrt(dx * dx + dy * dy); | |
| const angle = Math.atan2(dy, dx) * 180 / Math.PI; | |
| connection.style.width = length + 'px'; | |
| connection.style.left = neuron.x + 'px'; | |
| connection.style.top = neuron.y + 'px'; | |
| connection.style.transform = `rotate(${angle}deg)`; | |
| container.appendChild(connection); | |
| }); | |
| }); | |
| } | |
| // Animate neurons | |
| animateNeurons(); | |
| } | |
| // Animate neurons | |
| function animateNeurons() { | |
| const neurons = document.querySelectorAll('.neuron'); | |
| setInterval(() => { | |
| neurons.forEach(neuron => { | |
| if (Math.random() > 0.7) { | |
| neuron.style.opacity = '0.5'; | |
| setTimeout(() => { | |
| neuron.style.opacity = '1'; | |
| }, 200); | |
| } | |
| }); | |
| }, 500); | |
| } | |
| // Initialize when page loads | |
| window.addEventListener('load', function() { | |
| createNetworkVisualization(); | |
| }); | |
| </script> | |
| </body> | |
| </html> |