๐ŸŽ“ A1Learner
๐Ÿ”

PyTorch Entropy and KL Divergence

Entropy is one number that measures how spread out a distribution is. KL divergence measures the extra cost of using one distribution in place of another.

Entropy grows with spread

Wider Normal distributions carry higher entropy. Each doubling of the standard deviation adds the same step of about 0.6931.

for std in (0.5, 1.0, 2.0):
    d = Normal(0.0, std)
    print(std, round(d.entropy().item(), 4))

Entropy by hand

A standard Normal has mean 0 and a standard deviation of 1. Its entropy by hand matches the library value.

std = 1.0
hand = 0.5 * math.log(2 * math.pi * math.e * std ** 2)
print("By hand:", round(hand, 4))
print("By library:", round(Normal(0.0, std).entropy().item(), 4))

KL depends on direction

KL divergence depends on the direction of the swap. Swapping p and q changes the number, so KL is not a distance.

p = Normal(0.0, 1.0)
q = Normal(1.0, 2.0)
print("KL p to q:", round(kl_divergence(p, q).item(), 4))
print("KL q to p:", round(kl_divergence(q, p).item(), 4))

Example

import math

import torch
from torch.distributions import Normal, kl_divergence

p = Normal(0.0, 1.0)
q = Normal(1.0, 2.0)

entropy_hand = 0.5 * math.log(2 * math.pi * math.e * p.scale.item() ** 2)
entropy_lib = p.entropy().item()

mu1, s1 = p.mean.item(), p.scale.item()
mu2, s2 = q.mean.item(), q.scale.item()
kl_hand = (math.log(s2 / s1)
           + (s1 ** 2 + (mu1 - mu2) ** 2) / (2 * s2 ** 2) - 0.5)
kl_lib = kl_divergence(p, q).item()

print("Entropy by hand:", round(entropy_hand, 4))
print("Entropy by library:", round(entropy_lib, 4))
print("KL by hand:", round(kl_hand, 4))
print("KL by library:", round(kl_lib, 4))

Key points

  • Entropy: one number for how spread out a distribution is
  • Use dist.entropy() for the library entropy of a distribution
  • KL divergence: the cost of using distribution q in place of distribution p
  • Use kl_divergence(p, q) for the cost of using q in place of p
  • Closed form: a direct formula that needs no sampling or looping
  • KL divergence is not symmetric, so the order of the pair matters

In this example, p is a Normal with mean 0 and a standard deviation of 1. q is a Normal with mean 1 and a standard deviation of 2. The entropy of p is worked out by hand from the closed-form formula. The library entropy prints the same 1.4189. The KL divergence from p to q is also worked out by hand, in closed form. The library value matches at 0.4431. Both pairs agree, so the hand formulas and the library measure the same things.

Note

These values use natural logs, and their unit is called a nat

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท Python Playground

Exercise

KL divergence from p to q prints 0.4431. What does KL from q to p print?