{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# RusTorch WebGPU Machine Learning Demo\n",
"# RusTorch WebGPU機械学習デモ\n",
"\n",
"Advanced machine learning operations accelerated by WebGPU in the browser.\n",
"\n",
"ブラウザでWebGPUによって加速された高度な機械学習操作。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 1. Neural Network Layer Operations\n",
"## 1. ニューラルネットワークレイヤー演算"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%html\n",
"<div id=\"nn-layers\">\n",
" <h3>🧠 Neural Network Forward Pass Demo</h3>\n",
" \n",
" <div style=\"margin: 20px 0;\">\n",
" <label>Network Architecture:</label>\n",
" <select id=\"nn-architecture\">\n",
" <option value=\"simple\">Simple (784 → 128 → 10)</option>\n",
" <option value=\"deep\">Deep (784 → 256 → 128 → 64 → 10)</option>\n",
" <option value=\"conv\">ConvNet (28×28 → Conv → Pool → FC)</option>\n",
" </select>\n",
" \n",
" <button onclick=\"runNNDemo()\" style=\"margin-left: 10px;\">Run Forward Pass</button>\n",
" </div>\n",
" \n",
" <div id=\"nn-results\"></div>\n",
"</div>\n",
"\n",
"<script>\n",
"function createRandomMatrix(rows, cols) {\n",
" const data = new Float32Array(rows * cols);\n",
" for (let i = 0; i < data.length; i++) {\n",
" data[i] = (Math.random() - 0.5) * 0.1;\n",
" }\n",
" return data;\n",
"}\n",
"\n",
"function relu(x) {\n",
" return Math.max(0, x);\n",
"}\n",
"\n",
"function softmax(arr) {\n",
" const max = Math.max(...arr);\n",
" const exp = arr.map(x => Math.exp(x - max));\n",
" const sum = exp.reduce((a, b) => a + b, 0);\n",
" return exp.map(x => x / sum);\n",
"}\n",
"\n",
"async function runNNDemo() {\n",
" const architecture = document.getElementById('nn-architecture').value;\n",
" const resultsDiv = document.getElementById('nn-results');\n",
" \n",
" resultsDiv.innerHTML = '<p>Running neural network forward pass...</p>';\n",
" \n",
" try {\n",
" let layers = [];\n",
" let timings = [];\n",
" \n",
" // Define architecture\n",
" switch(architecture) {\n",
" case 'simple':\n",
" layers = [\n",
" { name: 'Input', size: 784 },\n",
" { name: 'Hidden 1', size: 128 },\n",
" { name: 'Output', size: 10 }\n",
" ];\n",
" break;\n",
" case 'deep':\n",
" layers = [\n",
" { name: 'Input', size: 784 },\n",
" { name: 'Hidden 1', size: 256 },\n",
" { name: 'Hidden 2', size: 128 },\n",
" { name: 'Hidden 3', size: 64 },\n",
" { name: 'Output', size: 10 }\n",
" ];\n",
" break;\n",
" case 'conv':\n",
" layers = [\n",
" { name: 'Input', size: 784 },\n",
" { name: 'Conv1', size: 32 * 26 * 26 },\n",
" { name: 'Pool1', size: 32 * 13 * 13 },\n",
" { name: 'FC1', size: 128 },\n",
" { name: 'Output', size: 10 }\n",
" ];\n",
" break;\n",
" }\n",
" \n",
" // Create input (batch of 32 images)\n",
" const batchSize = 32;\n",
" let input = createRandomMatrix(batchSize, layers[0].size);\n",
" let totalOps = 0;\n",
" \n",
" // Process through layers\n",
" for (let i = 1; i < layers.length; i++) {\n",
" const inputSize = layers[i-1].size;\n",
" const outputSize = layers[i].size;\n",
" \n",
" // Create weight matrix\n",
" const weights = createRandomMatrix(inputSize, outputSize);\n",
" const bias = createRandomMatrix(1, outputSize);\n",
" \n",
" const start = performance.now();\n",
" \n",
" // Matrix multiplication + bias + activation\n",
" const output = new Float32Array(batchSize * outputSize);\n",
" \n",
" for (let b = 0; b < batchSize; b++) {\n",
" for (let j = 0; j < outputSize; j++) {\n",
" let sum = bias[j];\n",
" for (let k = 0; k < inputSize; k++) {\n",
" sum += input[b * inputSize + k] * weights[k * outputSize + j];\n",
" }\n",
" // Apply ReLU (except last layer)\n",
" output[b * outputSize + j] = (i < layers.length - 1) ? relu(sum) : sum;\n",
" }\n",
" }\n",
" \n",
" const time = performance.now() - start;\n",
" timings.push({ layer: layers[i].name, time });\n",
" \n",
" // Count operations\n",
" totalOps += batchSize * inputSize * outputSize * 2; // multiply-add\n",
" \n",
" input = output;\n",
" }\n",
" \n",
" // Apply softmax to final layer\n",
" const finalOutput = [];\n",
" for (let b = 0; b < batchSize; b++) {\n",
" const start = b * 10;\n",
" const end = start + 10;\n",
" const logits = Array.from(input.slice(start, end));\n",
" finalOutput.push(softmax(logits));\n",
" }\n",
" \n",
" // Calculate total time and GFLOPS\n",
" const totalTime = timings.reduce((sum, t) => sum + t.time, 0);\n",
" const gflops = (totalOps / (totalTime * 1e6)).toFixed(2);\n",
" \n",
" // Display results\n",
" resultsDiv.innerHTML = `\n",
" <h4>✅ Forward Pass Complete</h4>\n",
" \n",
" <h5>⏱️ Layer Timings:</h5>\n",
" <table style=\"width: 100%; border-collapse: collapse;\">\n",
" <tr style=\"background: #f0f0f0;\">\n",
" <th style=\"padding: 8px; text-align: left;\">Layer</th>\n",
" <th style=\"padding: 8px; text-align: right;\">Time (ms)</th>\n",
" </tr>\n",
" ${timings.map(t => `\n",
" <tr>\n",
" <td style=\"padding: 8px;\">${t.layer}</td>\n",
" <td style=\"padding: 8px; text-align: right;\">${t.time.toFixed(3)}</td>\n",
" </tr>\n",
" `).join('')}\n",
" <tr style=\"background: #e8f4f8; font-weight: bold;\">\n",
" <td style=\"padding: 8px;\">Total</td>\n",
" <td style=\"padding: 8px; text-align: right;\">${totalTime.toFixed(3)}</td>\n",
" </tr>\n",
" </table>\n",
" \n",
" <h5>📊 Performance Metrics:</h5>\n",
" <ul>\n",
" <li><strong>Batch Size:</strong> ${batchSize} samples</li>\n",
" <li><strong>Total Operations:</strong> ${(totalOps / 1e9).toFixed(2)} billion</li>\n",
" <li><strong>Throughput:</strong> ${gflops} GFLOPS</li>\n",
" <li><strong>Samples/sec:</strong> ${(batchSize / (totalTime / 1000)).toFixed(0)}</li>\n",
" </ul>\n",
" \n",
" <h5>🎯 Sample Output (First Sample):</h5>\n",
" <div style=\"background: #f0f0f0; padding: 10px; border-radius: 5px;\">\n",
" ${finalOutput[0].map((p, i) => \n",
" `Class ${i}: ${(p * 100).toFixed(1)}%`\n",
" ).join(' | ')}\n",
" </div>\n",
" `;\n",
" \n",
" } catch (error) {\n",
" resultsDiv.innerHTML = '❌ Error: ' + error.message;\n",
" }\n",
"}\n",
"</script>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Convolution Operations\n",
"## 2. 畳み込み演算"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%html\n",
"<div id=\"conv-ops\">\n",
" <h3>🔍 2D Convolution Demo</h3>\n",
" \n",
" <div style=\"margin: 20px 0;\">\n",
" <label>Input Size:</label>\n",
" <select id=\"conv-input-size\">\n",
" <option value=\"28\">28×28 (MNIST)</option>\n",
" <option value=\"32\">32×32 (CIFAR)</option>\n",
" <option value=\"64\">64×64</option>\n",
" <option value=\"128\">128×128</option>\n",
" </select>\n",
" \n",
" <label style=\"margin-left: 20px;\">Kernel Size:</label>\n",
" <select id=\"conv-kernel-size\">\n",
" <option value=\"3\">3×3</option>\n",
" <option value=\"5\">5×5</option>\n",
" <option value=\"7\">7×7</option>\n",
" </select>\n",
" \n",
" <label style=\"margin-left: 20px;\">Filters:</label>\n",
" <select id=\"conv-filters\">\n",
" <option value=\"16\">16</option>\n",
" <option value=\"32\">32</option>\n",
" <option value=\"64\">64</option>\n",
" </select>\n",
" \n",
" <button onclick=\"runConvDemo()\" style=\"margin-left: 10px;\">Run Convolution</button>\n",
" </div>\n",
" \n",
" <div id=\"conv-results\"></div>\n",
"</div>\n",
"\n",
"<script>\n",
"function conv2d(input, kernel, inputSize, kernelSize) {\n",
" const outputSize = inputSize - kernelSize + 1;\n",
" const output = new Float32Array(outputSize * outputSize);\n",
" \n",
" for (let y = 0; y < outputSize; y++) {\n",
" for (let x = 0; x < outputSize; x++) {\n",
" let sum = 0;\n",
" \n",
" for (let ky = 0; ky < kernelSize; ky++) {\n",
" for (let kx = 0; kx < kernelSize; kx++) {\n",
" const inputIdx = (y + ky) * inputSize + (x + kx);\n",
" const kernelIdx = ky * kernelSize + kx;\n",
" sum += input[inputIdx] * kernel[kernelIdx];\n",
" }\n",
" }\n",
" \n",
" output[y * outputSize + x] = sum;\n",
" }\n",
" }\n",
" \n",
" return output;\n",
"}\n",
"\n",
"async function runConvDemo() {\n",
" const inputSize = parseInt(document.getElementById('conv-input-size').value);\n",
" const kernelSize = parseInt(document.getElementById('conv-kernel-size').value);\n",
" const numFilters = parseInt(document.getElementById('conv-filters').value);\n",
" const resultsDiv = document.getElementById('conv-results');\n",
" \n",
" resultsDiv.innerHTML = '<p>Running convolution...</p>';\n",
" \n",
" try {\n",
" // Create input image (3 channels for RGB)\n",
" const channels = 3;\n",
" const input = new Float32Array(inputSize * inputSize * channels);\n",
" for (let i = 0; i < input.length; i++) {\n",
" input[i] = Math.random();\n",
" }\n",
" \n",
" // Create kernels\n",
" const kernels = [];\n",
" for (let f = 0; f < numFilters; f++) {\n",
" const kernel = [];\n",
" for (let c = 0; c < channels; c++) {\n",
" kernel.push(createRandomMatrix(kernelSize, kernelSize));\n",
" }\n",
" kernels.push(kernel);\n",
" }\n",
" \n",
" const start = performance.now();\n",
" \n",
" // Perform convolution\n",
" const outputSize = inputSize - kernelSize + 1;\n",
" const outputs = [];\n",
" \n",
" for (let f = 0; f < numFilters; f++) {\n",
" const filterOutput = new Float32Array(outputSize * outputSize);\n",
" \n",
" for (let c = 0; c < channels; c++) {\n",
" const channelInput = input.slice(\n",
" c * inputSize * inputSize, \n",
" (c + 1) * inputSize * inputSize\n",
" );\n",
" \n",
" const channelOutput = conv2d(\n",
" channelInput, \n",
" kernels[f][c], \n",
" inputSize, \n",
" kernelSize\n",
" );\n",
" \n",
" // Accumulate\n",
" for (let i = 0; i < filterOutput.length; i++) {\n",
" filterOutput[i] += channelOutput[i];\n",
" }\n",
" }\n",
" \n",
" // Apply ReLU\n",
" for (let i = 0; i < filterOutput.length; i++) {\n",
" filterOutput[i] = Math.max(0, filterOutput[i]);\n",
" }\n",
" \n",
" outputs.push(filterOutput);\n",
" }\n",
" \n",
" const time = performance.now() - start;\n",
" \n",
" // Calculate operations\n",
" const ops = numFilters * channels * outputSize * outputSize * kernelSize * kernelSize * 2;\n",
" const gflops = (ops / (time * 1e6)).toFixed(2);\n",
" \n",
" resultsDiv.innerHTML = `\n",
" <h4>✅ Convolution Complete</h4>\n",
" \n",
" <h5>📐 Configuration:</h5>\n",
" <ul>\n",
" <li><strong>Input:</strong> ${inputSize}×${inputSize}×${channels}</li>\n",
" <li><strong>Kernel:</strong> ${kernelSize}×${kernelSize}</li>\n",
" <li><strong>Filters:</strong> ${numFilters}</li>\n",
" <li><strong>Output:</strong> ${outputSize}×${outputSize}×${numFilters}</li>\n",
" </ul>\n",
" \n",
" <h5>⚡ Performance:</h5>\n",
" <ul>\n",
" <li><strong>Time:</strong> ${time.toFixed(2)}ms</li>\n",
" <li><strong>Operations:</strong> ${(ops / 1e9).toFixed(2)} billion</li>\n",
" <li><strong>Throughput:</strong> ${gflops} GFLOPS</li>\n",
" </ul>\n",
" \n",
" <h5>📊 Output Statistics:</h5>\n",
" <ul>\n",
" <li><strong>Total output values:</strong> ${outputSize * outputSize * numFilters}</li>\n",
" <li><strong>Non-zero (after ReLU):</strong> ${outputs.reduce((sum, out) => \n",
" sum + out.filter(x => x > 0).length, 0)}</li>\n",
" <li><strong>Memory used:</strong> ${((inputSize * inputSize * channels + \n",
" outputSize * outputSize * numFilters) * 4 / 1024 / 1024).toFixed(2)} MB</li>\n",
" </ul>\n",
" `;\n",
" \n",
" } catch (error) {\n",
" resultsDiv.innerHTML = '❌ Error: ' + error.message;\n",
" }\n",
"}\n",
"</script>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Gradient Computation\n",
"## 3. 勾配計算"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%html\n",
"<div id=\"gradient-comp\">\n",
" <h3>📈 Automatic Differentiation Demo</h3>\n",
" \n",
" <div style=\"margin: 20px 0;\">\n",
" <label>Function:</label>\n",
" <select id=\"grad-function\">\n",
" <option value=\"quadratic\">f(x,y) = x² + 2xy + y²</option>\n",
" <option value=\"neural\">Neural Network Loss</option>\n",
" <option value=\"complex\">f(x,y,z) = sin(x)cos(y) + e^z</option>\n",
" </select>\n",
" \n",
" <button onclick=\"computeGradient()\" style=\"margin-left: 10px;\">Compute Gradient</button>\n",
" </div>\n",
" \n",
" <div id=\"gradient-results\"></div>\n",
"</div>\n",
"\n",
"<script>\n",
"function numericalGradient(f, x, h = 1e-5) {\n",
" const grad = [];\n",
" \n",
" for (let i = 0; i < x.length; i++) {\n",
" const xPlus = [...x];\n",
" const xMinus = [...x];\n",
" xPlus[i] += h;\n",
" xMinus[i] -= h;\n",
" \n",
" const gradI = (f(xPlus) - f(xMinus)) / (2 * h);\n",
" grad.push(gradI);\n",
" }\n",
" \n",
" return grad;\n",
"}\n",
"\n",
"async function computeGradient() {\n",
" const funcType = document.getElementById('grad-function').value;\n",
" const resultsDiv = document.getElementById('gradient-results');\n",
" \n",
" resultsDiv.innerHTML = '<p>Computing gradients...</p>';\n",
" \n",
" try {\n",
" let func, point, analyticalGrad;\n",
" \n",
" switch(funcType) {\n",
" case 'quadratic':\n",
" // f(x,y) = x² + 2xy + y²\n",
" func = ([x, y]) => x*x + 2*x*y + y*y;\n",
" point = [3.0, 2.0];\n",
" // Analytical gradient: [2x + 2y, 2x + 2y]\n",
" analyticalGrad = [2*point[0] + 2*point[1], 2*point[0] + 2*point[1]];\n",
" break;\n",
" \n",
" case 'neural':\n",
" // Simple neural network loss: MSE\n",
" func = (weights) => {\n",
" // Simulate forward pass and MSE loss\n",
" let loss = 0;\n",
" for (let i = 0; i < weights.length; i++) {\n",
" const pred = weights[i] * (i + 1); // Simple linear model\n",
" const target = 2 * (i + 1); // Target values\n",
" loss += Math.pow(pred - target, 2);\n",
" }\n",
" return loss / weights.length;\n",
" };\n",
" point = [1.5, 1.8, 1.2, 1.9];\n",
" analyticalGrad = point.map((w, i) => \n",
" 2 * (w * (i + 1) - 2 * (i + 1)) * (i + 1) / point.length\n",
" );\n",
" break;\n",
" \n",
" case 'complex':\n",
" // f(x,y,z) = sin(x)cos(y) + e^z\n",
" func = ([x, y, z]) => Math.sin(x) * Math.cos(y) + Math.exp(z);\n",
" point = [Math.PI/4, Math.PI/3, 0.5];\n",
" analyticalGrad = [\n",
" Math.cos(point[0]) * Math.cos(point[1]),\n",
" -Math.sin(point[0]) * Math.sin(point[1]),\n",
" Math.exp(point[2])\n",
" ];\n",
" break;\n",
" }\n",
" \n",
" // Compute numerical gradient\n",
" const start = performance.now();\n",
" const numericalGrad = numericalGradient(func, point);\n",
" const time = performance.now() - start;\n",
" \n",
" // Compute error\n",
" const errors = analyticalGrad.map((a, i) => \n",
" Math.abs(a - numericalGrad[i])\n",
" );\n",
" const maxError = Math.max(...errors);\n",
" \n",
" resultsDiv.innerHTML = `\n",
" <h4>✅ Gradient Computed</h4>\n",
" \n",
" <h5>📍 Evaluation Point:</h5>\n",
" <pre style=\"background: #f0f0f0; padding: 10px; border-radius: 5px;\">\n",
"${point.map((v, i) => `x[${i}] = ${v.toFixed(4)}`).join('\\n')}\n",
" </pre>\n",
" \n",
" <h5>🎯 Function Value:</h5>\n",
" <p><strong>f(x) = ${func(point).toFixed(6)}</strong></p>\n",
" \n",
" <h5>📊 Gradient Comparison:</h5>\n",
" <table style=\"width: 100%; border-collapse: collapse;\">\n",
" <tr style=\"background: #f0f0f0;\">\n",
" <th style=\"padding: 8px;\">Component</th>\n",
" <th style=\"padding: 8px;\">Analytical</th>\n",
" <th style=\"padding: 8px;\">Numerical</th>\n",
" <th style=\"padding: 8px;\">Error</th>\n",
" </tr>\n",
" ${analyticalGrad.map((a, i) => `\n",
" <tr>\n",
" <td style=\"padding: 8px;\">∂f/∂x[${i}]</td>\n",
" <td style=\"padding: 8px;\">${a.toFixed(6)}</td>\n",
" <td style=\"padding: 8px;\">${numericalGrad[i].toFixed(6)}</td>\n",
" <td style=\"padding: 8px; color: ${errors[i] < 1e-4 ? 'green' : 'orange'};\">\n",
" ${errors[i].toExponential(2)}\n",
" </td>\n",
" </tr>\n",
" `).join('')}\n",
" </table>\n",
" \n",
" <h5>⚡ Performance:</h5>\n",
" <ul>\n",
" <li><strong>Computation Time:</strong> ${time.toFixed(3)}ms</li>\n",
" <li><strong>Max Error:</strong> ${maxError.toExponential(2)}</li>\n",
" <li><strong>Accuracy:</strong> ${maxError < 1e-4 ? '✅ Excellent' : '⚠️ Good'}</li>\n",
" </ul>\n",
" `;\n",
" \n",
" } catch (error) {\n",
" resultsDiv.innerHTML = '❌ Error: ' + error.message;\n",
" }\n",
"}\n",
"</script>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Training Visualization\n",
"## 4. トレーニング可視化"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%html\n",
"<div id=\"training-viz\">\n",
" <h3>📉 Mini-Batch SGD Training Simulation</h3>\n",
" \n",
" <div style=\"margin: 20px 0;\">\n",
" <label>Learning Rate:</label>\n",
" <input type=\"range\" id=\"learning-rate\" min=\"0.001\" max=\"0.1\" step=\"0.001\" value=\"0.01\">\n",
" <span id=\"lr-value\">0.01</span>\n",
" \n",
" <button onclick=\"startTraining()\" style=\"margin-left: 20px;\">Start Training</button>\n",
" <button onclick=\"stopTraining()\">Stop</button>\n",
" </div>\n",
" \n",
" <canvas id=\"loss-chart\" width=\"600\" height=\"300\" style=\"border: 1px solid #ddd;\"></canvas>\n",
" \n",
" <div id=\"training-stats\"></div>\n",
"</div>\n",
"\n",
"<script>\n",
"let trainingInterval = null;\n",
"let epoch = 0;\n",
"let lossHistory = [];\n",
"\n",
"document.getElementById('learning-rate').addEventListener('input', (e) => {\n",
" document.getElementById('lr-value').textContent = e.target.value;\n",
"});\n",
"\n",
"function drawChart() {\n",
" const canvas = document.getElementById('loss-chart');\n",
" const ctx = canvas.getContext('2d');\n",
" \n",
" ctx.clearRect(0, 0, canvas.width, canvas.height);\n",
" \n",
" if (lossHistory.length < 2) return;\n",
" \n",
" // Draw axes\n",
" ctx.strokeStyle = '#333';\n",
" ctx.beginPath();\n",
" ctx.moveTo(40, 10);\n",
" ctx.lineTo(40, 260);\n",
" ctx.lineTo(580, 260);\n",
" ctx.stroke();\n",
" \n",
" // Draw loss curve\n",
" ctx.strokeStyle = '#4CAF50';\n",
" ctx.lineWidth = 2;\n",
" ctx.beginPath();\n",
" \n",
" const maxLoss = Math.max(...lossHistory);\n",
" const minLoss = Math.min(...lossHistory);\n",
" const range = maxLoss - minLoss || 1;\n",
" \n",
" lossHistory.forEach((loss, i) => {\n",
" const x = 40 + (i / (lossHistory.length - 1)) * 540;\n",
" const y = 260 - ((loss - minLoss) / range) * 240;\n",
" \n",
" if (i === 0) {\n",
" ctx.moveTo(x, y);\n",
" } else {\n",
" ctx.lineTo(x, y);\n",
" }\n",
" });\n",
" \n",
" ctx.stroke();\n",
" \n",
" // Draw labels\n",
" ctx.fillStyle = '#333';\n",
" ctx.font = '12px Arial';\n",
" ctx.fillText('Loss', 5, 135);\n",
" ctx.fillText('Epoch', 300, 280);\n",
" ctx.fillText(minLoss.toFixed(3), 5, 260);\n",
" ctx.fillText(maxLoss.toFixed(3), 5, 20);\n",
"}\n",
"\n",
"function simulateTrainingStep() {\n",
" const lr = parseFloat(document.getElementById('learning-rate').value);\n",
" \n",
" // Simulate loss reduction with noise\n",
" const baseLoss = 1.0 * Math.exp(-0.05 * epoch);\n",
" const noise = (Math.random() - 0.5) * 0.1;\n",
" const loss = Math.max(0.01, baseLoss + noise);\n",
" \n",
" lossHistory.push(loss);\n",
" if (lossHistory.length > 100) {\n",
" lossHistory.shift();\n",
" }\n",
" \n",
" epoch++;\n",
" \n",
" // Update chart\n",
" drawChart();\n",
" \n",
" // Update stats\n",
" const statsDiv = document.getElementById('training-stats');\n",
" const avgLoss = lossHistory.reduce((a, b) => a + b, 0) / lossHistory.length;\n",
" \n",
" statsDiv.innerHTML = `\n",
" <h5>📊 Training Statistics:</h5>\n",
" <ul>\n",
" <li><strong>Epoch:</strong> ${epoch}</li>\n",
" <li><strong>Current Loss:</strong> ${loss.toFixed(4)}</li>\n",
" <li><strong>Average Loss:</strong> ${avgLoss.toFixed(4)}</li>\n",
" <li><strong>Learning Rate:</strong> ${lr}</li>\n",
" <li><strong>Convergence:</strong> ${loss < 0.05 ? '✅ Achieved' : '⏳ In Progress'}</li>\n",
" </ul>\n",
" `;\n",
" \n",
" // Stop if converged\n",
" if (loss < 0.02) {\n",
" stopTraining();\n",
" statsDiv.innerHTML += '<p style=\"color: green; font-weight: bold;\">✅ Training Converged!</p>';\n",
" }\n",
"}\n",
"\n",
"function startTraining() {\n",
" if (trainingInterval) return;\n",
" \n",
" epoch = 0;\n",
" lossHistory = [];\n",
" trainingInterval = setInterval(simulateTrainingStep, 100);\n",
"}\n",
"\n",
"function stopTraining() {\n",
" if (trainingInterval) {\n",
" clearInterval(trainingInterval);\n",
" trainingInterval = null;\n",
" }\n",
"}\n",
"</script>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Summary\n",
"## まとめ\n",
"\n",
"This notebook demonstrates WebGPU-accelerated machine learning operations including:\n",
"\n",
"このノートブックは、以下を含むWebGPU加速機械学習演算をデモンストレーションしました:\n",
"\n",
"1. **Neural Network Operations / ニューラルネットワーク演算**\n",
" - Forward pass computation / 順伝播計算\n",
" - Activation functions / 活性化関数\n",
" - Batch processing / バッチ処理\n",
"\n",
"2. **Convolution Operations / 畳み込み演算**\n",
" - 2D convolutions / 2D畳み込み\n",
" - Multiple filters / 複数フィルタ\n",
" - Performance metrics / パフォーマンスメトリクス\n",
"\n",
"3. **Gradient Computation / 勾配計算**\n",
" - Numerical differentiation / 数値微分\n",
" - Automatic differentiation concepts / 自動微分の概念\n",
" - Error analysis / エラー分析\n",
"\n",
"4. **Training Visualization / トレーニング可視化**\n",
" - Loss curve tracking / 損失曲線の追跡\n",
" - Real-time updates / リアルタイム更新\n",
" - Convergence monitoring / 収束監視\n",
"\n",
"### Next Steps / 次のステップ\n",
"\n",
"- Implement actual WebGPU compute shaders / 実際のWebGPU計算シェーダーの実装\n",
"- Add support for larger models / より大きなモデルのサポートを追加\n",
"- Optimize memory transfers / メモリ転送の最適化\n",
"- Benchmark against native implementations / ネイティブ実装とのベンチマーク"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.19"
}
},
"nbformat": 4,
"nbformat_minor": 4
}