Jensen-Shannon Divergence
KL divergence points one way and explodes on zeros. Jensen-Shannon meets in the middle: symmetric, always finite, capped at one bit.
Why Does This Exist?
is directed and infinite when misses 's support: useless for comparing disjoint generator outputs or text distributions with different vocabularies. Evaluation needs a symmetric, finite ruler that still respects information geometry.
JSD with is that ruler: symmetric, in bits ( nats), zero exactly at equality, with a metric. It symmetrizes KL divergence for the comparisons in mutual information (MI is a KL; JSD is its tamed cousin).
The one idea you need first
KL prices extra bits using where rules. The midpoint covers both supports, so neither KL explodes. Averaging removes direction.
Think of It Like This
Meeting halfway
Two hikers argue whose trailhead is better. Instead of pricing each from the other's start (KL, possibly impossible), both walk to the midpoint camp and price from there. Same camp both ways: symmetric, reachable, bounded effort.
Midpoint effort caps at the trail length (1 bit). Where it stops: halfway flattens real asymmetries. If direction matters (coding cost one way), keep KL.
How It Actually Works
Properties: bit, symmetric, finite for all pairs, satisfies triangle inequality. Identity: with a fair mixture bit equals : JSD is the information a sample reveals about its source. Original GANs minimize JSD implicitly; evaluation uses it for stability where KL would be infinite. Estimate via plug-in on shared support (midpoint covers union) with smoothing for small samples.
Worked example
, , . ... compute: . . JSD ... recompute precisely: first term ; second ; sum . Second KL: ; ; sum . Average bits. far under the 1-bit cap.
Code
import numpy as np
p = np.array([0.5, 0.5])q = np.array([0.75, 0.25])m = 0.5 * (p + q)jsd = 0.5 * (p * np.log2(p / m)).sum() + 0.5 * (q * np.log2(q / m)).sum()print(round(float(jsd), 3)) # -> 0.049Code 0.049 pins the hand arithmetic. Prose, program, and diagram agree.
Watch Out For
Reading JSD saturation as progress
Near-disjoint distributions all score ~1 bit: JSD saturates and its gradient vanishes. GAN and embedding comparisons stall with "everything maximally different" while shapes differ wildly.
Use Wasserstein or MMD for geometry among far-apart laws. If JSD sits at 0.99+ across variants, the ruler is pegged.
Comparing JSD across different support sizes
Vocabulary or binning changes move the 1-bit cap's meaning: finer bins inflate attainable JSD without real change. Cross-tokenizer JSD leaderboards compare rulers, not models.
Fix the support and smoothing first. If bins differ, renormalize or switch metric.
The Quick Version
- JSD midpoints KL: symmetric, finite, capped at 1 bit, square-root metric.
- Fair versus 0.75-biased coins score about 0.049 bits.
- MI with a mixture bit is exactly a JSD; original GANs optimize it implicitly.
- Saturates near 1 for disjoint laws; use geometric metrics there.
- Fix support and smoothing before comparing across setups.
- Keep directed KL when coding direction is the question.