4.5.4 · D2Generative Models

Visual walkthrough — Reparameterization trick

1,751 words8 min readBack to topic

Step 1 — What a "sample from a distribution" actually looks like

WHAT. Our story stars a machine (called the encoder) that, given a picture , spits out two numbers: a center and a spread . Then a dice-roll picks a point near that center. We write this dice-roll as

  • ::: the random point we draw (a "latent code")
  • ::: read "is drawn from" — the wavy line means randomness happens here
  • ::: the Gaussian (bell curve) distribution
  • ::: the center of the bell — where samples cluster
  • ::: the spread — how wide the bell is ( always)

WHY. In a VAE the whole point is that is a guess — a randomly chosen code that could have made . Randomness is a feature, not a bug. But randomness is exactly what will fight us in Step 3.

PICTURE. Look at the bell below. The peak sits at ; the wider the curve, the bigger . A sampled is like dropping a dart that lands somewhere under the bell — more often near the middle.

Figure — Reparameterization trick

Step 2 — What "gradient" means, and why we want one

WHAT. Training means: nudge the encoder's knobs to make a loss smaller. The tool that tells us which way to nudge is the gradient, written .

  • ::: the loss — one number saying "how bad are we" (small = good)
  • ::: all the encoder's internal dials (its weights). and come out of these.
  • ::: the arrow of fastest increase of as we wiggle ; we step against it to go downhill

WHY. Gradients are the currency of backpropagation. To move the encoder at all, we need and — how the loss reacts when we slide the center or squeeze the spread.

PICTURE. Below, the loss is a valley. The gradient is the steepest-downhill arrow at your feet. No arrow → you're standing blind → no learning.

Figure — Reparameterization trick

Step 3 — The blockage: gradients cannot cross a dice-roll

WHAT. Try to compute directly on . It has no value. Nudge a hair; the random jumps to a fresh random place with no fixed relationship to the nudge.

WHY. A derivative asks "if input moves by a tiny amount, how much does output move?" That question needs the output to be a deterministic function of the input. A dice-roll is not a function of — the same gives different every time. So the chain of gradients from back to snaps at the sampling node.

PICTURE. The computation graph: a solid green arrow means "gradients flow." The stochastic node (the dice) is a red wall — the arrow dies there.

Figure — Reparameterization trick

Step 4 — The key fact: a shift and a stretch build any Gaussian

WHAT. Take one fixed dice — the standard normal (center , spread ). Then

is distributed exactly as .

  • ::: noise from a fixed bell that never changes, no matter what is
  • ::: shift — slide the whole bell so its center lands on
  • ::: stretch — widen the bell by a factor

WHY. This is the location–scale property of Gaussians. It lets us manufacture the exact same randomness as Step 1, but sourced from a dice that doesn't know about . Check the two knobs land right:

  • center:
  • spread:

PICTURE. Watch the standard bell (left) get slid by and widened by into our target bell (right). Same shape, relocated and rescaled.

Figure — Reparameterization trick

Step 5 — Reroute the randomness: move the dice off to the side

WHAT. Rebuild the computation graph. The dice-roll now happens on , before and ever touch it. The path that carries into is the plain arithmetic — no dice on it.

WHY. Randomness still exists (we still draw ), but it lives on a branch that has no in it. The main trunk from to is now a smooth, differentiable function . The red wall is gone from the trunk.

PICTURE. Compare with Step 3. The dice moved to a side-input; the trunk is now solid green all the way. Gradients cross freely.

Figure — Reparameterization trick

Step 6 — Send the gradient through the smooth path (worked numbers)

WHAT. With the chain rule now runs. Using the parent's Example 1: encoder gives , ; we draw ; the loss is .

  • ::: how the loss reacts to a bump in the code (negative → raising lowers loss)

Now the two local derivatives of the smooth path:

  • ::: shift by moves one-for-one
  • ::: the drawn noise is the sensitivity of to the stretch

Chain them:

WHY. Both gradients are finite numbers — gradient descent can now push up (toward the target ) and adjust . This is the payoff: the wall of Step 3 is fully crossed.

PICTURE. The graph carries real numbers backward: flows into , into , each factor labelled on its edge.

Figure — Reparameterization trick

Step 7 — Edge and degenerate cases (nothing left hidden)

WHAT & WHY, case by case:

(a) flips the -gradient. Redo Step 6 with the same but : Now the -gradient is positive → "shrink ." Makes sense: a negative with a big dragged below the target, so we want less spread. The sign of correctly tracks the drawn .

(b) (collapse to a point). The stretch vanishes: deterministically. The -gradient still equals (the path survives). The -gradient is and stays finite. So the trick degrades gracefully into an ordinary deterministic layer — no division, no blow-up.

(c) Multivariate, dimensions with diagonal covariance. Draw ( independent standard normals) and apply element-wise: where is entrywise multiply. Each coordinate is its own copy of Step 4, so the Jacobian is diagonal and backprop stays cheap.

(d) Non-reparameterizable distributions. If the sample is discrete (a category), you cannot write it as smooth-shift-plus-fixed-noise — there's no continuous stretch. Then this exact trick fails; you reach for the Gumbel-Softmax relaxation, or the score-function estimator used in policy gradients. The parent's ELBO objective, whose KL term and reconstruction term both depend on , only backprops cleanly because the Gaussian latent is reparameterizable.

PICTURE. Four mini-panels: (sign flip), (collapse), the -dim Hadamard product, and the discrete "no smooth path" wall.

Figure — Reparameterization trick

The one-picture summary

Everything above in a single frame: the fixed dice sits off on a side branch (blue), flows through center-and-stretch (green) into , and the gradient walks all the way back. The dashed red is the old dead path we abandoned.

Figure — Reparameterization trick
Recall Feynman retelling — say it like you'd explain to a friend

We wanted to train a machine that makes a random guess , and to train it we need gradients — little arrows saying "nudge this dial that way." But you can't send an arrow through a dice-roll: change the dial, the dice still lands wherever it wants, so there's no "how much did the output move." Dead end.

The fix is sneaky and simple. A bell curve with center and width is just the standard bell (center 0, width 1) picked up, slid over to , and stretched by . So instead of rolling a -dice, we roll a plain standard-dice once, off to the side, then compute with ordinary arithmetic. The randomness never touches the dials anymore — it's a side ingredient. The path from the dials to is now plain multiply-and-add, and gradients stroll right through it: , . Same random behavior as before, but now trainable. If the width shrinks to zero it just becomes a normal deterministic layer; if the thing you're sampling is a discrete category there's no smooth stretch to exploit, and you need a different trick entirely.