Majid Al-RaimiPruning criteria: magnitude and scaling factors

COE 592Lecture 4.1Part 05

Pruning criteria: magnitude and scaling factors

What makes a parameter less important, magnitude-based importance at element and row level with L1, L2 and general Lp norms, and scaling-based filter pruning that reuses batch normalization gamma factors.

Concepts
4
Slides
26-33
Reading
24 min
Understood
0/4 concepts

Why this part matters

Parts 03 and 04 settled the shape of what gets removed: a single weight, a pattern, a row, a whole channel. They never said which one. This part answers that question with the two criteria that run most real pruning: the magnitude of a weight or a group of weights, and a learned scaling factor per channel.

The same computations come back in three places. In a COE 592 exam you will be handed a small matrix and asked for its element-wise and row-wise importances and the pruned result. In code, every call to PyTorch's prune.l1_unstructured or prune.ln_structured does exactly what this part derives by hand. And in your research project, when a channel-pruned model has to justify its accuracy on an embedded board, the batch normalization gamma criterion at the end of this part is the one most practical channel-pruning pipelines actually use.

By the end you can

  1. State the principle behind every pruning criterion and apply it to a single neuron.
  2. Compute element-wise importances |W| and produce the pruned matrix for a target sparsity.
  3. Score rows or channels with L1, L2 and general Lp norms and say which row is pruned.
  4. Show with numbers when L1 and L2 rank structural sets differently.
  5. Explain scaling-based pruning and why batch norm gamma is a free channel importance.

Start with one neuron and three inputs. Its output is y = ReLU(10 x_0 - 8 x_1 + 0.1 x_2), and the budget says one of the three connections has to go. Removing the 10 changes the pre-activation by up to 10 |x_0|. Removing the -8 changes it by up to 8 |x_1|. Removing the 0.1 changes it by at most 0.1 |x_2|. If the three inputs are of similar size, the third cut is a hundred times gentler than the first, and that is the one to make.

y=f(iwixi+b)y = f\Big(\sum_i w_i x_i + b\Big)
One neuron: a weighted sum of inputs, a bias, then a nonlinearity f such as ReLU

That small decision contains the whole idea of a Pruning criterion. Pruning asks the network to give up parameters, and the principle the lecture states is simple: the less important the parameters being removed are, the better the performance of the pruned network is. Every criterion in this lecture is a different way of estimating importance, and importance always means the same thing underneath: how much the loss would change if this parameter, or this group, were set to zero. Magnitude, the subject of this part, is the cheapest such estimate. Second-order methods in the next part spend far more compute to estimate the same quantity more carefully (Second-order pruning).

The two strong connections light up and the output survives; the 0.1 connection is cut because it moves the sum least

Worked example

Three candidate deletions

  1. Cut the 10

    The pre-activation loses 10 x_0. For a typical input this is the largest term in the sum, so the output can flip from firing to silent.
  2. Cut the -8

    The pre-activation loses -8 x_1. The sign is negative, but the size of the change is 8 |x_1|, almost as large as the first case.
  3. Cut the 0.1

    The pre-activation loses 0.1 x_2. With inputs of similar scale, this is a rounding error next to the other two terms.
  4. Remove the 0.1

    The connection with the smallest absolute weight is removed, and y = ReLU(10 x_0 - 8 x_1) is almost the same function as before.

Notice what the example needed to make the decision: nothing but the weights. No data, no gradients, no second run through the training set. That is the appeal of magnitude criteria and also their limit. They answer the Pruning formulation only approximately, because the formulation asks for the smallest increase in loss under a budget on nonzeros, and magnitude is a proxy for loss, not the loss itself. The next three sections make the proxy precise for single weights, for rows, and for whole channels.

Recall

W = [10, -8, 0.1] feeds a ReLU neuron. Which weight goes first, and what assumption makes that answer safe?

The 0.1, because it has the smallest absolute value. The answer assumes x_0, x_1 and x_2 have similar scale, since the removed term is really |w_i| |x_i|.

Quick check

With W = [10, -8, 0.1] and inputs of similar scale, which weight does magnitude pruning remove first?

Now scale the neuron up to a weight matrix. Take W = [[3, -2], [1, -5]] and a budget of 50 percent Sparsity, which on four weights means exactly two zeros. Write the absolute value of every entry, keep the two largest, zero the rest. The importances are [[3, 2], [1, 5]], the survivors are 3 and -5, and the pruned matrix is [[3, 0], [0, -5]].

Importance=W\text{Importance} = |W|
Element-wise magnitude: each weight is scored by its own absolute value
The minus signs drop away, the two largest magnitudes fill in, and the pruned matrix keeps 3 and -5

This is Magnitude-based pruning at its finest granularity, the fine-grained case from part 03, and it is the criterion of the paper the slides cite. Han, Pool, Tran and Dally train a network, prune every connection whose weight falls below a threshold, and retrain the survivors. Done once, that took AlexNet to 5x fewer parameters; done iteratively, prune then retrain then prune again, it reached 9x on AlexNet (61M to 6.7M) and 13x on VGG-16 (138M to 10.3M) with no loss of accuracy. They also tried the obvious alternative, removing weights at random with probability tied to their magnitude, and report that it gave worse results. Hard thresholding on |w| won.

Worked example

From W to the pruned matrix at 50 percent sparsity

  1. Take absolute values

    |W| = [[3, 2], [1, 5]]. The -2 becomes 2 and the -5 becomes 5.
  2. Count how many survive

    Four weights at 50 percent sparsity means 4 × (1 - 0.5) = 2 survivors.
  3. Rank and keep

    Sorted importances are 5, 3, 2, 1. Keep the entries scoring 5 and 3, which are the original -5 and 3.
  4. Pruned weight

    [[3, 0], [0, -5]]. The kept weights keep their signs; only the zeros are new.

In code, this is one call. PyTorch's prune.l1_unstructured(module, name, amount) prunes a tensor by removing the units with the lowest L1 norm, and amount can be a fraction such as 0.5 or an absolute count. The name is exact: on a single element the L1 norm is just its absolute value, so element-wise L1 and |W| are the same criterion, and the slide's label "L1-norm, element-wise" is the same statement as Importance = |W|. Any other p would give the same ranking on single elements, which is why the choice of norm only starts to matter in the next section.

Recall

Compute the element-wise importances of [[3, -2], [1, -5]] and the result at 50 percent sparsity.

Importances [[3, 2], [1, 5]]. Two survivors: 3 and -5. Pruned matrix [[3, 0], [0, -5]].

Keep the same matrix, [[3, -2], [1, -5]], but change the unit of removal. Instead of two individual entries, remove one whole row. A row of a linear layer's weight matrix is one output neuron's incoming connections, so deleting it is Neuron pruning, and the result is a smaller dense matrix that any library runs faster (Coarse-grained (structured) pruning). The question is how to score a row when it holds several weights of different sizes and signs.

The lecture's answer is to treat the row as a Structural set, written W^(S) for the set S of parameters it contains, and to collapse its absolute values into one number. Two collapses are standard. Add them: the L1-norm importance. Or square them, add, and take the root: the L2-norm importance. Row 0 scores |3| + |-2| = 5 under L1 and sqrt(9 + 4) = sqrt(13) = 3.61 under L2. Row 1 scores |1| + |-5| = 6 and sqrt(1 + 25) = sqrt(26) = 5.10. Both norms rank row 1 higher, so both prune row 0, and the pruned matrix is [[0, 0], [1, -5]].

ImportanceL1=iSwi\text{Importance}_{L1} = \sum_{i \in S} |w_i|
Row-wise L1: the sum of absolute values over the structural set S
ImportanceL2=iSwi2\text{Importance}_{L2} = \sqrt{\sum_{i \in S} |w_i|^2}
Row-wise L2: the Euclidean length of the row
The two rows collapse to their L1 scores 5 and 6; the lower score loses and its whole row becomes zeros

Worked example

Row-wise scores, both norms

  1. Absolute values first

    Row 0 is [3, 2] in magnitude, row 1 is [1, 5].
  2. L1: add

    Row 0: 3 + 2 = 5. Row 1: 1 + 5 = 6.
  3. L2: square, add, root

    Row 0: sqrt(9 + 4) = sqrt(13) = 3.61. Row 1: sqrt(1 + 25) = sqrt(26) = 5.10.
  4. Compare and zero the loser

    Under both norms row 0 scores lower, so every entry of row 0 becomes zero.
  5. Pruned weight

    [[0, 0], [1, -5]]. Compare with the element-wise result [[3, 0], [0, -5]]: the same Sparsity, a different pattern, because the unit of removal changed.
CriterionRow 0 scoreRow 1 scoreRow prunedPruned matrix
Element-wise |w|not a row scorenot a row scorenone (two smallest elements)[[3, 0], [0, -5]]
Row-wise L156row 0[[0, 0], [1, -5]]
Row-wise L2sqrt(13) = 3.61sqrt(26) = 5.10row 0[[0, 0], [1, -5]]
Three criteria on [[3, -2], [1, -5]] at 50 percent sparsity

One formula for every p

L1 and L2 are two settings of one dial. Goodfellow, Bengio and Courville define the Lp norm of a vector for any p ≥ 1 as the p-th root of the sum of p-th powers of the absolute values. Set p = 1 and the root and the power vanish, leaving slide 29. Set p = 2 and you get the Euclidean length of slide 30. Slide 31 is the same example under the general formula, not a new method.

W(S)p=(iSwip)1/p\big\lVert W^{(S)} \big\rVert_p = \Big(\sum_{i \in S} |w_i|^p\Big)^{1/p}
The Lp norm of a structural set; p = 1 and p = 2 recover the two criteria above

When the norm changes the answer

On the slide's matrix L1 and L2 agree, and it is tempting to file the norm as a cosmetic choice. It is not. Compare a row [3, 3] with a row [0, 5] competing for the last surviving slot. L1 scores them 6 against 5 and keeps [3, 3]. L2 scores them sqrt(18) = 4.24 against 5 and keeps [0, 5]. Squaring amplifies the single largest entry, so L2 rewards a row with one dominant weight. Summing treats every unit of magnitude the same, so L1 rewards a row with many moderate weights. Goodfellow et al. describe the same contrast in general terms: the L1 norm grows at the same rate in all locations, while the squared L2 norm increases very slowly near the origin.

RowL1 scoreL2 score
[3, 3]3 + 3 = 6sqrt(9 + 9) = 4.24
[0, 5]0 + 5 = 5sqrt(0 + 25) = 5
Row kept[3, 3][0, 5]
Two rows, two norms, two different survivors
The L1 diamond of radius 6 passes through a = [3, 3] with b inside it; the L2 circle of radius 5 passes through b = [0, 5] with a inside it

Try it yourself. The explorer below scores an editable matrix element-wise or row-wise, always computes both row norms so a disagreement is visible without toggling, and ships with the slide's example and the [3, 3] against [0, 5] case as presets. Change a single entry and watch which row the two norms fight over.

SimulatorMagnitude criterion explorer: element-wise or row-wise, L1 or L2
any p gives |w| on one element
Weight W
Editable weight matrix
Importance |W|
3215
Pruned W
300-5

Keeping the top 2 of 4 elements by |w|; the rest become zero. Signs never enter the score. Ties keep the lower index. Achieved sparsity: 50 percent of 4 weights.

Where the row-wise criteria come from

The L1 row score is the criterion of Li et al. Their filter importance is the sum of the absolute kernel weights of a filter, which they describe as an expectation of the magnitude of the output feature map. They remove the m filters with the smallest sums, delete the matching input channels from the next layer, and show that pruning the smallest works better than pruning at random or pruning the largest. On CIFAR-10 this cut inference cost by up to 34 percent for VGG-16 and 38 percent for ResNet-110 with retraining recovering the accuracy. Because a filter is a structural set, this filter pruning is Channel pruning from part 04 with an explicit score attached.

The L2 row score is what Wen et al. put inside training. Their structured sparsity learning adds a group Lasso regularizer to the loss, a sum over groups of sqrt(sum of squared weights in the group), which is exactly the L2 norm of each structural set. The optimizer is then rewarded for driving whole filters, channels, filter shapes or even layers to zero, and they report 5.1x CPU and 3.1x GPU speedups on AlexNet's convolutional layers, and a ResNet on CIFAR-10 shrunk from 20 to 18 layers with accuracy moving from 91.25 to 92.60 percent, still above the original 32-layer ResNet. The difference between the two papers is when the norm is used: Li et al. score a trained network after the fact, Wen et al. shape the network during training so the sets to remove are already near zero.

PyTorch exposes the post-hoc version directly. prune.ln_structured(module, name, amount, n, dim) removes the channels with the lowest Ln norm along the specified dimension; n = 1 or 2 picks the norm, and dim = 0 on a weight of shape [c_o, c_i, k_h, k_w] scores whole filters. Finer structural sets such as a row inside a kernel (Vector-level pruning) use the same formula on a smaller S.

Recall

Row-wise L1 and L2 scores of [[3, -2], [1, -5]], and the pruned result at 50 percent.

L1: 5 and 6. L2: sqrt(13) = 3.61 and sqrt(26) = 5.10. Row 0 is pruned under both, giving [[0, 0], [1, -5]].

Recall

Give two rows where L1 and L2 disagree, with the numbers.

[3, 3] against [0, 5]. L1: 6 against 5, keeps [3, 3]. L2: 4.24 against 5, keeps [0, 5].

Quick check

Row-wise L1 pruning of [[3, -2], [1, -5]] at 50 percent sparsity removes which row, and why?

Quick check

Rows [3, 3] and [0, 5] compete for one surviving slot. Which row does each norm keep?

A convolution layer has N filters, one per output channel (Convolution weight dimensions). Give each filter a single trainable number, its scaling factor, and multiply that channel's entire output by it. On the slide the factors come out as 1.17, 0.10, 0.29, 0.82, ..., 0.56. Suppose the threshold is 0.3 (the slide only marks the two smallest factors as pruned) and two channels fall below it: filter 1 at 0.10 and filter 2 at 0.29. Delete those filters, delete the input channels that consumed their outputs in the next layer, and what remains is filter 0, filter 3, on to filter N-1: a physically narrower layer.

Hovering raises the threshold to 0.30; the channels with gamma 0.10 and 0.29 fade out and the survivors close the gap

This is Scaling-based pruning, and it differs from the norms in one important way. A norm scores a trained network after the fact, from the weights alone. A scaling factor is a parameter that training itself sets, so the network is asked, during training, how much it wants each channel. Liu et al. call the method network slimming and make the question sharp by adding an L1 penalty on the factors to the loss.

L=(x,y)(f(x,W),y)+λγΓγL = \sum_{(x, y)} \ell\big(f(x, W), y\big) + \lambda \sum_{\gamma \in \Gamma} |\gamma|
Network slimming: the usual loss plus an L1 penalty that pushes every channel scaling factor toward zero

The L1 penalty is the same L1 from the previous section, now used as a regularizer rather than a score: it charges every unit of |gamma| equally, so factors that the loss does not defend slide all the way to zero. Liu et al. use lambda = 1e-4 for VGGNet and 1e-5 for ResNet and DenseNet on CIFAR. After training they sort every factor in the whole network and set one global threshold at a percentile: pruning 70 percent of channels means the threshold is the 70th percentile of all factors, so layers with many weak channels lose more than layers with strong ones, which is the per-layer Pruning ratio falling out automatically. Then they fine-tune the slimmed network, and can repeat the whole loop.

Network slimming on VGGNet, CIFAR-10, 70 percent of channels pruned (Liu et al., 2017)

Test error
6.34 percent to 6.20 percent
Parameters
20.04M to 2.30M (88.5 percent fewer)
FLOPs
7.97e8 to 3.91e8 (51.0 percent fewer)
Multi-pass
up to 20x smaller and 5x less compute

Why the factor is already there: batch norm gamma

Where does the scaling factor live? Liu et al. observe that almost every modern convolution is followed by batch normalization, and batch normalization already contains one. Ioffe and Szegedy normalize each channel of a mini-batch to zero mean and unit variance, then let the network undo that with two learned parameters per channel: a scale gamma and a shift beta. Goodfellow et al. explain why they exist: the normalized activation is replaced by gamma H' + beta so the new variable can have any mean and standard deviation the network wants. That gamma is the Batch normalization scaling factor, one per output channel, and it is the scaling factor the slide reuses.

zo=γziμBσB2+ϵ+βz_o = \gamma \, \frac{z_i - \mu_{\mathcal{B}}}{\sqrt{\sigma^2_{\mathcal{B}} + \epsilon}} + \beta
Batch normalization for one channel: mini-batch statistics normalize z_i, then gamma rescales and beta shifts

Two things make gamma the right choice, and both are exam material. First, cost: reusing gamma adds no new parameters and no new layers. Liu et al. say it introduces no overhead, and in PyTorch the vector is already sitting in BatchNorm2d.weight, a learnable parameter of size C initialized to one, next to beta in BatchNorm2d.bias initialized to zero, with epsilon = 1e-5 by default.

Second, and more subtle, meaning. Suppose you skipped batch normalization and simply inserted a scaling layer after the convolution. Convolution is linear and scaling is linear, so the network could halve every factor and double the corresponding filter weights without changing a single output. The factor would then say nothing about importance, because the network can move magnitude freely between the factor and the weights, and an L1 penalty on the factor would be defeated the same way. Liu et al. call such a factor meaningless. Batch normalization breaks the symmetry: the normalized activation has a fixed unit scale regardless of what the filter weights do, so gamma alone sets the size of the channel's output and its magnitude is a genuine measure of how much the channel contributes.

Recall

Why does network slimming reuse batch norm gamma instead of adding a new scaling layer?

Gamma is already a per-channel trainable scale, so no new parameters or layers are needed. A standalone scaling layer after a linear convolution is meaningless because the scale could be moved into the weights, but batch normalization fixes the normalized activation's scale, so gamma alone measures the channel.

Recall

Factors 1.17, 0.10, 0.29, 0.82 and 0.56 with a threshold of 0.3: which filters go?

Filters 1 and 2, with factors 0.10 and 0.29. Their input channels in the next layer are removed as well.

Quick check

Why does network slimming reuse batch normalization's gamma as the channel scaling factor?

Recap

If you remember nothing else

  • A criterion estimates importance. The less important the removed parameters, the better the pruned network performs.
  • Magnitude pruning uses absolute value, never the signed weight: -5 is more important than 3.
  • Element-wise: Importance = |W|. [[3, -2], [1, -5]] at 50 percent sparsity becomes [[3, 0], [0, -5]].
  • Row-wise L1 gives 5 and 6, row-wise L2 gives 3.61 and 5.10. Both prune row 0, giving [[0, 0], [1, -5]].
  • General form: ||W^(S)||_p = (sum over i in S of |w_i|^p)^(1/p). L1 favors many moderate weights, L2 favors one dominant weight, as [3, 3] against [0, 5] shows.
  • Scaling-based pruning trains one factor per output channel and prunes small |gamma|. Network slimming adds an L1 penalty on gamma and prunes below a global percentile.
  • Batch norm gamma is that factor for free: z_o = gamma (z_i - mu_B)/sqrt(sigma_B^2 + epsilon) + beta, one gamma per channel, no extra parameters.

Sources