Majid Al-RaimiParameters and model size

COE 592Lecture 03Part 02

Parameters and model size

Counting weights for linear, convolution, grouped and depthwise layers, totaling AlexNet to 61M parameters, and converting parameter count into storage at different bit widths.

Concepts
4
Slides
10-17
Reading
24 min
Understood
0/4 concepts

Why this part matters

Every result you will meet later in this course, from pruning AlexNet "9x smaller" to Deep Compression's "35x" storage cut, is a ratio of two numbers computed the way this part teaches. Before you can judge pruning, quantization or an architecture search, you must be able to count what a network stores, and the same count decides whether a model fits into a microcontroller's flash.

Lecture 02 taught how linear, convolution, grouped and depthwise layers compute their outputs. This part does not repeat that. It asks one narrower question of each layer: how many numbers does it keep? Four short formulas answer it, AlexNet gives them a real workout, and one multiplication by the bit width turns the answer into megabytes. Along the way you will find a typo on the slide, a hidden value to compute yourself, and a simulator you can use to check every parameter and model-size number here and the MAC and FLOP numbers in part 04.

By the end you can

  1. Define #Parameters as the element count of all weight tensors and explain why n, h and w never enter it.
  2. Write and derive the four counting formulas (linear, convolution, grouped, depthwise) and justify the single division by g.
  3. Total AlexNet layer by layer, identify where 96 percent of the weights sit, and spot the slide's conv1 typo.
  4. Convert a parameter count to model size at any bit width in bits, KB and MB, stating the decimal convention.
  5. Predict how architecture choices (groups, depthwise filters, linear layer width) move model size before touching hardware.

Start with the smallest network worth drawing: five inputs x0 to x4 and three outputs y0 to y2, every input wired to every output. Count the arrows. Each input sends one arrow to each output, so there are 3 × 5 = 15 arrows, labelled from w00 up to w42. Each arrow carries exactly one learned number, its weight. That is the whole idea of the number of parameters: it is the synapse count, the number of weights, and for this layer it is 15.

Five inputs fully wired to three outputs: 15 arrows, 15 weights, c_o · c_i

Now look at the same layer the way a framework stores it. The inputs for a batch are a matrix X of shape n × c_i, the weights are a matrix W of shape c_o × c_i, and the outputs come out as Y = X · W^T of shape n × c_o. The fifteen arrows have become the fifteen elements of W. This is the second, equivalent definition the slides give: #Parameters is the number of elements in the network's weight tensors. For one linear layer that is the product of its two dimensions.

#Paramslinear=coci\#\text{Params}_{\text{linear}} = c_o \cdot c_i
One weight per input and output pair, bias ignored

One thing in that matrix picture deserves a second look. The batch size n appears in X and in Y, but never in W. Feed the layer one image or a thousand and the weight matrix is the same c_o × c_i block. Parameter count is a property of the model, not of the data flowing through it. Hold on to this observation: it returns in the next concept for spatial size, and it is the reason parameters and MACs behave so differently in part 04.

The slides define the count for the "given" (slide 10) or "entire" (slide 11) neural network; both mean the same thing, the sum over every layer. They also say bias is ignored, and this lecture keeps that convention throughout. In PyTorch a linear layer stores a bias vector of length c_o and a convolution stores one bias per output channel, so the true count is larger by c_o per layer (PyTorch Conv2d documentation). Next to c_o · c_i that is a rounding error, which is why the lecture drops it.

Notation used on slides 11 to 14 and in the rest of this lecture

n
Batch size, the number of inputs processed together
c_i, c_o
Input and output channels (for a linear layer, input and output features)
h_i, h_o
Input and output height
w_i, w_o
Input and output width
k_h, k_w
Kernel height and width
g
Number of groups in a grouped convolution

Layer mechanics live in lecture 02

How a linear layer, a convolution, padding and stride, grouped and depthwise convolution and pooling produce their outputs, including the output-shape arithmetic behind numbers like 96 × 55 × 55, was covered in lecture 02: neurons and linear layers, convolution layers, padding, stride and grouped convolution and pooling.

Recall

A linear layer maps 512 inputs to 256 outputs. How many parameters does it have, ignoring bias, and does the batch size change that number?

256 × 512 = 131,072. The batch size changes nothing: n never appears in a weight tensor.

Take AlexNet's third convolution: 384 filters, each looking at 256 input channels through a 3 × 3 window. One filter is a small brick of numbers, 256 deep and 3 × 3 across, so it holds 256 · 9 = 2,304 weights. There are 384 such bricks, so the layer holds 384 · 2,304 = 884,736 weights. That is the whole convolution formula for the #Parameters, read off the shape of the weight tensor.

#Paramsconv=cocikhkw\#\text{Params}_{\text{conv}} = c_o \cdot c_i \cdot k_h \cdot k_w
c_o filters, each c_i × k_h × k_w

Notice what is missing. The input is 256 × 13 × 13 and the output is 384 × 13 × 13, yet 13 appears nowhere in the count. A convolution slides the same brick to every output position, so the weights are shared across space. Goodfellow, Bengio and Courville make the point with an edge detector: a two-element kernel applied to a 320 × 280 image stores two parameters, where a dense matrix doing the same job would store billions (Goodfellow et al., section 9.2). The kernel size and the channel counts set the parameter count; the output height and width do not. Part 04 will show that MACs do multiply by h_o · w_o, because the brick is reapplied at every position, and that is the single most important difference between the two metrics.

Grouped convolution: derive it, do not memorize it

A grouped convolution with g groups cuts the c_i input channels into g slices of c_i/g and the c_o output channels into g slices of c_o/g, then runs g ordinary convolutions side by side, each reading only its own input slice and writing only its own output slice. So count one group with the formula you already have: (c_o/g) · (c_i/g) · k_h · k_w. There are g groups, so multiply by g. One factor of g cancels.

#Paramsgrouped=cogcigkhkwg=cocikhkwg\#\text{Params}_{\text{grouped}} = \frac{c_o}{g}\cdot\frac{c_i}{g}\cdot k_h k_w \cdot g = \frac{c_o \cdot c_i \cdot k_h \cdot k_w}{g}
Each group is smaller by g squared, but there are g of them
Four filters, each eight channels deep. With g = 2 each filter keeps only its half of the channels, and the lit volume is half of the resting stack.
Eight input and eight output channels. With g = 2 the 32 cross-group links disappear and two 4 × 4 blocks remain: 64 becomes 32, one division by g.

This matches what a framework actually stores. PyTorch gives Conv2d a weight of shape (out_channels, in_channels / groups, kH, kW) and requires that in_channels and out_channels are both divisible by groups (PyTorch documentation). The historical reason AlexNet has g = 2 in three of its layers is hardware, not elegance: the network was trained across two GTX 580 GPUs with 3 GB each, and "the kernels of the second, fourth, and fifth convolutional layers are connected only to those kernel maps in the previous layer which reside on the same GPU" (Krizhevsky et al., 2012, section 3.5). Grouping halved the weights each GPU had to hold.

Depthwise convolution: the limit g = c_i = c_o

Push the grouping to its extreme, one channel per group, and you get a depthwise convolution. Now g = c_i = c_o and every channel has its own private k_h × k_w filter. In the MobileNets paper this is stated directly: "the depthwise convolution applies a single filter to each input channel" (Howard et al., 2017, section 3.1). Plug g = c_i into the grouped formula and the c_i cancels.

#Paramsdepthwise=cocikhkwci=cokhkw\#\text{Params}_{\text{depthwise}} = \frac{c_o \cdot c_i \cdot k_h \cdot k_w}{c_i} = c_o \cdot k_h \cdot k_w
One k_h × k_w filter per channel

Worked example

One 3 × 3 layer with 256 input and 256 output channels

  1. Standard convolution

    256 · 256 · 3 · 3 = 589,824 weights.
  2. Grouped with g = 2

    589,824 / 2 = 294,912. Each of the two groups is a 128 → 128 convolution with 147,456 weights.
  3. Grouped with g = 8

    589,824 / 8 = 73,728. Eight groups of 32 → 32.
  4. Depthwise, g = 256

    256 · 9 = 2,304. Each channel keeps one 3 × 3 filter.
  5. Ratio to the standard layer

    LayerCount#ParametersRatio
    Standard, g = 1256 · 256 · 9589,8241
    Grouped, g = 2256 · 256 · 9 / 2294,9121/2
    Grouped, g = 8256 · 256 · 9 / 873,7281/8
    Depthwise, g = 256256 · 92,3041/256
Layer#ParametersDepends on h, w?Depends on n?Why
Linearc_o · c_iOnly through c_i after a flattenNoEvery input feature is wired to every output feature; a flattened c_i carries h × w
Convolutionc_o · c_i · k_h · k_wNoNoc_o filters, each c_i deep and k_h × k_w wide
Grouped convolutionc_o · c_i · k_h · k_w / gNoNog independent convolutions on c_i/g and c_o/g channels
Depthwise convolutionc_o · k_h · k_wNoNoGrouped with g = c_i = c_o, one filter per channel
The four counting formulas and what they ignore

The simulator collects all four formulas, adds the bit width from the final concept of this part and the MACs from part 04, and carries a preset for every parameterized AlexNet layer. Try conv3 now and confirm 884,736, then change h_o and watch which readouts move.

SimulatorLayer metrics calculator: parameters, model size, MACs
AlexNet presets, slide 16
Parameters884,736weightsc_o · c_i · k_h · k_w, matches slide 16
Model size (bits)28.31 Mbitsparameters × 32 bits
Model size (MB)3.539MB3,538.9 KB, decimal 10^6 as on slide 17, about 3.375 MiB
MACs149,520,384parameters × h_o × w_o, here × 169, about 149.52 M
FLOPs299.04 MFLOPs2 × MACs, one multiply and one add
Reads per filter256input channelseach filter sees all of c_i

Change h_o or w_o and watch MACs move while the parameter count and model size stay still. Only c_i, c_o, k_h, k_w and g touch the weight count, and only the bit width turns that count into storage.

Quick check

A 3 × 3 convolution has c_i = 64 and c_o = 128. How many parameters does it have?

Quick check

Doubling the input resolution of a CNN does what to a convolution layer's parameter count and MAC count?

Recall

Write the grouped-convolution count two ways and say why the division is by g, not g squared.

(c_o/g) · (c_i/g) · k_h · k_w · g = c_o · c_i · k_h · k_w / g. Each group shrinks both channel dimensions by g, a factor of 1/g², but there are g such groups, which multiplies back by g.

AlexNet is the convolutional network whose variant won the ILSVRC-2012 challenge with a top-5 test error of 15.3%, and its authors state up front that it has "60 million parameters and 650,000 neurons" (Krizhevsky et al., 2012). It is also the best possible exercise for this part: five convolutions, three of them grouped, three max-pools and three linear layers, with input 3 × 224 × 224. Walk it top to bottom and apply the right #Parameters formula at each layer. The output shapes come from lecture 02; here we only count.

Worked example

Counting AlexNet, part one: the convolutions

  1. conv1: 11 × 11, 96 channels, stride 4, pad 2

    Output 96 × 55 × 55. Weights 96 · 3 · 11 · 11 = 34,848. The stride and padding set the 55, but they do not touch the count.
  2. maxpool 3 × 3, stride 2

    Output 96 × 27 × 27. Pooling takes a maximum; it learns nothing and stores nothing: 0 parameters.
  3. conv2: 5 × 5, 256 channels, pad 2, groups 2

    Output 256 × 27 × 27. Grouped, so 256 · 96 · 5 · 5 / 2 = 307,200.
  4. maxpool 3 × 3, stride 2

    Output 256 × 13 × 13, 0 parameters.
  5. conv3: 3 × 3, 384 channels, pad 1

    Output 384 × 13 × 13. 384 · 256 · 3 · 3 = 884,736.
  6. conv4: 3 × 3, 384 channels, pad 1, groups 2

    Output 384 × 13 × 13. 384 · 384 · 3 · 3 / 2 = 663,552.
  7. conv5: 3 × 3, 256 channels, pad 1, groups 2

    Output 256 × 13 × 13. The slide hides this one behind a question mark. Compute it before you reveal the answer below.

Recall

conv5: 3 × 3 kernels, 256 output channels, 384 input channels, groups 2. How many parameters?

256 · 384 · 9 / 2 = 442,368. Without the grouping it would be 884,736, the same as conv3.

Worked example

Counting AlexNet, part two: the linear layers and the total

  1. maxpool 3 × 3, stride 2

    Output 256 × 6 × 6, 0 parameters. This map is flattened into a vector of 256 · 6 · 6 = 9,216 values.
  2. fc6: linear, 4096 outputs

    4096 · 9,216 = 37,748,736. One layer, and already more than half of the network.
  3. fc7: linear, 4096 outputs

    4096 · 4096 = 16,777,216.
  4. fc8: linear, 1000 outputs

    1000 · 4096 = 4,096,000, one output per ImageNet class.
  5. Total

    2,332,704 in the convolutions plus 58,621,952 in the linear layers gives 60,954,656, about 61M, which is what the slide and the paper both round to.
LayerOutput C × H × WCount#ParametersShare
Image3 × 224 × 2240
conv1, 11 × 11, 96 ch, stride 4, pad 296 × 55 × 5596 · 3 · 11 · 1134,8480.06%
maxpool 3 × 3, stride 296 × 27 × 270
conv2, 5 × 5, 256 ch, pad 2, groups 2256 × 27 × 27256 · 96 · 5 · 5 / 2307,2000.50%
maxpool 3 × 3, stride 2256 × 13 × 130
conv3, 3 × 3, 384 ch, pad 1384 × 13 × 13384 · 256 · 3 · 3884,7361.45%
conv4, 3 × 3, 384 ch, pad 1, groups 2384 × 13 × 13384 · 384 · 3 · 3 / 2663,5521.09%
conv5, 3 × 3, 256 ch, pad 1, groups 2256 × 13 × 13256 · 384 · 3 · 3 / 2442,3680.73%
maxpool 3 × 3, stride 2256 × 6 × 60
fc6, linear 409640964096 · (256 · 6 · 6)37,748,73661.93%
fc7, linear 409640964096 · 409616,777,21627.52%
fc8, linear 100010001000 · 40964,096,0006.72%
Five convolutions2,332,7043.83%
Three linear layers58,621,95296.17%
Total60,954,656100%
AlexNet parameters per layer, with the corrected conv1 value and each layer's share of the total

Where the weights actually are

The share column is the real lesson. The five convolutions together hold 2.3M weights, under 4 percent. The three linear layers hold 58.6M, about 96 percent, and fc6 alone holds 62 percent. Krizhevsky and colleagues knew this: a footnote in the paper says that "most of the net's parameters are in the first fully-connected layer" (Krizhevsky et al., 2012). Every input of fc6 is wired to every one of its 4,096 outputs, and it has 9,216 inputs, so the dense wiring the convolutions avoided comes back in one enormous matrix.

There is a subtle exception hiding in that 9,216. The previous concept said parameter counts do not depend on input resolution, and for every convolution that is true. But fc6 takes the flattened 256 × 6 × 6 map as its c_i, and the 6 × 6 came from 224 × 224 through the strides and pools. Feed AlexNet a larger image and fc6 would need a larger weight matrix. The first linear layer after a flatten is the one place where resolution leaks into the parameter count. Global average pooling, introduced in Network in Network, removes that leak: it averages each channel to one number, and "there is no parameter to optimize" in it (Lin, Chen and Yan, 2014), so the classifier input no longer grows with the image.

This table is the starting line for two results you will study later. Han and colleagues pruned AlexNet "from 61 million to 6.7 million" parameters with no loss of accuracy, a 9x reduction (Han et al., 2015), and Deep Compression then cut its storage "from 240MB to 6.9MB" (Han, Mao and Dally, 2016). Both papers attack exactly the layers this table flags: when 96 percent of the weights sit in three linear layers, that is where pruning pays.

Quick check

In AlexNet, which group of layers holds most of the 61M parameters?

Recall

Which AlexNet layers hold about 96 percent of the parameters, and why is fc6 so large?

The three linear layers fc6, fc7 and fc8, with 58.6M of 61M. fc6 is the largest because its input is the flattened 256 × 6 × 6 = 9,216 map, fully wired to 4,096 outputs.

A parameter count is a number of boxes. To know how much storage the boxes take, you need the size of each box. Store AlexNet's 61M weights as 32-bit floating point and each weight takes 4 bytes, so the whole network takes 61M × 4 B = 244 MB. Store the same weights as 8-bitintegers and the same network takes 61 MB. Nothing about the architecture changed; only the bit width did.

Model Size=#ParametersBit Width\text{Model Size} = \#\text{Parameters} \cdot \text{Bit Width}
Valid when the whole network uses one data type. The result is in bits.

That is the definition of model size: the storage needed for the weights of the network, the #Parameters times the bits each one occupies. The slide lists MB, KB and bits as the common units, and the formula as written produces bits. To reach bytes divide by 8, and to reach megabytes divide by another 10^6. The slide is explicit that its megabyte is decimal, 244 × 10^6 bytes. For a single layer, kilobytes are the natural unit: AlexNet's conv3 holds 884,736 weights, which at 8 bits is 884,736 bytes, or 884.7 KB (divide bytes by 10^3), and at 32 bits 3,538.9 KB.

SizeMB=#Parametersbits per weight8106\text{Size}_{\text{MB}} = \frac{\#\text{Parameters} \cdot \text{bits per weight}}{8 \cdot 10^{6}}
Bits to decimal megabytes
The same 61M weights on four shelves. Each halving of the bit width halves the shelf, and int8 lands at a quarter of fp32.
Data typeSize in bitsSize (decimal MB)Slide rounding
32-bit float (fp32)1,950.5 Mbit243.8 MB244 MB
16-bit (fp16 or bfloat16)975.3 Mbit121.9 MB122 MB
8-bit integer (int8)487.6 Mbit61.0 MB61 MB
4-bit integer (int4)243.8 Mbit30.5 MB30.5 MB
1-bit (binary weights)61.0 Mbit7.6 MB7.6 MB
AlexNet model size at each bit width, using the exact count 60,954,656. The last column is what the slide's rounded 61M gives.

The formula assumes one data type for the whole network. Mixed-precision models break that assumption, and then the size is a sum over layers, each layer's count times its own bit width. That is the form you need when, for example, the first and last layers stay at 8 bits while the middle is pushed to 4.

Model Size=l#Paramslbitsl\text{Model Size} = \sum_{l} \#\text{Params}_l \cdot \text{bits}_l
Mixed precision: sum per layer

Why the multiplication matters for this course

The parameter count is fixed once the architecture is chosen, but the bit width is a knob. The lecture on quantization turns that knob, and this formula says exactly what it buys: every halving of the bit width halves the model size with no change to the architecture. Deep Compression combined pruning, quantization and Huffman coding to take AlexNet "from 240MB to 6.9MB" (Han, Mao and Dally, 2016); their 240 MB starting point is, up to rounding, the 244 MB computed in this concept. Part 03 shows a microcontroller SRAM budget of 256 kB (the MCU constraint, a budget for activations). The slides do not give a flash size, but a typical MCU of this class, such as the STM32F746 used by MCUNet (Lin et al., NeurIPS 2020), has about 1 MB of flash, where the weights would live; even 8-bitAlexNet at 61 MB is about 60 times too large for that flash, which is why edge deployment starts with counting.

Quick check

A 10M-parameter model stored entirely in 16-bit numbers occupies how much storage?

Recall

61M parameters at 8 bits: what is the model size in MB, and in bits?

61 MB, that is 61 × 10^6 bytes, because at 8 bits each weight is exactly one byte. In bits it is 61M × 8 = 488 × 10^6 bits.

Recap

If you remember nothing else

  • #Parameters is the number of elements in the weight tensors of the whole network. Bias is ignored in this lecture.
  • Linear c_o · c_i. Convolution c_o · c_i · k_h · k_w. Grouped divides that by g. Depthwise is c_o · k_h · k_w.
  • Parameter count ignores batch size and spatial size. MACs (part 04) do not, because every filter is reapplied at every output position.
  • AlexNet has 60,954,656 parameters, about 61M. conv1 is 34,848 (the slide prints 24,848) and the hidden conv5 is 442,368.
  • The three linear layers hold about 96 percent (58.6M). fc6 alone is 37.7M because its input is the flattened 256 × 6 × 6 map.
  • Pooling layers have zero parameters.
  • Model size = #Parameters × bit width. 61M weights are 244 MB at 32-bit, 122 MB at 16-bit and 61 MB at 8-bit, in decimal MB.

Sources