Feature Maps in CNNs
Each filter draws one map of where its pattern fired. Stack the maps and you hold the image as the network sees it, channels first.
Why Does This Exist?
Raw pixels mix everything: light, object and background share the same numbers. A classifier reading pixels directly must untangle all of it at once, which is why dense layers on images explode in weights and still miss shifted patterns.
Convolutional layers split the job. Each filter hunts one pattern and records where it fired as a 2D sheet. Stack those sheets and later layers read pattern locations instead of pixels. This page names that stack and its shape. How the stack shrinks lives in padding and stride, and what the whole network does with it lives in feature extraction.
You need one idea first. A channel is a detector. Bright cells mean the pattern fired there.
Think of It Like This
Transparent overlays on a city map
You lay one clear sheet per question over a city map: one marks parks, one marks schools, one marks bus stops. Each sheet is sparse but honest. Stacked, they answer where a family should live.
Filters are those questions, maps are the marked sheets, and the stack is the pile you hand to the next analyst. Where the analogy stops: map sheets are drawn by people, while feature maps are learned numbers that shift during training.
How It Actually Works
One filter, one map
Filter with weights slides over input and writes map with one number per placement. With filters the output stacks to . Early maps fire on edges and blobs, middle maps on textures and parts, deep maps on object level patterns.
A worked tensor shape
Input , two filters , stride , no padding. Each map is:
So each map is numbers, and the stack is numbers. A real early block with filters on gives numbers, which is why memory, not weights, often caps batch size.
Reading maps honestly
Bright means strong match, not probability. Maps are unnormalized activations that later layers rescale. Dead maps that stay near zero signal dead filters, often from too high a learning rate, and pruning them rarely hurts.
Code
import numpy as np
def feature_stack(h_in: int, w_in: int, c_out: int, k: int) -> tuple: """Map shape and total numbers for square input, square kernel, stride 1.""" h_out = h_in - k + 1 # valid padding arithmetic return (c_out, h_out, h_out), c_out * h_out * h_out
print(feature_stack(5, 5, 2, 3)) # -> ((2, 3, 3), 18)Watch Out For
Reading raw maps as heatmap proof
A bright patch shows filter match, not object proof. It shifts with normalization and means little alone. The symptom is screenshots presented as explanations that change under a re seed. Pair maps with ablations before claiming one region caused the decision.
Adding channels past memory
Doubling channels quadruples the next cost and doubles activation memory. The symptom is out of memory at larger batches while accuracy barely moves. Widen in steps and watch validation per million activations, not per channel.
The Quick Version
- Each filter writes one 2D map of where its pattern fired.
- Stacking maps gives a channels by height by width tensor the next layer reads.
- Two 3 by 3 filters on a 5 by 5 input give a 2 by 3 by 3 stack of 18 numbers.
- Bright means match strength, not probability, and dead maps signal dead filters.