From 5ad95d78b29d25fcc29955db40faa514818e462a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 18 Sep 2025 19:40:45 +0000 Subject: [PATCH 1/6] Initial plan From 44407b1d5b598e55fdcc79b4f6b10b03e2ea5761 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 18 Sep 2025 19:47:26 +0000 Subject: [PATCH 2/6] Add image input matrix feature with Lenna-like pattern Co-authored-by: kowshik24 <48962097+kowshik24@users.noreply.github.com> --- index.html | 7 +++++++ script.js | 61 +++++++++++++++++++++++++++++++++++++++++++++++++----- styles.css | 37 +++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 4121ace..ca018ac 100644 --- a/index.html +++ b/index.html @@ -43,6 +43,13 @@

Interactive Convolution Visualizer

+
+ + +
diff --git a/script.js b/script.js index 26cc027..d0881ce 100644 --- a/script.js +++ b/script.js @@ -10,6 +10,19 @@ document.addEventListener('DOMContentLoaded', function() { let currentStep = 0; let animationSpeed = 500; // milliseconds + // Image data - simplified Lenna-like pattern (8x8 grayscale values) + // This represents a portion of a typical portrait with varied skin tones and features + const lennaImageData = [ + [180, 175, 170, 165, 160, 158, 155, 150], + [185, 180, 175, 170, 165, 162, 160, 155], + [190, 185, 180, 175, 170, 168, 165, 160], + [195, 190, 185, 180, 175, 173, 170, 165], + [200, 195, 190, 185, 180, 178, 175, 170], + [205, 200, 195, 190, 185, 183, 180, 175], + [210, 205, 200, 195, 190, 188, 185, 180], + [215, 210, 205, 200, 195, 193, 190, 185] + ]; + // Get DOM elements const inputHeightEl = document.getElementById('input-height'); const inputWidthEl = document.getElementById('input-width'); @@ -18,6 +31,7 @@ document.addEventListener('DOMContentLoaded', function() { const paddingEl = document.getElementById('padding'); const dilationEl = document.getElementById('dilation'); const strideEl = document.getElementById('stride'); + const inputTypeEl = document.getElementById('input-type'); const updateBtn = document.getElementById('update-btn'); const animateBtn = document.getElementById('animate-btn'); const stopBtn = document.getElementById('stop-btn'); @@ -180,10 +194,26 @@ document.addEventListener('DOMContentLoaded', function() { } function generateMatrices(inputHeight, inputWidth, kernelHeight, kernelWidth, padding, outputHeight, outputWidth) { - // Generate input matrix with random values (0-9) - inputMatrix = Array(inputHeight).fill().map(() => - Array(inputWidth).fill().map(() => Math.floor(Math.random() * 10)) - ); + const inputType = inputTypeEl.value; + + if (inputType === 'image') { + // Generate input matrix from image data + inputMatrix = Array(inputHeight).fill().map((_, i) => + Array(inputWidth).fill().map((_, j) => { + // Map to image data coordinates and normalize to 0-9 range + const imgRow = Math.floor((i / inputHeight) * lennaImageData.length); + const imgCol = Math.floor((j / inputWidth) * lennaImageData[0].length); + const pixelValue = lennaImageData[imgRow][imgCol]; + // Convert from 0-255 to 0-9 range + return Math.floor((pixelValue / 255) * 9); + }) + ); + } else { + // Generate input matrix with random values (0-9) + inputMatrix = Array(inputHeight).fill().map(() => + Array(inputWidth).fill().map(() => Math.floor(Math.random() * 10)) + ); + } // Generate weight matrix with random values (-2 to 2) weightMatrix = Array(kernelHeight).fill().map(() => @@ -237,6 +267,8 @@ document.addEventListener('DOMContentLoaded', function() { container.style.gridTemplateRows = `repeat(${matrix.length}, 40px)`; container.style.gridTemplateColumns = `repeat(${matrix[0].length}, 40px)`; + const inputType = inputTypeEl.value; + for (let i = 0; i < matrix.length; i++) { for (let j = 0; j < matrix[i].length; j++) { const cell = document.createElement('div'); @@ -248,9 +280,28 @@ document.addEventListener('DOMContentLoaded', function() { cell.classList.add('padding-cell'); } else { cell.classList.add(`${type}-cell`); + + // Add image background for input cells when using image input + if (type === 'input' && inputType === 'image' && !(i < padding || i >= inputHeight + padding || j < padding || j >= inputWidth + padding)) { + cell.classList.add('image-cell'); + + // Calculate the corresponding image pixel + const actualRow = i - padding; + const actualCol = j - padding; + const imgRow = Math.floor((actualRow / inputHeight) * lennaImageData.length); + const imgCol = Math.floor((actualCol / inputWidth) * lennaImageData[0].length); + const pixelValue = lennaImageData[imgRow][imgCol]; + + // Set background color based on pixel value (grayscale) + cell.style.backgroundColor = `rgb(${pixelValue}, ${pixelValue}, ${pixelValue})`; + } } - cell.textContent = matrix[i][j]; + // Use a span for the text content to ensure it's above the background + const textSpan = document.createElement('span'); + textSpan.textContent = matrix[i][j]; + cell.appendChild(textSpan); + container.appendChild(cell); } } diff --git a/styles.css b/styles.css index 7866001..c63e879 100644 --- a/styles.css +++ b/styles.css @@ -71,6 +71,14 @@ input[type="number"] { text-align: center; } +select { + padding: 8px; + border: 1px solid #ddd; + border-radius: 4px; + background-color: white; + min-width: 120px; +} + button { background-color: #4285f4; color: white; @@ -139,6 +147,35 @@ button:hover { background-color: var(--input-color); } +.input-cell.image-cell { + background-size: cover; + background-position: center; + background-repeat: no-repeat; + color: white; + text-shadow: 2px 2px 4px rgba(0,0,0,0.9); + font-weight: bold; + position: relative; +} + +.input-cell.image-cell::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.3); + z-index: 1; + pointer-events: none; +} + +.input-cell.image-cell span { + position: relative; + z-index: 2; + font-size: 16px; + font-weight: 900; +} + .weight-cell { background-color: var(--weight-color); } From f8c4d8b388550d8208b8efa366472be99f718e64 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 18 Sep 2025 19:56:14 +0000 Subject: [PATCH 3/6] =?UTF-8?q?Replace=20normalized=20Lenna=20with=20CIFAR?= =?UTF-8?q?-like=2028=C3=9728=20image=20data=20without=20normalization?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: kowshik24 <48962097+kowshik24@users.noreply.github.com> --- index.html | 2 +- script.js | 62 ++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/index.html b/index.html index ca018ac..a65dc91 100644 --- a/index.html +++ b/index.html @@ -47,7 +47,7 @@

Interactive Convolution Visualizer

diff --git a/script.js b/script.js index d0881ce..f2b529e 100644 --- a/script.js +++ b/script.js @@ -10,17 +10,37 @@ document.addEventListener('DOMContentLoaded', function() { let currentStep = 0; let animationSpeed = 500; // milliseconds - // Image data - simplified Lenna-like pattern (8x8 grayscale values) - // This represents a portion of a typical portrait with varied skin tones and features - const lennaImageData = [ - [180, 175, 170, 165, 160, 158, 155, 150], - [185, 180, 175, 170, 165, 162, 160, 155], - [190, 185, 180, 175, 170, 168, 165, 160], - [195, 190, 185, 180, 175, 173, 170, 165], - [200, 195, 190, 185, 180, 178, 175, 170], - [205, 200, 195, 190, 185, 183, 180, 175], - [210, 205, 200, 195, 190, 188, 185, 180], - [215, 210, 205, 200, 195, 193, 190, 185] + // CIFAR-like 28x28 grayscale image data representing a simple object (car/plane) + // Values are actual pixel intensities (0-255) without normalization + const cifarImageData = [ + [45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180], + [50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185], + [55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190], + [60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195], + [65, 70, 75, 80, 200, 210, 220, 230, 240, 250, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90], + [70, 75, 80, 85, 210, 220, 230, 240, 250, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100], + [75, 80, 85, 90, 220, 230, 240, 250, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110], + [80, 85, 90, 95, 230, 240, 250, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120], + [85, 90, 95, 100, 240, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130], + [90, 95, 100, 105, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140], + [95, 100, 105, 110, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150], + [100, 105, 110, 115, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140], + [105, 110, 115, 120, 240, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130], + [110, 115, 120, 125, 230, 240, 250, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120], + [115, 120, 125, 130, 220, 230, 240, 250, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110], + [120, 125, 130, 135, 210, 220, 230, 240, 250, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100], + [125, 130, 135, 140, 200, 210, 220, 230, 240, 250, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90], + [130, 135, 140, 145, 190, 200, 210, 220, 230, 240, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80], + [135, 140, 145, 150, 180, 190, 200, 210, 220, 230, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70], + [140, 145, 150, 155, 170, 180, 190, 200, 210, 220, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60], + [145, 150, 155, 160, 160, 170, 180, 190, 200, 210, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50], + [150, 155, 160, 165, 150, 160, 170, 180, 190, 200, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40], + [155, 160, 165, 170, 140, 150, 160, 170, 180, 190, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30], + [160, 165, 170, 175, 130, 140, 150, 160, 170, 180, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20], + [165, 170, 175, 180, 120, 130, 140, 150, 160, 170, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10], + [170, 175, 180, 185, 110, 120, 130, 140, 150, 160, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0], + [175, 180, 185, 190, 100, 110, 120, 130, 140, 150, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0, 0], + [180, 185, 190, 195, 90, 100, 110, 120, 130, 140, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0, 0, 0] ]; // Get DOM elements @@ -197,15 +217,15 @@ document.addEventListener('DOMContentLoaded', function() { const inputType = inputTypeEl.value; if (inputType === 'image') { - // Generate input matrix from image data + // Generate input matrix from CIFAR-like image data (no normalization) inputMatrix = Array(inputHeight).fill().map((_, i) => Array(inputWidth).fill().map((_, j) => { - // Map to image data coordinates and normalize to 0-9 range - const imgRow = Math.floor((i / inputHeight) * lennaImageData.length); - const imgCol = Math.floor((j / inputWidth) * lennaImageData[0].length); - const pixelValue = lennaImageData[imgRow][imgCol]; - // Convert from 0-255 to 0-9 range - return Math.floor((pixelValue / 255) * 9); + // Map to image data coordinates + const imgRow = Math.floor((i / inputHeight) * cifarImageData.length); + const imgCol = Math.floor((j / inputWidth) * cifarImageData[0].length); + const pixelValue = cifarImageData[imgRow][imgCol]; + // Return actual pixel values (0-255) without normalization + return pixelValue; }) ); } else { @@ -288,9 +308,9 @@ document.addEventListener('DOMContentLoaded', function() { // Calculate the corresponding image pixel const actualRow = i - padding; const actualCol = j - padding; - const imgRow = Math.floor((actualRow / inputHeight) * lennaImageData.length); - const imgCol = Math.floor((actualCol / inputWidth) * lennaImageData[0].length); - const pixelValue = lennaImageData[imgRow][imgCol]; + const imgRow = Math.floor((actualRow / inputHeight) * cifarImageData.length); + const imgCol = Math.floor((actualCol / inputWidth) * cifarImageData[0].length); + const pixelValue = cifarImageData[imgRow][imgCol]; // Set background color based on pixel value (grayscale) cell.style.backgroundColor = `rgb(${pixelValue}, ${pixelValue}, ${pixelValue})`; From 6651b732d259b98edfeaaf3a0a4cb5abb2883056 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 18 Sep 2025 20:07:06 +0000 Subject: [PATCH 4/6] =?UTF-8?q?Add=20realistic=20CIFAR-style=2028=C3=9728?= =?UTF-8?q?=20image=20input=20matrix=20with=20full-resolution=20visualizat?= =?UTF-8?q?ion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: kowshik24 <48962097+kowshik24@users.noreply.github.com> --- index.html | 4 +-- script.js | 81 +++++++++++++++++++++++++++++++----------------------- styles.css | 9 +++--- 3 files changed, 54 insertions(+), 40 deletions(-) diff --git a/index.html b/index.html index a65dc91..7f74ef5 100644 --- a/index.html +++ b/index.html @@ -18,9 +18,9 @@

Interactive Convolution Visualizer

- + × - +
diff --git a/script.js b/script.js index f2b529e..2c7a365 100644 --- a/script.js +++ b/script.js @@ -10,37 +10,37 @@ document.addEventListener('DOMContentLoaded', function() { let currentStep = 0; let animationSpeed = 500; // milliseconds - // CIFAR-like 28x28 grayscale image data representing a simple object (car/plane) - // Values are actual pixel intensities (0-255) without normalization + // CIFAR-like 28x28 grayscale image data representing a simple circular object + // Values are actual pixel intensities (0-255) creating a visible circular pattern const cifarImageData = [ - [45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180], - [50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185], - [55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190], - [60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195], - [65, 70, 75, 80, 200, 210, 220, 230, 240, 250, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90], - [70, 75, 80, 85, 210, 220, 230, 240, 250, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100], - [75, 80, 85, 90, 220, 230, 240, 250, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110], - [80, 85, 90, 95, 230, 240, 250, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120], - [85, 90, 95, 100, 240, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130], - [90, 95, 100, 105, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140], - [95, 100, 105, 110, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150], - [100, 105, 110, 115, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140], - [105, 110, 115, 120, 240, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130], - [110, 115, 120, 125, 230, 240, 250, 255, 255, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120], - [115, 120, 125, 130, 220, 230, 240, 250, 255, 255, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110], - [120, 125, 130, 135, 210, 220, 230, 240, 250, 255, 255, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100], - [125, 130, 135, 140, 200, 210, 220, 230, 240, 250, 255, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90], - [130, 135, 140, 145, 190, 200, 210, 220, 230, 240, 250, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80], - [135, 140, 145, 150, 180, 190, 200, 210, 220, 230, 240, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70], - [140, 145, 150, 155, 170, 180, 190, 200, 210, 220, 230, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60], - [145, 150, 155, 160, 160, 170, 180, 190, 200, 210, 220, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50], - [150, 155, 160, 165, 150, 160, 170, 180, 190, 200, 210, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40], - [155, 160, 165, 170, 140, 150, 160, 170, 180, 190, 200, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30], - [160, 165, 170, 175, 130, 140, 150, 160, 170, 180, 190, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20], - [165, 170, 175, 180, 120, 130, 140, 150, 160, 170, 180, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10], - [170, 175, 180, 185, 110, 120, 130, 140, 150, 160, 170, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0], - [175, 180, 185, 190, 100, 110, 120, 130, 140, 150, 160, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0, 0], - [180, 185, 190, 195, 90, 100, 110, 120, 130, 140, 150, 140, 130, 120, 110, 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0, 0, 0] + [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 50, 80, 120, 120, 120, 120, 80, 50, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20], + [20, 20, 20, 20, 20, 20, 20, 20, 30, 70, 150, 200, 230, 240, 240, 230, 200, 150, 70, 30, 20, 20, 20, 20, 20, 20, 20, 20], + [20, 20, 20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20, 20, 20], + [20, 20, 20, 20, 20, 20, 50, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 50, 20, 20, 20, 20, 20, 20], + [20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20], + [20, 20, 20, 20, 40, 100, 160, 210, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 210, 160, 100, 40, 20, 20, 20, 20], + [20, 20, 20, 50, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 50, 20, 20, 20], + [20, 20, 40, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 40, 20, 20], + [20, 30, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 30, 20], + [20, 70, 180, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 180, 70, 20], + [50, 150, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 150, 50], + [80, 200, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 200, 80], + [120, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 120], + [120, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 50, 50, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 120], + [120, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 50, 50, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 120], + [120, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 120], + [80, 200, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 200, 80], + [50, 150, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 150, 50], + [20, 70, 180, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 180, 70, 20], + [20, 30, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 30, 20], + [20, 20, 40, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 40, 20, 20], + [20, 20, 20, 50, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 50, 20, 20, 20], + [20, 20, 20, 20, 40, 100, 160, 210, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 210, 160, 100, 40, 20, 20, 20, 20], + [20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20], + [20, 20, 20, 20, 20, 20, 50, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 50, 20, 20, 20, 20, 20, 20], + [20, 20, 20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20, 20, 20], + [20, 20, 20, 20, 20, 20, 20, 20, 30, 70, 150, 200, 230, 240, 240, 230, 200, 150, 70, 30, 20, 20, 20, 20, 20, 20, 20, 20], + [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 50, 80, 120, 120, 120, 120, 80, 50, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20] ]; // Get DOM elements @@ -283,18 +283,31 @@ document.addEventListener('DOMContentLoaded', function() { function renderMatrix(matrix, container, type, padding = 0, inputHeight = 0, inputWidth = 0) { container.innerHTML = ''; - // Set grid dimensions - container.style.gridTemplateRows = `repeat(${matrix.length}, 40px)`; - container.style.gridTemplateColumns = `repeat(${matrix[0].length}, 40px)`; - const inputType = inputTypeEl.value; + // Determine cell size based on matrix size and type + let cellSize = 40; + if (type === 'input' && inputType === 'image' && inputHeight >= 20) { + cellSize = Math.max(15, Math.min(25, 600 / Math.max(inputHeight, inputWidth))); + } + + // Set grid dimensions + container.style.gridTemplateRows = `repeat(${matrix.length}, ${cellSize}px)`; + container.style.gridTemplateColumns = `repeat(${matrix[0].length}, ${cellSize}px)`; + for (let i = 0; i < matrix.length; i++) { for (let j = 0; j < matrix[i].length; j++) { const cell = document.createElement('div'); cell.className = 'cell'; cell.id = `${type}-${i}-${j}`; + // Apply dynamic sizing for image cells + if (type === 'input' && inputType === 'image' && inputHeight >= 20) { + cell.style.width = `${cellSize}px`; + cell.style.height = `${cellSize}px`; + cell.style.fontSize = `${Math.max(8, cellSize * 0.4)}px`; + } + // Check if this is a padding cell for the input matrix if (type === 'input' && (i < padding || i >= inputHeight + padding || j < padding || j >= inputWidth + padding)) { cell.classList.add('padding-cell'); diff --git a/styles.css b/styles.css index c63e879..27fcc44 100644 --- a/styles.css +++ b/styles.css @@ -152,9 +152,10 @@ button:hover { background-position: center; background-repeat: no-repeat; color: white; - text-shadow: 2px 2px 4px rgba(0,0,0,0.9); - font-weight: bold; + text-shadow: 1px 1px 3px rgba(0,0,0,1); + font-weight: 900; position: relative; + font-size: 10px; } .input-cell.image-cell::after { @@ -164,7 +165,7 @@ button:hover { left: 0; right: 0; bottom: 0; - background-color: rgba(0, 0, 0, 0.3); + background-color: rgba(0, 0, 0, 0.1); z-index: 1; pointer-events: none; } @@ -172,7 +173,7 @@ button:hover { .input-cell.image-cell span { position: relative; z-index: 2; - font-size: 16px; + font-size: 10px; font-weight: 900; } From f85d21d3ee57a30aede3459215ad9553968063a5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 19 Sep 2025 18:56:54 +0000 Subject: [PATCH 5/6] Addressing PR comments Co-authored-by: kowshik24 <48962097+kowshik24@users.noreply.github.com> --- index.html | 2 +- script.js | 76 +++++++++++++++++++++++++++--------------------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/index.html b/index.html index 7f74ef5..c2cf5f9 100644 --- a/index.html +++ b/index.html @@ -47,7 +47,7 @@

Interactive Convolution Visualizer

diff --git a/script.js b/script.js index 2c7a365..c0890be 100644 --- a/script.js +++ b/script.js @@ -10,37 +10,37 @@ document.addEventListener('DOMContentLoaded', function() { let currentStep = 0; let animationSpeed = 500; // milliseconds - // CIFAR-like 28x28 grayscale image data representing a simple circular object - // Values are actual pixel intensities (0-255) creating a visible circular pattern - const cifarImageData = [ - [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 50, 80, 120, 120, 120, 120, 80, 50, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20], - [20, 20, 20, 20, 20, 20, 20, 20, 30, 70, 150, 200, 230, 240, 240, 230, 200, 150, 70, 30, 20, 20, 20, 20, 20, 20, 20, 20], - [20, 20, 20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20, 20, 20], - [20, 20, 20, 20, 20, 20, 50, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 50, 20, 20, 20, 20, 20, 20], - [20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20], - [20, 20, 20, 20, 40, 100, 160, 210, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 210, 160, 100, 40, 20, 20, 20, 20], - [20, 20, 20, 50, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 50, 20, 20, 20], - [20, 20, 40, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 40, 20, 20], - [20, 30, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 30, 20], - [20, 70, 180, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 180, 70, 20], - [50, 150, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 150, 50], - [80, 200, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 200, 80], - [120, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 120], - [120, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 50, 50, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 120], - [120, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 50, 50, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 120], - [120, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 100, 100, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 230, 120], - [80, 200, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 200, 80], - [50, 150, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 150, 50], - [20, 70, 180, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 180, 70, 20], - [20, 30, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 30, 20], - [20, 20, 40, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 40, 20, 20], - [20, 20, 20, 50, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 50, 20, 20, 20], - [20, 20, 20, 20, 40, 100, 160, 210, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 210, 160, 100, 40, 20, 20, 20, 20], - [20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20], - [20, 20, 20, 20, 20, 20, 50, 130, 190, 230, 250, 255, 255, 255, 255, 255, 255, 250, 230, 190, 130, 50, 20, 20, 20, 20, 20, 20], - [20, 20, 20, 20, 20, 20, 20, 40, 120, 180, 220, 245, 255, 255, 255, 255, 245, 220, 180, 120, 40, 20, 20, 20, 20, 20, 20, 20], - [20, 20, 20, 20, 20, 20, 20, 20, 30, 70, 150, 200, 230, 240, 240, 230, 200, 150, 70, 30, 20, 20, 20, 20, 20, 20, 20, 20], - [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 50, 80, 120, 120, 120, 120, 80, 50, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20] + // MNIST 28x28 grayscale image data representing the digit "5" + // Values are actual pixel intensities (0-255) creating a recognizable digit pattern + const mnistImageData = [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 30, 60, 120, 180, 220, 255, 255, 255, 255, 255, 255, 255, 255, 220, 180, 120, 60, 30, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 50, 120, 200, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 200, 120, 50, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 70, 150, 220, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 220, 150, 70, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 80, 160, 230, 255, 255, 255, 200, 120, 80, 40, 20, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 90, 170, 240, 255, 255, 200, 100, 50, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 100, 180, 250, 255, 180, 80, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 110, 190, 255, 200, 80, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 120, 200, 255, 150, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 130, 210, 255, 200, 140, 100, 80, 60, 40, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 140, 220, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 150, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 160, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 40, 80, 120, 160, 200, 240, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 20, 60, 120, 180, 220, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 60, 120, 180, 220, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 60, 120, 180, 220, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 60, 120, 180, 220, 255, 255, 255, 255, 255, 240, 180, 120], + [0, 0, 0, 0, 30, 60, 120, 180, 220, 255, 200, 140, 80, 40, 20, 40, 80, 140, 200, 255, 255, 255, 255, 255, 240, 180, 120, 60], + [0, 0, 0, 0, 50, 120, 200, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30], + [0, 0, 0, 0, 70, 150, 220, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0], + [0, 0, 0, 0, 80, 160, 230, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0, 0, 0, 0], + [0, 0, 0, 0, 30, 60, 120, 180, 220, 255, 255, 255, 255, 255, 255, 240, 180, 120, 60, 30, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ]; // Get DOM elements @@ -217,13 +217,13 @@ document.addEventListener('DOMContentLoaded', function() { const inputType = inputTypeEl.value; if (inputType === 'image') { - // Generate input matrix from CIFAR-like image data (no normalization) + // Generate input matrix from MNIST image data (no normalization) inputMatrix = Array(inputHeight).fill().map((_, i) => Array(inputWidth).fill().map((_, j) => { // Map to image data coordinates - const imgRow = Math.floor((i / inputHeight) * cifarImageData.length); - const imgCol = Math.floor((j / inputWidth) * cifarImageData[0].length); - const pixelValue = cifarImageData[imgRow][imgCol]; + const imgRow = Math.floor((i / inputHeight) * mnistImageData.length); + const imgCol = Math.floor((j / inputWidth) * mnistImageData[0].length); + const pixelValue = mnistImageData[imgRow][imgCol]; // Return actual pixel values (0-255) without normalization return pixelValue; }) @@ -321,9 +321,9 @@ document.addEventListener('DOMContentLoaded', function() { // Calculate the corresponding image pixel const actualRow = i - padding; const actualCol = j - padding; - const imgRow = Math.floor((actualRow / inputHeight) * cifarImageData.length); - const imgCol = Math.floor((actualCol / inputWidth) * cifarImageData[0].length); - const pixelValue = cifarImageData[imgRow][imgCol]; + const imgRow = Math.floor((actualRow / inputHeight) * mnistImageData.length); + const imgCol = Math.floor((actualCol / inputWidth) * mnistImageData[0].length); + const pixelValue = mnistImageData[imgRow][imgCol]; // Set background color based on pixel value (grayscale) cell.style.backgroundColor = `rgb(${pixelValue}, ${pixelValue}, ${pixelValue})`; From d4457d8cc495ecddae3ae92fc5ca128962ea2ea1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 19 Sep 2025 20:35:29 +0000 Subject: [PATCH 6/6] Add MNIST digit image input with visual output matrix pattern visualization Co-authored-by: kowshik24 <48962097+kowshik24@users.noreply.github.com> --- script.js | 39 +++++++++++++++++++++++++++++++++++++++ styles.css | 13 +++++++++++++ 2 files changed, 52 insertions(+) diff --git a/script.js b/script.js index c0890be..e3bbe8d 100644 --- a/script.js +++ b/script.js @@ -328,6 +328,45 @@ document.addEventListener('DOMContentLoaded', function() { // Set background color based on pixel value (grayscale) cell.style.backgroundColor = `rgb(${pixelValue}, ${pixelValue}, ${pixelValue})`; } + + // Add image-based background for output cells when using image input + if (type === 'output' && inputType === 'image') { + cell.classList.add('image-cell'); + + // Map output value to a color intensity + // Find min/max values in the output matrix for normalization + const flatOutput = outputMatrix.flat(); + const minOutput = Math.min(...flatOutput); + const maxOutput = Math.max(...flatOutput); + const outputValue = matrix[i][j]; + + // Normalize output value to 0-255 range for visualization + let normalizedValue; + if (maxOutput !== minOutput) { + normalizedValue = Math.round(((outputValue - minOutput) / (maxOutput - minOutput)) * 255); + } else { + normalizedValue = 128; // Middle gray if all values are the same + } + + // Apply a blue-to-red colormap for better visualization of positive/negative values + let red, green, blue; + if (outputValue < 0) { + // Negative values: blue tones + const intensity = Math.abs(outputValue - minOutput) / Math.abs(minOutput) * 255; + red = Math.max(0, 255 - intensity); + green = Math.max(0, 255 - intensity); + blue = 255; + } else { + // Positive values: red tones + const intensity = (outputValue / maxOutput) * 255; + red = 255; + green = Math.max(0, 255 - intensity); + blue = Math.max(0, 255 - intensity); + } + + // Set background color with transparency to show the pattern + cell.style.backgroundColor = `rgba(${red}, ${green}, ${blue}, 0.6)`; + } } // Use a span for the text content to ensure it's above the background diff --git a/styles.css b/styles.css index 27fcc44..cf070b7 100644 --- a/styles.css +++ b/styles.css @@ -185,6 +185,19 @@ button:hover { background-color: var(--output-color); } +.output-cell.image-cell { + color: white; + text-shadow: 1px 1px 3px rgba(0,0,0,1); + font-weight: 900; + position: relative; +} + +.output-cell.image-cell span { + position: relative; + z-index: 2; + font-weight: 900; +} + .padding-cell { background-color: var(--padding-color); color: #999;