DL0072 Inception Module

What is the Inception module, and how does it use parallel convolutions of different sizes?

Answer

The Inception module is the building block of GoogLeNet: instead of committing a layer to one kernel size, it runs several convolutional branches in parallel over the same input (1×1, 3×3, 5×5, plus a 3×3 max-pool path) and concatenates their outputs along the channel axis. Every branch uses stride 1 with padding chosen so all branches emit the same spatial size, which is what makes the concatenation legal. The naive form is prohibitively expensive because the 5×5 branch convolves over the full input depth, so the practical module inserts 1×1 convolutions as channel bottlenecks before the 3×3 and 5×5 convolutions and after the pooling path. The next layer therefore sees features at several receptive-field sizes at once, and the learned weights decide how much of each scale to use rather than the architect fixing one kernel per layer.

(1) Parallel Multi-Scale Branches: the 1×1, 3×3, 5×5, and pooling paths all read the identical input tensor, so one module covers several receptive fields; a face at 20 px and one at 60 px are both matched inside the same layer.
(2) Channel-Wise Concatenation: branches keep H and W identical (stride 1, pad 1 for 3×3, pad 2 for 5×5), and outputs are stacked on the channel dimension, so module output depth is the sum of branch depths, not their average.
(3) 1×1 Bottlenecks: convolution cost is linear in C_{in} C_{out} k^2, so projecting 192 channels down to 16 before the 5×5 conv cuts that branch roughly 10x with a small accuracy cost.
(4) Dense Ops, Sparse Intent: the design approximates a sparse, locally-optimal connectivity structure using dense operations that BLAS and cuDNN execute efficiently, which is why GoogLeNet reached top ILSVRC-2014 accuracy at about 5M parameters, roughly 12x fewer than AlexNet.

Two side-by-side block diagrams of an Inception module: on the left the naive version sends the 28x28x192 input straight into 1x1, 3x3, 5x5 convolutions and a 3x3 max pool before filter concatenation; on the right the dimension-reduced version inserts 1x1 convolutions with 96 and 16 channels before the 3x3 and 5x5 convolutions and a 32-channel 1x1 projection after the pool

Figure 1: Naive versus dimension-reduced Inception module. The 1×1 convolutions shrink channel depth before the expensive kernels and project the pooled path, so concatenation does not grow depth without bound.

The pooling branch is the reason the naive module is unstable when stacked: max pooling preserves its input depth, so every module would add at least the full input depth back into the concatenated output and channel count would grow monotonically with depth. The 1×1 projection after the pool fixes this, and the same trick applied before the 3×3 and 5×5 convolutions is where nearly all the savings come from. Take the classic Inception (3a) block with a 28 \times 28 \times 192 input and a 5×5 branch producing 32 maps.

Mathematical Formulation:
y = \mathrm{concat}(y_1, y_3, y_5, y_p)
C = H_o W_o C_{out} k^2 C_{in}
C_{naive} = 28^2 \cdot 32 \cdot 5^2 \cdot 192 \approx 120 \times 10^6
C_{reduce} = 28^2 \cdot 16 \cdot 1^2 \cdot 192 \approx 2.4 \times 10^6
C_{conv} = 28^2 \cdot 32 \cdot 5^2 \cdot 16 \approx 10.0 \times 10^6

Where:

  • y_1, y_3, y_5, y_p are the outputs of the 1×1, 3×3, 5×5, and pooling branches, and \mathrm{concat} stacks them on the channel axis, which requires all four to share the same H_o \times W_o.
  • C counts multiply-adds for one convolution, with H_o W_o the output spatial size, C_{in} and C_{out} the input and output channels, and k the kernel width.
  • C_{naive} is the 5×5 branch applied to all 192 input channels; C_{reduce} is the 1×1 projection to 16 channels and C_{conv} the 5×5 conv on those 16, summing to about 12.4 \times 10^6, roughly a tenth of the naive branch.
Grouped bar chart of multiply-adds in millions per Inception 3a branch, naive versus dimension-reduced: 1x1 branch 9.6 and 9.6, 3x3 branch 173.4 and 101.2, 5x5 branch 120.4 and 12.4, pool branch 0 and 4.8, module total 303.5 and 128.0

Figure 2: Multiply-adds per branch for Inception (3a) on a 28 \times 28 \times 192 input. The bottlenecks cut the 5×5 branch from about 120M to 12M and the module total from about 304M to 128M, while also shrinking output depth from 416 to 256 channels.

Branch1×1 ReductionMain OperationOutput ChannelsMultiply-Adds
Point-wisenone needed1×1 conv, 64 filters649.6M
Medium scale192 to 963×3 conv, 128 filters, pad 1128101.2M
Large scale192 to 165×5 conv, 32 filters, pad 23212.4M
Pooling192 to 32, after the pool3×3 max pool, stride 1, pad 1324.8M
Concatenatedchannel-axis concat, 28×28 preserved256128M

Login to view more content


Log in to track your progress

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *