DIP+CV · Programming Exercise

EP09_03 — 🟡 Counting Trainable Parameters of a CNN

9.10.3 EP09_03 🟡 Counting Trainable Parameters of a CNN

This EP formalizes the counting of trainable parameters of a CNN. Given the textual description of a small architecture, composed of convolutional, pooling, and fully connected layers, determine, for each layer, the number of trainable parameters and the network total.

The architecture must be interpreted sequentially: the output of a convolutional layer becomes the input of the next compatible layer. Thus, the number of channels produced by a CONV layer determines the number of input channels (cin) of the following convolutional layer.

In a convolutional layer, it is important to distinguish input channels and output channels:

  • \(c_{in}\) (channels in) is the number of channels entering the layer. A grayscale image has \(c_{in}=1\), while an RGB image has \(c_{in}=3\). In an intermediate convolutional layer, cin is typically equal to the number of channels produced by the preceding CONV layer.
  • \(c_{out}\) (channels out) is the number of channels produced by the layer. It equals the number of filters used. Therefore, if a layer has 16 filters, it produces \(c_{out}=16\) channels.

For example, consider the sequence:

CONV 3 3 1 8 1
POOL
CONV 3 3 8 16 1
POOL
FC 784 10 1

The first convolution receives an image with one channel and produces 8 channels. After pooling, the second convolution receives those 8 channels and produces 16 channels. The POOL layer does not alter the number of channels; it may only reduce the spatial dimensions. The FC layer receives the number of inputs specified in its own description.

Each convolutional filter has dimensions

\[ k_h \times k_w \times c_{in}. \]

Thus, a layer with \(c_{out}\) filters has

\[ k_h \cdot k_w \cdot c_{in} \cdot c_{out} \]

weights. If there is a bias, one parameter is added for each filter, totaling an additional \(c_{out}\) parameters.

The central point of this exercise is to observe that the number of parameters in a convolutional layer does not depend on the spatial dimensions (\(H \times W\)) of the feature map. This occurs due to weight sharing: the same filter is reused at different positions of the input.

9.10.3.1 📋 Implementation Guidelines

  1. Input: Read the integer \(L\) (number of layers in the architecture, in the order they are applied).

  2. Layers: Read \(L\) lines, each describing a layer in one of three formats:

    • CONV kh kw cin cout bias — convolutional layer with kernel \(k_h \times k_w\), \(c_{in}\) input channels, \(c_{out}\) output channels, and bias (0 or 1), indicating whether there is a bias per filter;
    • POOL — pooling layer (max or average), which has no trainable parameters and preserves the number of channels;
    • FC in out bias — fully connected layer with in inputs, out outputs, and bias (0 or 1), indicating whether there is a bias per neuron.
  3. Consistency between CONV layers: in a sequence of convolutional layers, the cin of a layer must correspond to the cout of the preceding convolutional layer. A POOL layer does not alter this number of channels.

    For example:

    CONV 3 3 1 8 1
    POOL
    CONV 3 3 8 16 1

    The first CONV produces 8 channels, which are received by the second CONV. Therefore, in the second layer, cin=8 and cout=16.

  4. Parameters of a CONV layer:

    Each of the \(c_{out}\) filters has \(k_h \cdot k_w \cdot c_{in}\) weights. Therefore,

    \[ P_{\mathrm{CONV}} = k_h \cdot k_w \cdot c_{in} \cdot c_{out} + c_{out}\cdot\text{bias}. \]

  5. Parameters of an FC layer:

    \[ P_{\mathrm{FC}} = \text{in}\cdot\text{out} + \text{out}\cdot\text{bias}. \]

  6. Parameters of a POOL layer: always \(0\).

  7. Network total: sum the trainable parameters of all layers.

  8. Output: For each layer, in reading order, print Camada i: P, where \(i\) starts at \(1\) and \(P\) is the number of parameters for that layer. At the end, print Total: T.

9.10.3.2 📐 Example to understand cin and cout

Consider the sequence:

CONV 3 3 1 8 1
POOL
CONV 3 3 8 16 1

In the first layer:

  • cin=1: one channel enters;
  • cout=8: there are 8 filters and, therefore, 8 channels exit.

Each filter has

\[ 3\cdot3\cdot1=9 \]

weights. Since there are 8 filters:

\[ 9\cdot8=72 \]

weights. With one bias per filter:

\[ 72+8=80. \]

In the second layer:

  • cin=8: the 8 channels produced by the first CONV enter;
  • cout=16: there are 16 filters and, therefore, 16 channels exit.

Each filter has

\[ 3\cdot3\cdot8=72 \]

weights. Since there are 16 filters:

\[ 72\cdot16=1152 \]

weights. With 16 biases:

\[ 1152+16=1168. \]

Thus, the two layers have, respectively, 80 and 1168 trainable parameters.

Note that cout is not \(cin\) multiplied by the number of filters. The number of filters is exactly cout: each filter combines all input channels and produces a single output channel.

9.10.3.3 📌 Computational Constraints

  • Independence from spatial dimension: the input does not provide \(H \times W\). The count for a CONV layer depends only on kh, kw, cin, and cout.
  • Channel consistency: for two consecutive CONV layers, the cin of the second must equal the cout of the first. A POOL layer preserves the number of channels.
  • bias always 0 or 1: multiply the bias term directly by this value.
  • POOL layers with no additional arguments: the line contains only the word POOL.
  • FC layers: the number of inputs in is provided explicitly. It is not necessary to compute the spatial dimensions produced by previous layers.
  • All numerical input values are non-negative integers.

9.10.3.4 🧠 Theoretical Foundation

Element Role in parameter counting
\(c_{in}\) Number of channels received by the layer
\(c_{out}\) Number of filters and, therefore, of channels produced by the layer
Convolutional filter Each filter has \(k_h \cdot k_w \cdot c_{in}\) weights and produces one output channel
Weight sharing The same filter is reused at different input positions, making the count independent of \(H \times W\)
Bias A single additional parameter per filter (CONV) or per neuron (FC)
Pooling May alter \(H \times W\), but has no trainable parameters and preserves the number of channels
FC layer Has one weight for each combination of input and output neuron

9.10.3.5 🧩 morph.py methods that may help

This exercise is purely arithmetic and does not directly use functions from morph.py. The count can, however, be checked in a real architecture implemented in PyTorch using:

sum(p.numel() for p in modelo.parameters())

This expression counts the model parameters, including weights and biases.

9.10.3.6 📦 Input and Output Specification (VPL)

Input:

  • Line 1: Integer \(L\).
  • Next \(L\) lines: description of each layer, in the format CONV kh kw cin cout bias, POOL, or FC in out bias.

Output:

  • \(L\) lines in the format Camada i: P.
  • Last line: Total: T.

9.10.3.7 📌 Examples

Input Output Observation
3
CONV 3 3 1 8 1
POOL
FC 1352 10 1
Camada 1: 80
Camada 2: 0
Camada 3: 13530
Total: 13610
Simple network with one convolution, pooling, and classification layer.
5
CONV 3 3 1 8 1
POOL
CONV 3 3 8 16 1
POOL
FC 400 10 1
Camada 1: 80
Camada 2: 0
Camada 3: 1168
Camada 4: 0
Camada 5: 4010
Total: 5258
Small CNN with two convolutions, two poolings, and one fully connected layer.
6
CONV 3 3 1 8 1
POOL
CONV 3 3 8 16 1
POOL
FC 256 32 1
FC 32 10 1
Camada 1: 80
Camada 2: 0
Camada 3: 1168
Camada 4: 0
Camada 5: 8224
Camada 6: 330
Total: 9802
Small CNN with two convolutions, intermediate pooling, and two fully connected layers for classification.
🎮 Simulator: Parameter Counting 🟡 weight sharing
CONV Blue block POOL Green cylinder FC Orange diamond BATCH Red stack 🖱️ Drag to move layers
32×32
1
4
3
🧠 3D Visualization
🖱️ Drag layers | Scroll zoom | P to pause
Figure 9.45: Simulator EP09_03: Parameter Counting — Convolution vs. Fully Connected Layer
%%writefile EP09_03.py
# Python code
Overwriting EP09_03.py
TestSuite("EP09_03.py").run()
✔️ EP09_03.cases already exists in casos/
📋 3 case(s) loaded from casos/EP09_03.cases

🔍 Testing Python: EP09_03.py
⚠️ EP09_03.py: Empty file (fewer than 3 lines). Tests skipped.