Convolutional Neural Networks

Step a kernel across an image to build feature maps, then pool and stack layers

IntermediateConvolutionFeature MapsPoolingStride & Padding

Input pattern

Padding P

Stride S

O = ⌊(W − K + 2P) / S⌋ + 1 = ⌊(8 − 3 + 2·0) / 1⌋ + 1 = 6 → feature map 6×6, after 2×2 pooling 3×3

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

0·(-1)
0·0
0·1
0·(-1)
1·0
1·1
0·(-1)
0·0
0·1

Σ = 1

Feature map 6×6

Filled cell by cell: 1 of 36

1

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.

Input28×28×1Conv 1 + ReLU28×28×8Pool 114×14×8Conv 2 + ReLU14×14×16Pool 27×7×16Conv 3 + ReLU5×5×32Dense10
LayerOperationOutput shapeParameters
Inputgrayscale image28×28×10
Conv 1 + ReLU8 filters 3×3, P=1, S=128×28×880
Pool 1max 2×2, S=214×14×80
Conv 2 + ReLU16 filters 3×3, P=1, S=114×14×161,168
Pool 2max 2×2, S=27×7×160
Conv 3 + ReLU32 filters 3×3, P=0, S=15×5×324,640
Denseflatten 800 → 10 classes108,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)
Deep learning libraries actually compute cross-correlation (the kernel is not flipped). Since the kernel is learned, the difference does not matter, and this page follows the same convention.

How to use this visualizer

  1. 1
    Pick an input pattern or paint your own by clicking and dragging on the 8×8 grid.
  2. 2
    Choose a kernel preset or type weights into the 3×3 kernel. Try the vertical and horizontal edge detectors on the same image.
  3. 3
    Press Play or Step to slide the kernel. The panel under the kernel shows each pixel × weight product and their sum for the current position.
  4. 4
    Switch padding between 0 and 1 and stride between 1 and 2, and watch the output-size formula and the feature map change shape.
  5. 5
    Press Finish to complete the scan, then compare the ReLU output with the 2×2 max-pooled result.
  6. 6
    Scroll to the layer-stack diagram to see how these operations shape a full (small) CNN.

Key concepts

Kernel (filter)

A small grid of learned weights. The same kernel is reused at every position, so a CNN has far fewer weights than a fully connected layer on the same image.

Feature map

The grid of kernel responses. A high value means the patch under the kernel looks like the pattern the kernel encodes.

Stride and padding

Stride is how far the kernel jumps between positions. Padding adds a border of zeros so edges get covered and the output can stay the same size.

Pooling

Max pooling keeps the strongest response in each 2×2 block. It halves the width and height and makes the network less sensitive to small shifts.

Channels

Each filter in a layer produces its own feature map. The next layer’s kernels span all of those maps, so they combine edges into corners, textures and shapes.

Receptive field

Every conv and pool layer widens the patch of the original image that one deep unit can see, which is how depth builds up from edges to objects.

Code

NumPy
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

A 32×32 image goes through a 5×5 convolution with padding 2. What is the output size with stride 1? With stride 2?
Show 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

A 64×64 RGB image (3 channels) passes through a conv layer with 16 filters of size 3×3, padding 1, stride 1, followed by 2×2 max pooling. What is the output shape after each step, and how many parameters does the conv layer have?
Show 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.