Paper · 2018-04-12 · stat.ML, cs.LG
Regularisation of Neural Networks by Enforcing Lipschitz Continuity
Caps the Lipschitz constant of each layer (its worst-case stretch under l1, l2 or l-inf norm) and keeps it under the cap by projecting weights after every update. The network bound is the product of layer caps. Author-reported: CIFAR-10 VGG19 rises from 90.43% to 92.57% with LCC-l2, and gains are largest with small training sets.
Lipschitz constraintSpectral normalizationDropoutregularizationlipschitz-continuitygeneralizationoperator-normprojected-gradient
arXivPDFCodeMarkdown18 min read
AI-compiled by claude-haiku-5-5 on 2026-10-19, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
A neural network can memorise its training examples and then do badly on new ones. One way to guard against that is to make the network smooth: a small change in the input should cause only a small change in the output. The standard name for the worst-case amount of stretching is the Lipschitz constant.
The paper gives a simple way to put a ceiling on this number for a network built from common layer types. Each layer gets its own ceiling, like a speed limit on that layer. Training then works as usual, but after every weight update any layer that has gone over its limit is scaled back down to the limit. The authors find that this helps most when training data is scarce, that it combines well with dropout, and that the choice of how to measure size (the norm) changes the result. The extra work per step is small, according to the authors.
TL;DR
- Each layer's operator norm is capped at a hyperparameter λ under ℓ1, ℓ2 or ℓ∞; the network's Lipschitz bound is then the product of the layer caps §3 eq. 3 §4.
- Enforcement is projected SGD: after each optimiser step, every weight tensor is divided by max(1, norm/λ) eq. 25 alg. 2.
- ℓ1 and ℓ∞ are computed exactly for convolutions, but ℓ2 is estimated by a power method that can underestimate the norm, so only ℓ1 and ℓ∞ give a guarantee §4.1 §6.
- Author-reported: the authors say LCC is weaker alone than combined with dropout §1; a dropout combination is the best cell in several tables, and gains are largest with few training examples §5 §5.8 tab. 1 tab. 2.
- λ is sensitive. Too small a value collapses accuracy and can stop training from converging; too large a value drifts back to the baseline §5.7.
Problem
Regularising neural networks is hard. The most effective methods, dropout and batch normalisation, are heuristic and hard to transfer reliably to new problems. Classical ℓ2 penalties on parameters are less effective §1. Theory relates generalisation gaps to weight magnitudes and to products of norms of the weight matrices, and the Lipschitz constant appears as a key quantity in several such bounds §1 §2. The paper assumes that functions which vary more slowly generalise better, and that controlling the network's Lipschitz constant controls generalisation §1 §4.
Earlier work mostly used ℓ2 operator norms, with spectral normalisation or a spectral penalty as the usual tool §2. The paper argues that ℓ1 and ℓ∞ norms are also worth using, and that they are cheaper to compute exactly for convolutions §1 §3.2 §4.1.
Method
Layer bounds §3. For any feed-forward composition, the Lipschitz constant of a composition is at most the product of the constants of its parts eq. 3. For a linear layer under the p-norm, its Lipschitz constant equals the operator norm of its weight matrix §3.1 eq. 8.
-
Fully connected layers §3.1. For W of shape out × in, the ℓ1 operator norm is the largest absolute column sum and the ℓ∞ operator norm is the largest absolute row sum. The ℓ2 norm is the spectral norm, the largest singular value. The bias does not enter the bound eq. 4 §3.1.
-
Convolutions, ℓ1 and ℓ∞ §3.2. Let F_ij be the filter from input map j to output map i, and let ‖F‖₁ be the sum of absolute filter entries. The exact norms are the ones below eq. 12 eq. 13.
\|W\|_1 = \max_{j} \sum_{i} \|F_{i,j}\|_1 eq. 12
\|W\|_\infty = \max_{i} \sum_{j} \|F_{i,j}\|_1 eq. 13
-
Convolutions, ℓ2 §3.2. The spectral norm is found by the power method. Each step applies the layer's own convolution, then its transposed convolution, instead of building the matrix eq. 15 eq. 16 eq. 17 alg. 1. Padding and stride are handled because the real operations are used §3.2.
-
Activations and pooling §3.3. ReLU, max pooling and softmax have Lipschitz constant at most 1 for all p-norms §3.3.
-
Residual blocks §3.4. A block φ(x) = x + f(x) eq. 18 has bound 1 plus the product of the layer bounds inside f eq. 24.
-
Batch normalisation §4.2. Viewed as a diagonal scale, the bound is the largest |γ_i / √Var[x_i]| eq. 26 eq. 28. In training the paper projects γ using a moving-average variance, not the minibatch variance §4.2.
Projection §4. After each update a layer's weights W are replaced by π(W, λ), which divides W by max(1, ‖W‖_p / λ). The projection leaves W unchanged when it is already feasible eq. 25 §4. The paper says this is the closest feasible matrix under the operator-norm distance §4.
Training loop §4 alg. 2. The paper uses projected stochastic gradient. Adam converges quickly, and SGD with Nesterov momentum also works §4 §5 intro. Each weight tensor, including convolution filter banks, is projected after the update §4.
# Project one weight tensor into the feasible set [eq. 25]
# Input: weights (dense or conv kernel), cap lam, norm p in {1, 2, inf}
# Output: the weights, scaled down if their operator norm exceeds lam
def project(weights, lam, p):
# Operator norm under p, computed as in [§3.1] and [§3.2]
norm = operator_norm(weights, p)
# Scale only when the norm is above the cap [eq. 25]
scale = 1.0 / max(1.0, norm / lam)
return weights * scale# Projected stochastic gradient training [alg. 2]
# Input: weights W[1..l], caps lam[1..l], optimiser update rule
# Output: trained weights satisfying the per-layer caps
def train(weights, lam, batches):
# Repeat until the weights converge [alg. 2]
for batch in batches:
# Gradient of the loss at the current weights [alg. 2]
grads = gradient(loss, weights, batch)
# Take an ordinary optimiser step [alg. 2]
proposed = update(weights, grads)
# Project each layer back into its feasible set [eq. 25] [alg. 2]
for i in range(len(weights)):
weights[i] = project(proposed[i], lam[i], p)
return weights# Estimate the spectral norm of one layer [alg. 1]
# Input: weights W (conv or dense), iteration count n
# Output: sigma, which never exceeds the true spectral norm [§4.1]
def spectral_norm_estimate(weights, n):
# Random start vector, shaped like the layer input [alg. 1]
x = random_normal(input_shape)
for i in range(n):
# Forward pass with the layer's own operation [eq. 16]
x_mid = apply(weights, x)
# Transposed operation (conv transpose or matmul transpose) [eq. 17]
x = apply_transpose(weights, x_mid)
# Ratio of norms; converges only as n grows [alg. 1]
return norm(apply(weights, x)) / norm(x)Choice of norm §4.1 §5. ℓ1 and ℓ∞ are computed exactly, in time linear in the number of weights. ℓ2 is estimated with a small fixed number of power iterations, so the estimate is a lower bound and the constraint is approximate §4.1. The three norms are compared throughout the experiments §5.
Hyperparameter λ §4 §5.7. The paper describes a single λ that caps every layer, so that a depth-d network has a bound of λ^d §4. In the experiments, λ was instead set separately for each layer type (convolution, dense and batch norm), which gives up to three values §5 intro §5.7.
Hyperparameters
Values the paper states, or that the code states where the paper does not. Code-only values are marked.
| Name | Value | Where | Notes |
|---|---|---|---|
| Norm p | ℓ1, ℓ2 or ℓ∞ (one run per norm) | §3 §5 | Compared throughout; no single best norm across tasks §6. |
| Cap λ | searched per layer type; text gives no values | §5 intro §5.7 | Per-run values are in the scripts, summarised below. Search ranges are code-only: tune.py. |
| Power iterations (ℓ2) | "a small number" | §4.1 | Code default is 2 lipschitz.py lipschitz.py. Code-only. |
| Optimiser | Adam; SGD with Nesterov momentum for residual networks | §5 intro | Code uses Adam with AMSGrad, the variant cifar.py, and SGD with momentum 0.9 and Nesterov for WRN cifar.py. AMSGrad is code-only. |
| Weight initialisation | Glorot | §5 intro | |
| Repeats | five seeds (CIFAR, SVHN, MNIST, Fashion-MNIST); 10 folds (SINS-10); 2 × 5-fold CV (tabular) | §5 intro §5.5 §5.6 | Tables give mean ± standard deviation. |
| Batch normalisation | "used in all networks" | §5 intro | Not what the code does for VGG; see Paper vs code. |
| Batch size | not stated | §4 §5 | Code: 100 for VGG and small models cifar.py and 50 for WRN cifar.py. Code-only. |
| Input scaling | rescaled to [−1, 1] | §5.1 | Code divides by 128 and subtracts 1 cifar.py. |
| Validation split (CIFAR) | 10,000 of the 50,000 training images for tuning | §5.1 | Code holds out the last 10,000 cifar.py. |
| Dropout rates | not stated in the text | §5 | Set per run in the scripts; see the table below. |
| Spectral-decay coefficient | not stated in the text | §5 | Code uses 0.01 for CIFAR and 0.001 for MNIST cifar10-vgg.sh mnist.sh. |
| Hyperparameter search | 50 trials of TPE (hyperopt) | §5 intro | 50 trials is code-only tune.py. |
CIFAR-10 and CIFAR-100 §5.1 §5.2.
| Name | Value | Where | Notes |
|---|---|---|---|
| VGG19 epochs | 140 | §5.1 | Code matches cifar.py. |
| VGG19 learning rate | 1e-4; ÷10 after epochs 100 and 120 | §5.1 | Code matches cifar.py. |
| VGG19 optimiser | Adam | §5.1 | AMSGrad is code-only cifar.py. |
| WRN-16-10 epochs | 200 | §5.1 | Code matches cifar.py. |
| WRN learning rate | 0.1; ÷5 at epochs 60, 120, 160 | §5.1 | Code matches cifar.py. |
| WRN optimiser | SGD, Nesterov, momentum 0.9 | §5.1 | Momentum value is code-only cifar.py. |
| Augmentation | random crops and horizontal flips | §5.1 | Code shifts up to 12.5% and flips; it does not crop cifar.py. |
| CIFAR-100 | same schedules as CIFAR-10; λ tuned for CIFAR-100 | §5.2 |
MNIST and Fashion-MNIST §5.3. Two convolutions with 64 and 128 maps, 5 × 5 kernels, each followed by 2 × 2 max pooling. Then a dense layer of 128 units and a 10-way output. ReLU throughout. Adam, 60 epochs, learning rate 1e-4 divided by 10 at epoch 50. The last 10,000 training images measure performance for tuning. The code runs 30 epochs with the drop at epoch 20; see Paper vs code mnist.py mnist.py.
SVHN §5.4. VGG-style network with four conv–conv–pool blocks of 64, 128, 192 and 256 maps, then two dense layers of 512 and a logistic output. 20 epochs, Adam, learning rate 1e-4 divided by 10 at epochs 15 and 18. WRN-16-4 uses SGD with learning rate 0.1 divided by 5 at epochs 6, 12 and 16. No augmentation. The code's VGG variant has the same block sizes vgg.py and no augmentation svhn.py.
SINS-10 §5.5. Ten predefined folds, each with 9,000 training and 1,000 test images. VGG: 60 epochs, learning rate 1e-4 divided by 10 at epochs 40 and 50. WRN: 100 epochs, learning rate 0.1 divided by 5 at epochs 30, 60 and 80. The final 1,000 training images are the validation set. Paired t-tests decide significance §5.5. The code schedules match sins10.py sins10.py.
Fully connected networks, tabular data §5.6. Two hidden layers of 100 ReLU units. Dropout p ∈ {0.2, 0.3, 0.4, 0.5}. λ grid: {2, 4, …, 18, 20} for ℓ2 and ℓ∞, {5, 10, …, 45, 50} for ℓ1. Grid search per fold, using a hold-out set from the training data. Two repetitions of 5-fold cross-validation. No code for these runs is in the repository.
Per-run λ values for the plain LCC runs. Each row lists the λ values that the repository's scripts use for LCC without batch norm or dropout. The scripts hold every run; this table shows only the plain-LCC rows.
| Setting | ℓ1 (λ_conv, λ_dense) | ℓ2 (λ_conv, λ_dense) | ℓ∞ (λ_conv, λ_dense) | Source |
|---|---|---|---|---|
| CIFAR-10 VGG | 48, 48 | 8, 8 | 48, 16 | cifar10-vgg.sh |
| CIFAR-10 WRN (λ_bn = 10) | 64, 64 | 7, 7 | 52, 38 | cifar10-wrn.sh |
| CIFAR-100 VGG | 56, 48 | 4.3, 7.6 | 54, 30 | cifar100-vgg.sh |
| CIFAR-100 WRN (λ_bn = 9.4 / 6.1 / 11) | 87, 47 | 10, 3.9 | 87, 38 | cifar100-wrn.sh |
| MNIST | 32, 32 | 8, 8 | 16, 16 | mnist.sh |
| Fashion-MNIST | 48, 48 | 8, 8 | 36, 36 | fashion-mnist.sh |
| SVHN VGG | 28, 27 | 4.1, 1.1 | 20, 50 | svhn-vgg.sh |
| SVHN WRN-16-4 (λ_bn = 8.5 / 9.3 / 7.5) | 89, 34 | 5.6, 5.6 | 58, 63 | svhn-wrn.sh |
The λ_bn values are in the scripts on the same lines. For VGG rows the scripts do not set λ_bn, because they run without batch norm. SINS-10 VGG plain-LCC rows are commented out in the script, so they are not in this table sins10-vgg.sh.
Dropout rates in the scripts: CIFAR-10 VGG 0.2 (conv) and 0.5 (dense) cifar10-vgg.sh. CIFAR-10 WRN 0.2 (conv) cifar10-wrn.sh. The other settings are in the same script files.
Results
Author-reported. Setup: test accuracy (%) with mean ± standard deviation over five seeds. Models: VGG19 and WRN-16-10 on CIFAR-10 and CIFAR-100, a small convolutional net on MNIST and Fashion-MNIST, VGG-style and WRN-16-4 on SVHN and SINS-10, and two-hidden-layer networks on tabular data. Baseline: no regulariser, dropout, spectral decay and their combinations with LCC §5. Hardware: not stated.
CIFAR-10 tab. 1. Test accuracy (%).
| Method | VGG19 | WRN-16-10 |
|---|---|---|
| None | 90.43±0.17 | 95.13±0.17 |
| Dropout | 90.46±0.10 | 95.46±0.20 |
| Spectral Decay | 90.14±0.16 | 95.21±0.08 |
| LCC-ℓ1 | 92.48±0.13 | 95.34±0.21 |
| LCC-ℓ2 | 92.57±0.28 | 95.32±0.15 |
| LCC-ℓ∞ | 91.64±0.20 | 95.82±0.19 |
| Dropout + Spectral Decay | 90.29±0.17 | 95.22±0.08 |
| Dropout + LCC-ℓ1 | 91.72±0.17 | 95.47±0.15 |
| Dropout + LCC-ℓ2 | 91.23±0.24 | 95.57±0.15 |
| Dropout + LCC-ℓ∞ | 92.71±0.29 | 95.68±0.11 |
CIFAR-100 tab. 2. Test accuracy (%).
| Method | VGG19 | WRN-16-10 |
|---|---|---|
| None | 65.46±0.43 | 77.94±0.33 |
| Dropout | 66.75±0.40 | 77.98±0.24 |
| Spectral Decay | 65.32±0.24 | 77.93±0.20 |
| LCC-ℓ1 | 69.59±0.29 | 78.16±0.04 |
| LCC-ℓ2 | 68.25±0.38 | 79.00±0.33 |
| LCC-ℓ∞ | 69.16±0.22 | 79.39±0.28 |
| Dropout + Spectral Decay | 66.97±0.24 | 77.70±0.33 |
| Dropout + LCC-ℓ1 | 70.17±0.21 | 79.08±0.11 |
| Dropout + LCC-ℓ2 | 71.76±0.26 | 79.45±0.26 |
| Dropout + LCC-ℓ∞ | 69.25±0.43 | 78.17±1.86 |
MNIST and Fashion-MNIST tab. 3. Test accuracy (%).
| Method | MNIST | Fashion-MNIST |
|---|---|---|
| None | 99.29±0.03 | 92.54±0.10 |
| Dropout | 98.93±0.17 | 91.68±0.17 |
| Spectral Decay | 99.28±0.07 | 92.59±0.03 |
| LCC-ℓ1 | 99.41±0.05 | 93.06±0.15 |
| LCC-ℓ2 | 99.41±0.05 | 92.62±0.18 |
| LCC-ℓ∞ | 99.32±0.09 | 92.87±0.12 |
| Dropout + Spectral Decay | 98.85±0.15 | 91.86±0.18 |
| Dropout + LCC-ℓ1 | 99.35±0.08 | 93.23±0.23 |
| Dropout + LCC-ℓ2 | 99.42±0.10 | 91.71±0.38 |
| Dropout + LCC-ℓ∞ | 99.36±0.04 | 92.75±0.25 |
SVHN tab. 4. Test accuracy (%).
| Method | VGG | WRN-16-4 |
|---|---|---|
| None | 96.90±0.05 | 97.97±0.04 |
| Dropout | 96.98±0.10 | 98.23±0.05 |
| Spectral Decay | 96.88±0.04 | 98.02±0.04 |
| LCC-ℓ1 | 97.17±0.09 | 98.00±0.06 |
| LCC-ℓ2 | 96.94±0.04 | 97.93±0.07 |
| LCC-ℓ∞ | 97.35±0.03 | 98.03±0.05 |
| Dropout + Spectral Decay | 97.10±0.06 | 98.15±0.04 |
| Dropout + LCC-ℓ1 | 97.30±0.07 | 98.21±0.02 |
| Dropout + LCC-ℓ2 | 97.73±0.30 | 98.17±0.05 |
| Dropout + LCC-ℓ∞ | 97.32±0.06 | 98.24±0.06 |
SINS-10, VGG tab. 5. Accuracy (%). The "+/−" column marks a significant change when LCC is added to the other regularisers, at 95% confidence (paired t-test).
| Method | VGG | +/− |
|---|---|---|
| None | 63.73±1.18 | |
| Dropout | 68.65±1.00 | + |
| Spectral Decay | 63.81±1.25 | |
| LCC-ℓ1 | 71.24±1.31 | + |
| LCC-ℓ2 | 69.96±2.16 | + |
| LCC-ℓ∞ | 70.92±2.04 | + |
| Dropout + Spectral Decay | 68.97±1.31 | |
| Dropout + LCC-ℓ1 | 72.18±1.97 | + |
| Dropout + LCC-ℓ2 | 71.15±1.13 | + |
| Dropout + LCC-ℓ∞ | 70.99±1.03 | + |
SINS-10, WRN tab. 6. Accuracy (%). Same significance convention.
| Method | WRN-16-4 | +/− |
|---|---|---|
| None | 68.26±1.89 | |
| Dropout | 68.14±2.78 | |
| Spectral Decay | 76.85±1.29 | + |
| LCC-ℓ1 | 72.85±1.63 | + |
| LCC-ℓ2 | 75.89±2.02 | + |
| LCC-ℓ∞ | 74.09±2.19 | + |
| Dropout + Spectral Decay | 78.57±1.37 | + |
| Dropout + LCC-ℓ1 | 73.27±1.19 | + |
| Dropout + LCC-ℓ2 | 77.93±1.19 | + |
| Dropout + LCC-ℓ∞ | 76.80±1.05 | + |
Tabular, fully connected tab. 7. Mean test accuracy (%), two repetitions of 5-fold cross-validation. Bold marks the best method per dataset in the paper.
| Dataset | None | DO | ℓ1 | ℓ2 | ℓ∞ | DO+ℓ1 | DO+ℓ2 | DO+ℓ∞ |
|---|---|---|---|---|---|---|---|---|
| dig44 | 96.96 | 95.79 | 96.83 | 96.85 | 97.11 | 96.04 | 96.04 | 96.81 |
| letter | 95.37 | 90.28 | 95.29 | 95.34 | 96.42 | 91.44 | 91.37 | 93.24 |
| pendigits | 99.44 | 99.14 | 99.45 | 99.45 | 99.52 | 99.21 | 99.25 | 99.41 |
| sat | 90.82 | 89.18 | 90.75 | 90.73 | 91.00 | 90.08 | 89.84 | 90.06 |
| segment | 95.37 | 93.70 | 95.91 | 95.89 | 96.52 | 93.90 | 93.85 | 95.52 |
| spambase | 94.11 | 93.88 | 94.06 | 93.86 | 94.37 | 93.68 | 93.68 | 94.06 |
| twonorm | 97.16 | 97.64 | 97.10 | 97.05 | 97.41 | 97.71 | 97.68 | 97.69 |
| vehicle | 78.02 | 72.52 | 77.84 | 78.07 | 80.14 | 74.94 | 74.65 | 77.60 |
| vowel | 86.21 | 68.18 | 82.98 | 83.13 | 90.86 | 70.61 | 71.21 | 77.07 |
| waveform | 85.40 | 86.16 | 86.00 | 85.82 | 86.51 | 86.71 | 86.54 | 86.59 |
The paper reports that LCC-ℓ∞ has the highest mean accuracy on eight of the ten datasets, and that its average rank is just over 1.5, against just over 3.5 for no regularisation. It says the gap to the unregularised baseline is not statistically significant, but LCC-ℓ∞ is significantly better than most dropout combinations §5.6 fig. 1.
Sample efficiency fig. 3 fig. 4. Test accuracy (%) at two training-set sizes on CIFAR-10. The values are read from the plotted data in the paper's source, not from a table.
| Method | VGG, 5,000 | VGG, 25,000 | WRN, 5,000 | WRN, 25,000 |
|---|---|---|---|---|
| None | 70.14 | 86.50 | 79.47 | 92.58 |
| Spectral Decay | 70.09 | 86.62 | 82.02 | 92.53 |
| Dropout | 71.11 | 86.11 | 80.39 | 92.73 |
| LCC-ℓ1 | 75.10 | 88.38 | 80.20 | 93.17 |
| LCC-ℓ2 | 72.98 | 88.08 | 80.95 | 92.91 |
| LCC-ℓ∞ | 74.32 | 87.58 | 81.01 | 93.03 |
Sensitivity to λ fig. 2. Read from the plotted data. Accuracy on CIFAR-100 VGG19 as the three λ values are scaled by a common factor c, with batch norm. For LCC-ℓ2, c = 0.8 gives 46.94% and c = 0.9 gives 69.57%. The unregularised baseline is 65.46% tab. 2. LCC-ℓ1 fails to converge at c = 0.6 fig. 2 caption.
Paper vs code
The official code is linked from the footnote in §5 §5 intro. It is henrygouk/keras-lipschitz-networks, owned by the first author, not a fork. It is pinned to commit 943150c1c039f9c3351273ff2788064c61d6242e. The repository has no LICENSE file, so code_license is set to "none". No code is quoted in this card; pseudocode is written from the paper and the code is cited by path and line only.
The constraint code agrees with the paper:
- Norm formulas match eq. 12 eq. 13. The ℓ1 constraint sums over the output axis for dense kernels and over kernel height, width and output channels for convolutions. The ℓ∞ constraint does the same over the other axes lipschitz.py lipschitz.py.
- Projection matches eq. 25. Each constraint divides by max(1, norm/λ) lipschitz.py lipschitz.py lipschitz.py.
- Batch norm matches eq. 28, with one addition. The constraint acts on γ, using the moving variance and a term of 1e-6 that the paper does not write lipschitz.py lipschitz.py.
These points differ:
- MNIST and Fashion-MNIST schedule. The paper says 60 epochs, with the learning rate divided by 10 at epoch 50 §5.3. The code runs 30 epochs and divides at epoch 20 mnist.py mnist.py. The Fashion-MNIST script uses the same file fashion-mnist.sh.
- Batch norm for VGG. The paper says batch norm "is used in all networks" §5 intro. For VGG it is added only with a flag, and the main-table VGG runs leave it out cifar.py cifar.py vgg.py cifar10-vgg.sh cifar10-vgg.sh. WRN always has batch norm wrn.py wrn.py.
- Augmentation. The paper says random crops and horizontal flips §5.1. The code shifts images by up to 12.5% in each direction, fills the gaps with the nearest pixel, and flips cifar.py. It does not crop.
- SINS-10 augmentation. The code builds the same augmenter for SINS-10 but calls
model.fiton the raw arrays, so the augmenter is not used sins10.py sins10.py. The paper does not describe augmentation for SINS-10. - Plain-LCC SINS-10 VGG runs. The script's plain-LCC rows are commented out. The active VGG rows all use batch norm sins10-vgg.sh sins10-vgg.sh. Table 5 includes plain-LCC rows, so the repository does not reproduce them.
- Weight decay in WRN. When spectral decay is off, WRN kernels get an ℓ2 penalty of 5e-5 wrn.py wrn.py. That applies to the "None" baseline and to every LCC and dropout run. The paper does not mention it.
- Output layer. The code constrains the final dense layer with λ_dense vgg.py wrn.py mnist.py mnist.py. The paper says "each layer" §4 without saying whether the output layer is included.
- One λ or three. §4 describes one λ and a bound of λ^d §4. §5.7 and the code use separate λ values for convolution, dense and batch norm §5.7 vgg.py wrn.py. With separate values, the λ^d bound does not hold; the network bound is the product of the caps actually used.
- Power iterations. The paper says "a small number" §4.1. The code uses 2 and draws a fresh random start at every constraint call, with no warm start lipschitz.py lipschitz.py lipschitz.py lipschitz.py. The estimate is always at most the true norm, as the paper says, so the ℓ2 constraint is loose by an amount that depends on the layer §4.1.
- Dropout and test-time scaling. §4.3 describes weights being scaled at test time, which would raise the needed λ §4.3. The repository uses Keras
Dropoutmaybe.py. By Keras's documented behaviour (not stated in this repository), it scales activations during training and does nothing at test time. That is inferred, not confirmed by the code. - Residual shortcuts. The WRN block is pre-activation (batch norm, ReLU, convolution, twice) plus a shortcut that uses average pooling and zero-padding, which are not constrained wrn.py. The paper's residual bound eq. 24 counts the shortcut as the identity with bound 1.
- Tabular runs. There is no code for the tabular experiments in the repository. The grid in §5.6 cannot be checked against code.
- Python version. The scripts use Python 2
printstatements cifar.py sins10.py and Keras 2 APIs such asfit_generator. Porting to Python 3 is needed before running them.
Pitfalls
- ℓ2 is only approximate. Power iteration with two steps can be far from the true spectral norm when the two largest singular values are close, because convergence depends on the ratio σ₂/σ₁ §4.1. The constraint then does not bound the Lipschitz constant. The paper's own conclusion recommends ℓ1 or ℓ∞ when a guarantee is needed §6. If you use ℓ2, log the estimate and check it against an exact SVD on a few layers.
- Cost of projection. For ℓ2 each projection needs a forward and a backward convolution per constrained layer, for each power iteration. ℓ1 and ℓ∞ are computed exactly, linearly in the number of weights §4.1. The paper calls the overhead small but does not measure it.
- λ has a narrow useful range. Values slightly too small collapse accuracy, and the model may not converge at all. Values above the optimum drift back toward the baseline slowly. The optimum differs by dataset, architecture and norm, so there is no typical range §5.7 fig. 2. The code's search ranges (exp of 0–2.5 for ℓ2 and exp of 3–4.5 for ℓ1 and ℓ∞) are a starting point, not a recommendation tune.py.
- The bound is loose by design. The network bound is the product of layer caps. With one λ it grows as λ^d, and residual blocks add the 1 + ∏ term eq. 24. The paper says tighter whole-network bounds may exist but does not give one §3.
- Batch-norm projection uses a moving average. Projecting γ with the minibatch variance is noisy, so the code and the paper use the moving-average variance §4.2 lipschitz.py. The 1e-6 term is not in the paper.
- Dropout changes what λ means. The paper expects that dropout needs a larger λ, but it says that tuning without dropout and then rescaling is not a valid shortcut §4.3.
- Differences are small. Several cells differ by less than one standard deviation (for example, CIFAR-10 WRN, LCC-ℓ∞ 95.82 ± 0.19 vs. dropout + LCC-ℓ∞ 95.68 ± 0.11). Only the SINS-10 and tabular significance tests are reported §5.5 §5.6.
- Plain LCC is weak alone. The authors say the method is not competitive in isolation but is highly effective combined with other common regularisers §1. Several best cells in the tables are dropout combinations tab. 1 tab. 2 tab. 4.
- Data-scarcity claim. The sample-efficiency curves cover CIFAR-10 only §5.8. The abstract's small-data claim rests on them, so treat it as shown for CIFAR-10 alone.
- Unstated values. Batch size, hardware, dropout rates, spectral-decay coefficients, the number of power iterations and the λ values are not in the text. The scripts give them, but the paper does not justify them.
Lineage
- Builds on: dropout and maxnorm [Srivastava et al. 2014] §2; generalisation bounds that use products of norms [Bartlett et al. 2017] [Neyshabur et al. 2017] [Golowich et al. 2018] §1 §2; spectral-norm penalty for networks [Yoshida & Miyato 2017] and spectral normalisation for GANs [Miyato et al. 2018] §2. These are cited by name only; no arXiv ids are given in the paper text.
- Compared against: dropout and spectral decay §5.1; ℓ2 penalties are mentioned as weaker than dropout §1.
- Concurrent work: Sedghi et al. 2018 and Tsuzuku et al. 2018, both on convolutional spectral norms §2.
- Superseded: not stated.
Source and license
Adapted from “Regularisation of Neural Networks by Enforcing Lipschitz Continuity” by Henry Gouk, Eibe Frank, Bernhard Pfahringer, Michael J. Cree (arXiv:1804.04368), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/henrygouk/keras-lipschitz-networks at commit 943150c1c039 (none (no LICENSE file in the repository)). Any quoted code is shown under that license.