Neural Mastery
← Back to Practice

2D Convolution From Scratch

Difficulty: Medium · Concept: Vision Fundamentals — Convolution as Classical Filtering

Slide a small kernel across an image, and at every position, compute the weighted sum of the pixels it currently covers. That's the entire mechanical operation — the same one a hand-designed Sobel edge filter runs, and the same one every CNN's convolutional layer runs, except a CNN learns the kernel values from data instead of a human choosing them.

Your task: implement convolve2d(image, kernel) — "valid" convolution only (no padding), stride 1. image and kernel are lists of lists (rows) of numbers; assume the kernel is no larger than the image in either dimension. Output size: for an (H×W)(H \times W) image and (kh×kw)(k_h \times k_w) kernel, the output is (Hkh+1)×(Wkw+1)(H - k_h + 1) \times (W - k_w + 1).

Implement it yourself
assert convolve2d([[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[1, 0], [0, 1]]) == [[6, 8], [12, 14]] assert convolve2d([[1, 1, 1], [1, 1, 1], [1, 1, 1]], [[1, 1], [1, 1]]) == [[4, 4], [4, 4]] assert convolve2d([[1, 2], [3, 4]], [[1]]) == [[1, 2], [3, 4]] assert convolve2d([[0, 0, 0], [0, 5, 0], [0, 0, 0]], [[1, 0, 0], [0, 1, 0], [0, 0, 1]]) == [[5]]

Next: Discounted Return From Scratch

Last updated Sep 5, 2026Edit this pageReport an issue