3.4.10 · D2Convolutional Neural Networks

Visual walkthrough — DenseNet and EfficientNet

3,453 words16 min readBack to topic

This page rebuilds one result from the parent note, DenseNet and EfficientNet, from absolute zero: the EfficientNet rule

The parent note stated this. Here we earn it — every symbol, every square, every "2" — with a picture per step. If you have not yet met the ideas of layers, channels, and image size, we build them from scratch below. Related reading: 3.4.9-MobileNet-and-Depthwise-Separable-Convolutions and 3.4.11-Neural-Architecture-Search.


Step 1 — What is a convolutional layer counting?

WHAT. A CNN has three independent sizes:

  • Depth — how many layers are stacked (a taller tower).
  • Width — how many channels each layer holds (a fatter tower).
  • Resolution — how many pixels tall and wide the image is (a bigger picture).

WHY. Historically people pulled one arrow at a time — "let's just add layers", or "just add channels". EfficientNet's whole point is that these are three different arrows, so we must first name each one cleanly and separately before we can talk about pulling them together.

PICTURE. Figure s01 — a single network drawn as a point, with three coloured arrows leaving it: a lavender arrow going up labelled "Depth (more layers)", a coral arrow going right labelled "Width (more channels)", and a mint arrow going up-right labelled "Resolution (bigger image)". The figure's job is to establish that these are three separate, independent directions of growth before any algebra appears.

Figure — DenseNet and EfficientNet

Each of is just a plain positive number. Nothing hidden yet.


Step 2 — Counting the work of ONE layer

WHAT. Take a single convolution. A filter of size slides over an grid (using the scaled resolution ). At each of the positions it touches:

  • input channels,
  • to produce output channels,
  • doing multiply-adds per channel-pair.

So the multiply-adds for one layer are

WHY these factors, term by term.

  • — the filter must stop at every pixel of an image, and there are pixels. Two spatial directions ⇒ the square.
  • — every one of the output channels is built by looking at all input channels. Two channel counts multiplied ⇒ . (This "dense" all-to-all channel mixing is exactly what depthwise-separable convolutions in real EfficientNet avoid — another place the toy model is simpler than reality.)
  • — the fixed filter size (say ); by the assumption above it is the same constant in every layer, so we factor it into the proportionality constant and ignore it from here.

PICTURE. Figure s02 — the three counted things laid side by side: on the left a mint grid labelled " positions"; in the middle a coral column of input channels feeding through an " filter" arrow into a lavender column of output channels; a caption "each out reads each in ⇒ ". The figure makes visible why resolution and width each contribute a square.

Figure — DenseNet and EfficientNet

Step 3 — Counting the whole network

WHAT. In the toy model a network of depth is just identical layers stacked. Total work is the per-layer work times the number of layers:

WHY. Depth enters linearly (one copy of the work per layer), while width and resolution each enter squared. This asymmetry — one linear, two squared — is the whole reason the final rule has a and a but only . Keep your eye on it.

PICTURE. Figure s03 — a vertical stack of five identical butter-coloured bricks, each labelled "layer: ", with a lavender arrow up the side labelled "depth copies" and a coral caption "total FLOPs ~ ". The figure shows depth as repetition (linear) versus the squared per-brick cost.

Figure — DenseNet and EfficientNet

Step 4 — Scaling each knob by its own factor

WHAT. Introduce three growth factors, all , that stretch the baseline sizes:

  • multiplies depth: ,
  • multiplies width: ,
  • multiplies resolution: .

Substitute into the total-work formula from Step 3:

Now expand each squared bracket, term by term:

So

WHY. Look what happened: the baseline work factored straight back out, leaving a single tidy multiplier . The squares on and come directly from the two squared factors in Step 2 — width and resolution each cost a square because each spans two directions.

PICTURE. Figure s04 — the three growth factors as small boxes ("" lavender, "" coral, "" mint) with arrows converging into one butter box labelled "multiplier " and a note "(width & res squared)". The figure shows all scaling collapsing into one factor.

Figure — DenseNet and EfficientNet

Step 5 — The compound coefficient : one dial for all three

WHAT. Define the depth, width and resolution growth as powers of , always relative to the baseline:

Here is the compound coefficient. It is a real number , not restricted to whole numbers — fractional values like are perfectly meaningful (they give a network between two named models). In practice EfficientNet publishes models at the integer steps (named B0…B7) purely for convenience; the maths itself is continuous. Turning up grows all three sizes at once. gives : no growth, so — the untouched baseline.

Plug these into the multiplier from Step 4. Using the exponent rule :

WHY, term by term.

  • — power of a power multiplies exponents.
  • Factoring the common exponent out gives : the same base from Step 4, now raised to the dial .

So the total work grows as

PICTURE. Figure s05 — a dial (labelled "phi ≥ 0 (real)") on the left whose output fans out to the three factor boxes "", "", "", which then feed a single box "". The figure shows one dial simultaneously driving all three scalings.

Figure — DenseNet and EfficientNet

Step 6 — Why the base is chosen to be 2

WHAT. We want: increasing by multiplies FLOPs by . From Step 5, going from to multiplies FLOPs by

Set that target equal to the desired factor :

WHY. This is not a law of nature — it is a design choice. Fixing the target base to turns into a "compute-doubling counter": FLOPs of the baseline, , , and so on. The constraint guarantees we only ever grow, never shrink.

PICTURE. Figure s06 — a bar chart of FLOPs (in multiples of the baseline) against , each bar exactly double the previous (), with a caption "ratio between steps = ". The figure makes the doubling-per-step meaning of the target concrete.

Figure — DenseNet and EfficientNet

Step 7 — Checking the real EfficientNet numbers

WHAT. Neural Architecture Search found, for EfficientNet-B0:

Test the target, term by term:

The here is exactly the point of Step 6's box: the target is , the realized value is .

Now drive the dial. For B7, :

The raw formula on the baseline resolution gives px.

WHY. Notice depth (base ) grows fastest, width (base ) slowest — but because width and resolution are squared in the cost, small still contribute plenty to the budget. That is the balance the squared exponents from Step 2 buy us.

PICTURE. Figure s07 — three curves of growth factor versus : lavender "" (depth, steepest), coral "" (width, flattest), mint "" (resolution, middle), with dotted verticals marking B0 (), B1 () and B7 (). The figure shows each knob growing exponentially at its own rate.

Figure — DenseNet and EfficientNet

Step 8 — The degenerate case

WHAT. Set the dial to zero:

Every growth factor becomes , so nothing scales — this is exactly EfficientNet-B0, the baseline.

WHY. A good scaling law must contain "do nothing" as a special case. giving multiplier (any positive number to the power is ) confirms the formula degrades gracefully: zero dial ⇒ FLOPs ⇒ the original network untouched.

PICTURE. Figure s08 — the same dial as s05 but pointed straight up at "phi = 0", feeding three boxes each reading "", "", "", with a caption " → nothing scales". The figure confirms the law contains the do-nothing case.

Figure — DenseNet and EfficientNet

The one-picture summary

PICTURE. Figure s09 — a left-to-right flow that compresses the whole page: "3 knobs " → "layer cost " → "net cost " → "scaled × " → "one dial: " → "double per step ⇒ ". Reading the chain top-to-bottom replays every step in one glance.

Figure — DenseNet and EfficientNet

The whole derivation on one canvas: three knobs → per-layer cost → network cost → scaled by → tied to one dial as → doubling wish targets the base .

Recall Feynman retelling — say it back in plain words

A CNN has three ways to get bigger: taller (more layers, ), fatter (more channels, ), and higher-detail (bigger image, ). We use a toy picture: one long stack of identical layers — real EfficientNet has varied stages, down-sampling and residuals, but they all scale the same way, so the toy gives the right exponents. One layer's work is "how many pixels" times "channels in" times "channels out" — pixels are two-dimensional so that's , and channels-in times channels-out is ; the filter size is the same constant in every layer, so it factors out and we drop it. Stack layers and the total work is . Now grow each baseline size by its own factor ; the extra work is exactly the multiplier — width and resolution get squared because they each stretch in two directions, depth doesn't. Tie all three factors to one dial (any real ) by raising them to , and the multiplier becomes . Finally we decide that each click of the dial should double the compute; that decision targets exactly, though the searched constants only reach (hence ). Resolutions from the formula get rounded to clean, stride-friendly whole numbers — that's why B7 ships at px, not the raw . Dial at zero ⇒ the plain baseline network.

Recall

Why is width squared in the FLOP formula but depth is not? ::: Width sets both the number of input channels and the number of output channels, and each output channel reads every input channel — two counts multiplied ⇒ . Depth just stacks copies of a layer, so it enters linearly. What single design wish forces the target ? ::: The wish that increasing the compound coefficient by 1 should exactly double the network's FLOPs. Is the constraint an exact equality or an approximation? ::: The target is exact (); the searched values only approximate it (product ), so we write when substituting real numbers. What network do you get when ? ::: The unscaled baseline (EfficientNet-B0), because every growth factor raised to the power 0 equals 1. Is restricted to whole numbers? ::: No — is any real number ; the integer values 0…7 (B0…B7) are just the officially published models. Fractional is perfectly valid and lands between named models. What does stand for and why does it drop out? ::: is the filter's side-length (e.g. for a window); held constant across all layers, its is the same factor everywhere and cancels from every ratio. Why is the derivation a "toy" model? ::: It treats the net as a stack of identical layers with one shared and ; real EfficientNet has multiple stages, down-sampling, expansion factors and residuals — but they all scale the same way, so the toy gives the correct scaling exponents. Why doesn't the raw formula give the published resolution (e.g. 517 vs 600 px)? ::: A pixel grid needs an integer side that is also divisible by powers of two (for the stride-2 down-sampling); the raw is rounded to the nearest clean, stride-friendly whole number.