Exercises — DenseNet and EfficientNet
This is a self-testing page for DenseNet and EfficientNet. Each problem hides its full solution inside a collapsible [!recall]- box. Try first, then reveal.
Before we start, one promise: every symbol below was earned in the parent note. As a quick warm-up, here is the vocabulary you need, each anchored to a picture.

Look at the figure: each layer is a horizontal tray. A new tray always stacks on top of every tray below it (concatenation), never blends into it (that would be addition — the ResNet idea). The pile only grows.
Level 1 — Recognition
Exercise 1.1
State, in one sentence each, the difference between how DenseNet and ResNet combine a layer's output with earlier information. Write the two governing equations.
Recall Solution
DenseNet concatenates; ResNet adds. Concatenation stacks feature maps side-by-side along the channel axis, so every earlier feature survives untouched. Addition merges them into one tensor of the same channel count, so individual identities are lost but memory stays flat. See 3.4.7-ResNet-and-Skip-Connections.
Exercise 1.2
In compound scaling, name the three dimensions being scaled and give the symbol used for each scaling base.
Recall Solution
- Depth (number of layers): base
- Width (channels per layer): base
- Resolution (input image side length): base
All three are raised to the same compound coefficient : .
Level 2 — Application
Exercise 2.1
A dense block has input channels, growth rate , and layers. How many channels does it output? What are the input channel counts seen by layers 1 through 5?
Recall Solution
What we do: apply the running rule "layer receives , outputs new." Why: each layer's output is stacked onto the pile, so the pile grows by exactly each step.
| Layer | Input channels | Running total after |
|---|---|---|
| 1 | ||
| 2 | ||
| 3 | ||
| 4 | ||
| 5 |
Output channels .
Exercise 2.2
The block from 2.1 outputs channels and is followed by a transition layer with compression . How many channels leave the transition?
Recall Solution
The floor matters only when is not an integer; here it is exact. Transition also halves spatial size via average pooling.
Exercise 2.3
EfficientNet-B0 uses . Verify the constraint numerically.
Recall Solution
This is close to — the small shortfall is why the paper writes "". Each unit of therefore roughly (not exactly) doubles FLOPs.
Level 3 — Analysis
Exercise 3.1
For a bottleneck layer with input channels, growth , compare parameter counts with and without the bottleneck. Find the value of (in terms of ) above which the bottleneck saves parameters.
Recall Solution
With bottleneck ( to , then to ): Without bottleneck (direct from to ): Bottleneck saves parameters when Interpretation: early in a block is small, so the bottleneck's fixed cost dominates and it does not help. Late in a block has grown well past , so and the bottleneck wins. That is exactly where channel counts explode — precisely where you want savings.
Exercise 3.2
EfficientNet-B7 uses . Compute depth, width, and resolution multipliers, and the B7 input resolution given B0 uses px.
Recall Solution
Resolution: px — the paper rounds the architecture to a network-friendly px in practice, but the scaling law predicts . (Depth and width multiplier magnitudes match the parent note's and .)
Exercise 3.3
Show that if you scaled depth alone to double FLOPs, you would multiply by , but under compound scaling with the constraint, doubling FLOPs multiplies by only . Why is spreading the budget usually better for accuracy?
Recall Solution
Depth-only: FLOPs , so needs . Compound: FLOPs . One extra unit of doubles FLOPs while multiplying depth by only , width by , resolution by . Why spreading wins: each single dimension has diminishing returns — a very deep but narrow, low-resolution net saturates. Balancing keeps all three below their saturation points, so the same FLOP budget buys more accuracy. This is the empirical finding behind EfficientNet; see 3.4.11-Neural-Architecture-Search for how were discovered.
Level 4 — Synthesis
Exercise 4.1
Design a mini-DenseNet stage. Requirements: input , two dense blocks each with , , a transition with between them, and a final transition with . Report the channel count after every stage.
Recall Solution
Block 1 output: . Transition 1: . Block 2 output: . Transition 2: .
Sequence: channels. Notice the transition resets the "pile" so the next block starts from a controlled base — this is what keeps DenseNet's channel growth from exploding, unlike a single giant block.
Exercise 4.2
You have a FLOPs budget that lets you increase from to . Using B0's , by what factor does total FLOPs increase, and what is the new resolution from a px base?
Recall Solution
FLOPs factor . Resolution px. So the compute buys a jump to px input alongside proportional depth () and width () growth.
Level 5 — Mastery
Exercise 5.1
A researcher claims: "Replace DenseNet's concatenation with ResNet-style addition; feature reuse will be identical and we save memory." Critique this rigorously, referencing what concatenation preserves that addition destroys, and what MobileNet-style tricks (3.4.9-MobileNet-and-Depthwise-Separable-Convolutions) could recover the memory instead.
Recall Solution
The claim is false on feature reuse.
- Addition requires all summands to share the same channel count and merges them: . A downstream layer sees one blended tensor and cannot recover or separately. Information is superimposed, not preserved.
- Concatenation keeps and as distinct slices: any later layer's conv can weight them independently. This is true feature reuse — the raw low-level maps from layer 0 remain literally addressable at layer 100.
So memory is the genuine cost of concatenation (channel pile grows as ). The correct fixes are the ones DenseNet already ships and that MobileNet inspires:
- Bottleneck convs cap the expensive input at (Ex 3.1).
- Transition compression halves the pile between blocks (Ex 2.2).
- Depthwise-separable convs (MobileNet) cut the cost per channel, orthogonal to the concat memory. None of these sacrifice the concatenation semantics, so they save resources without destroying reuse — unlike swapping to addition.
Exercise 5.2
Combine both architectures conceptually: EfficientNet scales an MBConv baseline. If you instead wanted a "compound-scaled DenseNet," which single hyperparameter most directly plays the role of width , and why must you be careful scaling it?
Recall Solution
The growth rate is DenseNet's width knob: it sets how many channels each layer emits, exactly the role scales in EfficientNet. The catch: in a plain CNN, scaling width multiplies FLOPs by and channel count grows linearly with depth. In DenseNet, the input to layer is , so channel count grows linearly in and in depth simultaneously — the two scaling axes are coupled. Doubling in a deep block inflates every subsequent layer's input, so FLOPs grow faster than the naive prediction. A compound-scaled DenseNet must therefore re-tighten the constraint empirically (a job for 3.4.11-Neural-Architecture-Search), and lean harder on compression and bottlenecks to stay in budget.
Recall Self-test cloze
DenseNet layer receives channels ::: and outputs new ones by concatenation. Bottleneck saves parameters once exceeds ::: . Compound scaling constraint ::: . Growth rate is DenseNet's analogue of EfficientNet's ::: width .
Related: 3.4.8-Inception-and-GoogLeNet, 3.4.3-Batch-Normalization-and-Regularization, 4.2.5-Model-Compression-and-Pruning.