Skip to content
AI360XpertBeta

L1 & L2 Regularization Derivations

Two penalties, two fates for a small weight. L1 subtracts a constant each step and locks weights at exactly zero, while L2 subtracts a fraction and shrinks them without ever landing on zero.

L1 diamond corners snap weights to zero while the L2 circle only shrinks them
L1 diamond corners snap weights to zero while the L2 circle only shrinks them

Why Does This Exist?

Training loss alone rewards memorisation: a model with enough weights can fit noise exactly and fail on anything new. Regularization adds a penalty for complexity, trading a slightly worse fit on the training set for weights that generalise. Both penalties below do that, yet they produce visibly different models: one sparse, one dense.

This page derives why, from the gradients. The applied side, fitting each penalty on real regressions and reading the coefficients, lives in lasso regression and ridge regression. The unifying view, that minimising f(x)+λ∥x∥2f(x) + \lambda \lVert x \rVert^2 is the Lagrangian of minimising f(x)f(x) subject to ∥x∥2≤c\lVert x \rVert^2 \le c, lives in constrained optimisation and duality, with convexity background in convex optimization.

The one idea you need first

Gradient descent repeats w←w−η∇Lw \leftarrow w - \eta \nabla L, where η\eta is the step size. A penalty P(w)P(w) added to the loss adds its own gradient P′(w)P'(w) to that update. Everything below is one question: what does P′(w)P'(w) look like near zero, where a weight is deciding whether to survive.

Think of It Like This

A warehouse charging for shelf space

A warehouse stores your boxes and charges for the space. Under the L2 tariff the fee per box is proportional to the box size, so every restocking round you shrink each box a little. Boxes get tiny but none ever vanishes: a 10 percent cut of a crumb is nothing, so crumbs persist forever.

Under the L1 tariff there is a fixed handling fee per box plus the space charge, so every round removes the same fixed amount from each box regardless of size. Small boxes hit zero in finite rounds and are gone, while big boxes barely notice. The shelf ends up sparse: a few large boxes, nothing else.

The analogy stops at the kink. Real L1 sparsity comes from the absolute value being non-differentiable at zero, which lets the update lock a weight exactly at zero rather than merely shaving it. The derivation below is that locking mechanism, not warehouse policy.

How It Actually Works

Add the penalty to the loss J(w)J(w), with strength λ>0\lambda > 0 and weights w1,…,wnw_1, \ldots, w_n. In plain words: JJ measures fit, the penalty measures complexity, λ\lambda sets the exchange rate.

L2 (ridge): Jreg=J(w)+λ∑iwi2J_{\mathrm{reg}} = J(w) + \lambda \sum_i w_i^2. The penalty gradient is 2λwi2\lambda w_i, proportional to the weight itself. A gradient step multiplies the weight by (1−2ηλ)(1 - 2\eta\lambda): exponential shrinkage toward zero that never arrives in finite steps. Zero is a fixed point the iterates approach but do not land on.

L1 (lasso): Jreg=J(w)+λ∑i∣wi∣J_{\mathrm{reg}} = J(w) + \lambda \sum_i \lvert w_i \rvert. Away from zero the penalty gradient is λ⋅sign(wi)\lambda \cdot \mathrm{sign}(w_i), a constant independent of size. A gradient step subtracts the same fixed amount ηλ\eta\lambda every round, so small weights cross zero in finite steps. At exactly zero the absolute value has no single derivative; instead the subgradient is the whole interval [−λ,λ][-\lambda, \lambda], which contains a value that cancels the loss gradient and locks the weight at zero. That kink is the entire difference between the two penalties.

Geometry. Read as constrained optimization, L2 restricts weights to a ball and L1 to a cross-polytope, a diamond in two dimensions. Loss contours expanding from the unregularised minimum touch the ball at a generic point with all coordinates nonzero, but touch the diamond at a corner with high probability, snapping one coordinate to exactly zero. The diagram above draws both contacts.

Worked example

One weight, quadratic fit (w−4)2(w - 4)^2, so the unregularised answer is w=4w = 4. Penalise it and solve in closed form.

L2 with λ=1\lambda = 1: minimise (w−4)2+w2(w - 4)^2 + w^2. The derivative 2(w−4)+2w=4w−82(w - 4) + 2w = 4w - 8 vanishes at w⋆=2w^{\star} = 2. Halved, not zeroed.

L1 with strength α=6\alpha = 6: minimise (w−4)2+6∣w∣(w - 4)^2 + 6\lvert w \rvert. For w>0w > 0 the derivative 2(w−4)+62(w - 4) + 6 vanishes at w=1w = 1, which is positive and consistent, so w⋆=1w^{\star} = 1. This is soft thresholding: w⋆=sign(z)max⁡(∣z∣−α/2,0)w^{\star} = \mathrm{sign}(z)\max(\lvert z \rvert - \alpha/2, 0) for target z=4z = 4.

Raise the L1 strength to α=10\alpha = 10: the formula gives max⁡(4−5,0)=0\max(4 - 5, 0) = 0, so w⋆=0w^{\star} = 0, exactly. Check the lock: at w=0w = 0 the loss gradient is 2(0−4)=−82(0 - 4) = -8 and the subgradient interval is [−10,10][-10, 10], which contains +8+8 to cancel it. Locked.

Contrast with strong L2, λ=5\lambda = 5: w⋆=4/(1+5)≈0.667w^{\star} = 4/(1 + 5) \approx 0.667. Small, dense, nonzero. Same target, same spirit of penalty, opposite fate for the weight.

Code

The point is the check: the closed forms above, evaluated, with the dense L2 answer beside the sparse L1 ones.

import numpy as np

def soft_threshold(z: float, alpha: float) -> float:    return float(np.sign(z) * max(abs(z) - alpha / 2, 0.0))  # L1 closed form

print(round(soft_threshold(4.0, 6.0), 3))  # -> 1.0print(round(soft_threshold(4.0, 10.0), 3))  # -> 0.0   exactly sparseprint(round(4.0 / (1 + 5.0), 3))  # -> 0.667  L2 with penalty 5 stays dense

Strength 6 leaves weight 1, strength 10 locks it at 0, while L2 at strength 5 leaves 0.667. Sparsity against shrinkage, in three numbers.

Watch Out For

Regularizing features that live on different scales

The penalty sees raw magnitudes, so a feature measured in thousands carries a penalty thousands of times larger than one measured in fractions, for no statistical reason. L1 then deletes the large-scale features first regardless of merit, and L2 shrinks them hardest. The symptom is a regularized model that discards exactly the variables with the biggest units.

Standardize every feature before penalizing: zero mean, unit variance, fit on the training fold only. Refit without scaling and the selected set changes, which proves the first one was an artefact of units rather than signal.

Running naive subgradient steps and never seeing an exact zero

The locking argument above is about the exact minimum, not about every optimizer reaching it. Plain subgradient SGD with a fixed step subtracts ηλ\eta\lambda past zero, overshoots to the other side, and oscillates around zero forever, so weights hover near zero without ever equaling it. The symptom is a "sparse" model with hundreds of weights at 10−410^{-4} that cannot be pruned safely.

What fixes it is the proximal step: shrink, then threshold, setting values inside [−ηλ,ηλ][-\eta\lambda, \eta\lambda] to exactly zero each round (ISTA and its accelerated FISTA variant), or a library solver built for the L1 objective such as coordinate descent. If your L1 model has no exact zeros, the optimizer is the bug, not the penalty. Check np.sum(w == 0) before claiming sparsity.

The Quick Version

  • L2 adds λ∑wi2\lambda \sum w_i^2 with gradient 2λwi2\lambda w_i: proportional shrinkage by (1−2ηλ)(1 - 2\eta\lambda) per step, never reaching zero.
  • L1 adds λ∑∣wi∣\lambda \sum \lvert w_i \rvert with constant-magnitude steps λ⋅sign(wi)\lambda \cdot \mathrm{sign}(w_i): small weights hit zero in finite steps and lock there via the subgradient interval.
  • Soft thresholding gives the 1D answer in closed form: sign(z)max⁡(∣z∣−α/2,0)\mathrm{sign}(z)\max(\lvert z \rvert - \alpha/2, 0).
  • On target 4, L1 at strength 6 gives 1 and at strength 10 gives exactly 0, while L2 at strength 5 gives 0.667.
  • Geometrically the loss contours touch the L1 diamond at a corner (sparse) and the L2 ball at a generic point (dense).
  • Standardize features before penalizing, and use a proximal or coordinate-descent solver when exact zeros are the goal.