Convolutional Neural Networks
Step a kernel across an image to build feature maps, then pool and stack layers
Input pattern
Padding P
Stride S
Input 8×8
Click or drag to paint. Grey cells are zero padding.
Kernel 3×3
Pick a preset or type your own weights (−9 to 9).
Position (0, 0): multiply and sum
Σ = 1
Feature map 6×6
Filled cell by cell: 1 of 36
Orange = positive response, blue = negative.
ReLU 6×6
max(0, x) keeps only positive responses.
Finish the scan to apply ReLU to the whole feature map.
Max pool 2×2 → 3×3
Each output keeps the largest value in its 2×2 block.
Finish the scan to pool the ReLU output.
Through a small CNN
Spatial size shrinks with pooling while the number of feature maps (channels) grows. Shapes and parameter counts are computed with the same formula.
| Layer | Operation | Output shape | Parameters |
|---|---|---|---|
| Input | grayscale image | 28×28×1 | 0 |
| Conv 1 + ReLU | 8 filters 3×3, P=1, S=1 | 28×28×8 | 80 |
| Pool 1 | max 2×2, S=2 | 14×14×8 | 0 |
| Conv 2 + ReLU | 16 filters 3×3, P=1, S=1 | 14×14×16 | 1,168 |
| Pool 2 | max 2×2, S=2 | 7×7×16 | 0 |
| Conv 3 + ReLU | 32 filters 3×3, P=0, S=1 | 5×5×32 | 4,640 |
| Dense | flatten 800 → 10 classes | 10 | 8,010 |
What a convolution layer does
A convolutional layer slides a small kernel over the image. At each position it multiplies the kernel weights with the pixels underneath, adds them up, and writes that single number into the feature map. Because the same weights are used everywhere, a kernel that detects a vertical edge finds it anywhere in the image.
After the convolution, a ReLU zeroes out negative responses and a max-pooling layer shrinks the map by keeping the largest value in each 2×2 block. Real networks learn dozens of kernels per layer and stack several layers, so early layers respond to edges and later layers to whole shapes.
The kernels in this visualizer are hand-picked classics (edge detectors, blur, sharpen) so you can predict what they do. In a trained CNN the values are learned by backpropagation and are rarely this tidy.
Key formulas
Output size
O = ⌊(W − K + 2P) / S⌋ + 1
- W
- input width (or height)
- K
- kernel size
- P
- padding added on each side
- S
- stride
One feature-map value
y[i, j] = Σa Σb k[a, b] · x[i·S + a, j·S + b] + bias
Parameters in a conv layer
params = (K · K · Cin + 1) · Cout
- C_in
- input channels
- C_out
- number of filters (output channels)
How to use this visualizer
- 1Pick an input pattern or paint your own by clicking and dragging on the 8×8 grid.
- 2Choose a kernel preset or type weights into the 3×3 kernel. Try the vertical and horizontal edge detectors on the same image.
- 3Press Play or Step to slide the kernel. The panel under the kernel shows each pixel × weight product and their sum for the current position.
- 4Switch padding between 0 and 1 and stride between 1 and 2, and watch the output-size formula and the feature map change shape.
- 5Press Finish to complete the scan, then compare the ReLU output with the 2×2 max-pooled result.
- 6Scroll to the layer-stack diagram to see how these operations shape a full (small) CNN.
Key concepts
Kernel (filter)
Feature map
Stride and padding
Pooling
Channels
Receptive field
Code
import numpy as np
def conv2d(x, k, stride=1, pad=0):
"""Single-channel 2D convolution (cross-correlation, as in deep learning)."""
x = np.pad(x, pad) # zero padding
K = k.shape[0]
out = (x.shape[0] - K) // stride + 1 # = (W - K + 2P) // S + 1
y = np.zeros((out, out))
for i in range(out):
for j in range(out):
patch = x[i*stride:i*stride+K, j*stride:j*stride+K]
y[i, j] = np.sum(patch * k) # element-wise multiply, then sum
return y
def max_pool(y, size=2):
n = y.shape[0] // size
return y[:n*size, :n*size].reshape(n, size, n, size).max(axis=(1, 3))
feature = np.maximum(conv2d(image, kernel, stride=1, pad=0), 0) # ReLU
pooled = max_pool(feature)Practice problems
Problem 1: Output sizes
Show solutionHide solution
Stride 1: O = ⌊(32 − 5 + 2·2) / 1⌋ + 1 = 31 + 1 = 32
Stride 2: O = ⌊(32 − 5 + 2·2) / 2⌋ + 1 = ⌊31 / 2⌋ + 1 = 15 + 1 = 16
32×32 with stride 1 (a "same" convolution), 16×16 with stride 2
Problem 2: Shapes and parameters
Show solutionHide solution
Conv: O = ⌊(64 − 3 + 2) / 1⌋ + 1 = 64, one map per filter → 64×64×16
Pool 2×2, stride 2: 64 / 2 = 32 → 32×32×16
Each filter spans all 3 input channels: 3·3·3 = 27 weights + 1 bias = 28
params = 28 · 16 = 448 (pooling has none)
64×64×16, then 32×32×16; 448 parameters
Discussion
Questions, ideas or a different approach? Join the conversation.