TAI BUI
Back to curriculum
LearnPython

Information Theory

Information theory measures surprise, in bits. Cross-entropy, KL divergence, and perplexity all reduce to the same handful of ideas Shannon wrote down in 1948.

TIME: ~60 minutesPREREQUISITES: Phase 1, Lesson 06 (Probability)

Learning Objectives

  • Compute entropy, cross-entropy, and KL divergence from scratch and explain their relationship
  • Derive why minimizing cross-entropy loss is equivalent to maximizing log-likelihood
  • Calculate mutual information between features and a target to rank feature importance
  • Explain perplexity as the effective vocabulary size a language model chooses from

The Problem

You call CrossEntropyLoss() in every classification model you train. You see "perplexity" in every language model paper. KL divergence shows up in VAEs, distillation, and RLHF, anywhere two probability distributions need to be compared. None of that is a coincidence: all three come from the same handful of ideas.

Claude Shannon wrote those ideas down in 1948 to solve a communication problem: how do you measure the information carried by a signal, and how efficiently can you encode it? Training a neural network turns out to be the same problem in disguise. The model is trying to transmit the correct label through a noisy channel of learned weights, and the loss function is measuring how many bits get lost along the way.

This lesson builds entropy, cross-entropy, and KL divergence from scratch, in that order, so you can see exactly where each one comes from and why it works.

Warm-up0/3
1. A forecaster says there's a 99% chance of rain, and it rains. A different forecaster says there's only a 2% chance of snow, and it snows. Which forecast should feel more surprising when it comes true?Warm-up
Two forecast cards: forecast A gave a 99 percent chance of rain and it rained, forecast B gave a 2 percent chance of snow and it snowed, with a question mark asking which should feel more surprising.
2. If two events are independent, how do you get the probability that both happen?Warm-up
A coin flip with P of heads 0.5 and a die roll with P of rolling a 6 equal to 1/6, both feeding into a box asking for the probability that both happen.
3. For a probability p between 0 and 1, such as 0.5, what is the sign of log(p)?Warm-up
A probability p equals 0.5, between 0 and 1, feeding into log of p, with a question mark over the result, asking for its sign.

The Concept

Information Content (Surprise)

The information content of an event x with probability p(x) is I(x) = -log(p(x)): the less likely an event is, the more information you get when it actually happens.

I(x) = -log(p(x))

A coin landing heads carries almost no information. A lottery win carries a lot. Log base 2 gives you bits, natural log gives you nats: same quantity, different units.

Event              Probability    Surprise (bits)
Fair coin heads    0.5            1.0
Rolling a 6        0.167          2.58
1-in-1000 event    0.001          9.97
Certain event      1.0            0.0

A certain event carries zero information, because you already knew it would happen.

Entropy (Average Surprise)

Entropy measures the expected surprise across every outcome of a distribution: weight each event's surprise by how often it happens, then add them up.

H(P) = -sum( p(x) * log(p(x)) )  for all x

A fair coin has the maximum entropy possible for a binary variable, 1 bit. A coin biased 99% toward heads has only 0.08 bits, because you already know what's coming and each flip barely tells you anything new.

Fair coin:    H = -(0.5 * log2(0.5) + 0.5 * log2(0.5)) = 1.0 bit
Biased coin:  H = -(0.99 * log2(0.99) + 0.01 * log2(0.01)) = 0.08 bits

Analogy: think of entropy as how many good guesses a game of twenty questions needs, on average, to land on the answer. A fair coin needs exactly one good guess. A coin that lands heads 99% of the time barely needs a guess at all, you already know what's coming before you ask.

Entropy is the irreducible uncertainty in a distribution. You cannot compress a signal below it.

Cross-Entropy (The Loss Function You Use Every Day)

Cross-entropy measures the average surprise when you use distribution Q to encode events that actually come from distribution P.

H(P, Q) = -sum( p(x) * log(q(x)) )  for all x

P is the true distribution, the labels. Q is your model's predictions. If Q matches P perfectly, cross-entropy equals entropy; any mismatch makes it larger.

Analogy: picture paying a courier by weight, but using someone else's estimate of the package instead of the real scale reading. If their estimate matches the true weight, you pay the fair price, the entropy. If it's off, every shipment costs a little extra, and that extra is exactly what cross-entropy adds on top.

In classification, P is a one-hot vector: the true class has probability 1, everything else 0. That collapses cross-entropy down to:

H(P, Q) = -log(q(true_class))

That's the entire cross-entropy loss formula for classification: push the predicted probability of the correct class as close to 1 as you can.

KL Divergence (Distance Between Distributions)

KL divergence measures how much extra surprise you get from using Q instead of P.

D_KL(P || Q) = sum( p(x) * log(p(x) / q(x)) )  for all x
             = H(P, Q) - H(P)

Cross-entropy is entropy plus KL divergence, and since the entropy of the true distribution stays constant during training, minimizing cross-entropy and minimizing KL divergence are the same move: you're pushing your model's distribution toward the true one.

KL divergence is not symmetric, D_KL(P || Q) != D_KL(Q || P), so it doesn't qualify as a true distance metric.

Analogy: imagine navigating with a map that's slightly wrong. You still get there, but with extra turns and backtracking an accurate map wouldn't need. KL divergence is that overhead, measured in bits: the gap between the shortest path a correct model of the world gives you and the longer one you get by trusting a distribution that's slightly off.

Conditional Entropy

Conditional entropy H(Y|X) measures how much uncertainty about Y remains after you've observed X.

H(Y|X) = H(X,Y) - H(X)

Two extremes:

  • If X completely determines Y, H(Y|X) = 0. Knowing X eliminates all uncertainty about Y: temperature in Celsius versus temperature in Fahrenheit is a clean example.
  • If X tells you nothing about Y, H(Y|X) = H(Y). Knowing X does not reduce your uncertainty at all: a coin flip tells you nothing about tomorrow's weather.

Conditional entropy is always non-negative and never exceeds H(Y):

0 <= H(Y|X) <= H(Y)

Decision trees lean on exactly this conditional-entropy bound. At each split, the algorithm picks whichever feature X minimizes H(Y|X): the one that removes the most uncertainty about the label Y.

Joint Entropy

Joint entropy H(X,Y) is the entropy of X and Y treated as one combined outcome, over their joint distribution.

H(X,Y) = -sum sum p(x,y) * log(p(x,y))   for all x, y

Key property:

H(X,Y) <= H(X) + H(Y)

Equality holds only when X and Y are independent. Once they share any information, the joint entropy drops below the sum of the individual entropies, and the gap is exactly the mutual information.

Mermaid diagram

The relationships:

  • H(X,Y) = H(X) + H(Y|X) = H(Y) + H(X|Y)
  • I(X;Y) = H(X) - H(X|Y) = H(Y) - H(Y|X)
  • H(X,Y) = H(X) + H(Y) - I(X;Y)

Mutual Information

Mutual information measures how much knowing one variable tells you about another, and unlike KL divergence, it's symmetric: knowing X about Y tells you exactly as much as knowing Y about X.

I(X;Y) = H(X) - H(X|Y)
       = H(Y) - H(Y|X)
       = H(X) + H(Y) - H(X,Y)
       = sum sum p(x,y) * log(p(x,y) / (p(x) * p(y)))

If X and Y are independent, mutual information is zero: knowing one tells you nothing about the other. If they're perfectly correlated, it equals the entropy of either variable.

Properties:

  • I(X;Y) >= 0 always, since you never lose information by observing something.
  • I(X;Y) = 0 if and only if X and Y are independent.
  • I(X;Y) = I(Y;X): it's symmetric, unlike KL divergence.
  • I(X;X) = H(X): a variable shares all its information with itself.

Analogy: think of mutual information as how much a friend's restaurant opinion actually tells you. If their taste has nothing to do with yours, hearing it adds nothing, zero mutual information. If their taste always tracks yours exactly, their opinion tells you everything you'd have learned by trying the place yourself.

Mutual information for feature selection. High mutual information between a feature and the target means the feature is useful; low mutual information means it's noise. Mutual information gives you a principled way to rank features:

  1. For each feature X_i, compute I(X_i; Y) against the target Y.
  2. Rank features by MI score.
  3. Keep the top k.

This catches any relationship between a feature and the target: linear, nonlinear, monotonic, or not. Correlation only catches the linear ones; MI catches all of them.

MethodDetectsComputational costHandles categorical?
Pearson correlationLinear relationshipsO(n)No
Spearman correlationMonotonic relationshipsO(n log n)No
Mutual informationAny statistical dependencyO(n log n) with binningYes

Label Smoothing and Cross-Entropy

Standard classification uses hard targets, like [0, 0, 1, 0]: the true class gets probability 1, everything else gets 0. Label smoothing replaces that with a soft target:

soft_target = (1 - epsilon) * hard_target + epsilon / num_classes

With epsilon = 0.1 and 4 classes:

  • Hard target: [0, 0, 1, 0]
  • Soft target: [0.025, 0.025, 0.925, 0.025]

From an information theory angle, label smoothing raises the entropy of the target distribution. Hard one-hot targets have zero entropy: no uncertainty at all. Soft targets carry positive entropy instead.

Why this helps:

  • It keeps the model from driving logits to extreme values, since matching a one-hot target exactly under cross-entropy would need infinite logits.
  • It acts as regularization: the model can never claim 100% confidence.
  • It improves calibration, so predicted probabilities track true uncertainty more closely.
  • It shrinks the gap between training and inference behavior.

The cross-entropy loss with label smoothing becomes:

L = (1 - epsilon) * CE(hard_target, prediction) + epsilon * H_uniform(prediction)

The second term penalizes predictions that stray far from uniform, which works as direct regularization on confidence.

Why Cross-Entropy Is THE Classification Loss

Three perspectives, same conclusion.

Information theory view. Cross-entropy measures how many bits you waste by using your model's distribution instead of the true one. Minimize it and your model becomes the most efficient encoder of reality it can be.

Maximum likelihood view. For N training samples with true classes y_i:

Likelihood     = product( q(y_i) )
Log-likelihood = sum( log(q(y_i)) )
Negative log-likelihood = -sum( log(q(y_i)) )

That last line is cross-entropy loss. Minimizing cross-entropy is the same as maximizing the likelihood of the training data under your model.

Gradient view. The gradient of cross-entropy with respect to the logits is just (predicted - true) — clean, stable, and fast to compute, which is exactly why it pairs so well with softmax.

Bits vs Nats

The only difference is the log base.

log base 2   -> bits      (information theory tradition)
log base e   -> nats      (machine learning convention)
log base 10  -> hartleys  (rarely used)

1 nat = 1/ln(2) bits = 1.4427 bits. PyTorch and TensorFlow use natural log (nats) by default.

Perplexity

Perplexity is the exponential of cross-entropy: the effective number of equally likely choices the model is uncertain between at each step.

Perplexity = 2^H(P,Q)   (if using bits)
Perplexity = e^H(P,Q)   (if using nats)

A language model with perplexity 50 is, on average, as confused as if it had to pick uniformly from 50 possible next tokens. Lower is better.

Analogy: think of perplexity as a multiple-choice question with a variable number of options. A model with perplexity 4 is choosing among roughly 4 plausible next words, about as hard as a well-written quiz question. A model with perplexity 4000 might as well be guessing blind from the whole dictionary.

GPT-2 landed around perplexity 30 on common benchmarks. Modern models sit in the single digits for well-represented domains.

Check: The Concept0/34
1. What is the information content of an event with probability p?Define
A single die face showing 6, with its probability 0.167 labelled, and a question mark asking for its information content.
2. What does the entropy of a distribution measure?Define
Six equal bars for a fair die's faces 1 through 6, each marked 1/6, asking what the entropy of this distribution measures.
3. What is the cross-entropy loss commonly used for in neural networks?Define
A true one-hot label and a model's predicted distribution both feeding into CrossEntropyLoss, with a question mark asking what this is commonly used for.
4. What does KL divergence between P and Q measure?Define
Two bar charts over the same three outcomes a, b and c: P is 0.6, 0.3, 0.1 and Q is 0.2, 0.3, 0.5, asking what extra quantity results from using Q to encode events from P.
5. What does mutual information I(X;Y) measure?Define
Two overlapping circles, one labelled X for weather and one labelled Y for umbrella, with a question mark in the overlap, asking what mutual information I of X and Y measures about them.
6. What does softmax do to a vector of logits?Define
A flow of three boxes: raw logits 2.0, 1.0 and 0.1, then softmax of dot dot dot, then three question marks, asking what softmax does to the raw scores.
7. A language model has a perplexity of 50 on a test set. What does this mean?Define
A card reading perplexity equals 50 for a language model's test set score, with a question mark asking what this number means.
8. What is one bit of information?Define
A table of three log bases, 2, e and 10, each with a blank unit name to fill in, the log base 2 row highlighted, asking what exactly one bit of information is.
9. What is a nat?Define
The same table of three log bases, 2, e and 10, each with a blank unit name to fill in, the log base e row highlighted, asking what a nat is.
10. For one-hot labels, how does negative log-likelihood relate to cross-entropy loss?Define
Two formulas, negative log-likelihood and cross-entropy loss for one-hot labels, with a question mark between NLL and cross-entropy loss asking how they relate.
11. What does conditional entropy H(Y|X) measure?Define
A box labelled observe X, with an arrow to a box labelled uncertainty about Y, H of Y given X equals question mark, asking what conditional entropy H of Y given X measures.
12. What is joint entropy H(X,Y)?Define
Boxes for X and Y, each with its own outcomes, both arrows merging into a single box labelled X, Y treated as one outcome, asking what joint entropy H of X, Y is.
13. In decision tree construction, why does the algorithm pick the feature X that minimizes conditional entropy H(Y|X) at each split?Explain
A decision tree root splitting into two candidate features, split on X1 and split on X2, each with its own conditional entropy left as a question mark, asking why the algorithm picks the feature that minimizes H of Y given X.
14. How does joint entropy H(X,Y) compare with H(X) + H(Y)?Explain
The quantity H of X, Y next to H of X plus H of Y, with an unresolved question-mark relation between them, asking how they compare.
15. Why is minimizing cross-entropy equivalent to minimizing KL divergence during training?Explain
Two training snapshots, epoch 1 with the model far from the true labels and epoch 50 with it close, next to the formula H of P, Q equals H of P plus KL of P given Q, with a question mark asking why minimizing the first also minimizes the second.
16. Maximizing the likelihood of the training data is the same as minimizing which quantity?Explain
A flow from likelihood as the product of q of y_i, to log-likelihood as the sum of log q of y_i, to a box asking what quantity maximizing this is the same as minimizing.
17. Is D_KL(P || Q) always equal to D_KL(Q || P)?Explain
Two distributions P and Q over the same two outcomes, with D_KL of P given Q and D_KL of Q given P both left as question marks, asking whether they are always equal.
18. How does mutual information differ from Pearson correlation for feature selection?Explain
A table of three feature-ranking methods, Pearson correlation, Spearman correlation and mutual information, with cost and categorical-handling filled in but the Detects column left as question marks, asking how mutual information differs from Pearson correlation.
19. What does label smoothing do to the target distribution used in cross-entropy loss?Explain
A hard one-hot target, 0, 0, 1, 0, feeding through label smoothing with epsilon 0.1, with the resulting soft target left as a question mark, asking what label smoothing does to the target distribution.
20. Why does a certain event (probability 1) carry zero information?Explain
A box reading P of event equals 1.0, a certain outcome, with a question mark asking why it carries zero information.
21. Why does a fair coin have higher entropy than a coin biased 99% toward heads?Explain
Two coins, a fair coin at 0.5 and 0.5 with entropy 1.00 bits, and a biased coin at 0.99 and 0.01 with entropy 0.08 bits, asking why the fair coin's entropy is higher.
22. What is the cross-entropy H(P,Q) when the model Q matches the true distribution P exactly?Explain
Two identical, unlabelled bar charts side by side, P and Q, shown as exactly the same shape, with H of P, Q left as a question mark.
23. Why does cross-entropy collapse to -log(q(true_class)) for classification?Explain
A one-hot label vector 0, 0, 1, 0, next to the general cross-entropy sum, asking why it collapses to just negative log of q of the true class.
24. Why can perplexity be read as an effective number of equally likely choices?Explain
The formula perplexity equals exponential of H of P, Q, with a question mark, asking why this can be read as an effective number of equally likely choices.
25. With epsilon = 0.1 and 4 classes, what is the third entry of the smoothed target for the hard target [0, 0, 1, 0]?Apply
The hard target 0, 0, 1, 0 smoothed with epsilon 0.1 and 4 classes, with entries 1, 2 and 4 already shown as 0.025 each, asking for entry 3.
26. PyTorch reports a cross-entropy loss of 0.693 nats. About how many bits is that?Apply
A reported cross-entropy loss of 0.693 nats, with the lesson's own conversion of 1 nat equal to 1.4427 bits given, and the equivalent number of bits left as a question mark.
27. Two models are scored on the same validation set, where the true labels are essentially deterministic (entropy near zero). Model A has a cross-entropy loss of 0.05 nats. Model B has a cross-entropy loss of 3.2 nats. What does Model B's score tell you?Analyze
Two models scored on labels with entropy close to zero, Model A at 0.05 nats cross-entropy and Model B at 3.2 nats, with a question mark asking what Model B's score tells you.
28. A teammate reports a model's cross-entropy that is lower than the entropy of the true distribution, with both measured in the same units. What should you suspect?Analyze
A report showing the true labels' entropy at 0.60 nats and a model's reported cross-entropy at 0.30 nats, lower than the entropy, with a question mark asking what should be suspected.
29. A feature has a Pearson correlation near 0 with the target but a high mutual information score. What does this most likely mean?Analyze
A scatter plot shaped like a U, feature x against target y, with a real computed Pearson correlation near zero, asking what this combined with a high mutual information score most likely means.
Scatter and correlation computed with numpy, seed 7.
30. A distillation loss is written kl_div(teacher, student). A teammate swaps the arguments, assuming it just flips a sign, and training changes. Why?Analyze
Two lines of code, kl_div of teacher then student, and below it the swapped call kl_div of student then teacher, with a question mark asking why training changes after the swap.
31. A model trained with label smoothing (epsilon = 0.1) never reaches zero training loss, even on easy examples. Is something broken?Analyze
An illustrative training loss curve that drops then flattens above zero, with a dashed line marking where it levels off, for a model trained with label smoothing epsilon 0.1, asking whether never reaching zero loss means something is broken.
Illustrative curve shape.
32. You must rank 200 features, a mix of numeric and categorical, whose relationships to the target may be nonlinear. Which method fits?Design
The full comparison table of Pearson correlation, Spearman correlation and mutual information, with their detection power, cost and categorical handling all filled in, for a task of ranking 200 mixed numeric and categorical features with possibly nonlinear relationships to the target.
33. Your classifier is overconfident and its logits keep growing during training. Which change fits?Design
An illustrative curve of a classifier's logit magnitude climbing over training steps, for an overconfident model, asking which change fits this situation.
Illustrative curve shape.
34. You want a loss that measures how far a student model's output distribution is from a teacher's. Which choice fits?Design
A teacher's output distribution and a student's output distribution over the same three outcomes, drawn with different shapes, asking which loss measures how far the student's distribution is from the teacher's.

Build It

Step 1: Information content and entropy

python
import math
 
def information_content(p, base=2):
    if p <= 0 or p > 1:
        return float('inf') if p <= 0 else 0.0
    return -math.log(p) / math.log(base)
 
def entropy(probs, base=2):
    return sum(
        p * information_content(p, base)
        for p in probs if p > 0
    )
 
fair_coin = [0.5, 0.5]
biased_coin = [0.99, 0.01]
fair_die = [1/6] * 6
 
print(f"Fair coin entropy:   {entropy(fair_coin):.4f} bits")
print(f"Biased coin entropy: {entropy(biased_coin):.4f} bits")
print(f"Fair die entropy:    {entropy(fair_die):.4f} bits")

Step 2: Cross-entropy and KL divergence

python
def cross_entropy(p, q, base=2):
    total = 0.0
    for pi, qi in zip(p, q):
        if pi > 0:
            if qi <= 0:
                return float('inf')
            total += pi * (-math.log(qi) / math.log(base))
    return total
 
def kl_divergence(p, q, base=2):
    return cross_entropy(p, q, base) - entropy(p, base)
 
true_dist = [0.7, 0.2, 0.1]
good_model = [0.6, 0.25, 0.15]
bad_model = [0.1, 0.1, 0.8]
 
print(f"Entropy of true dist:     {entropy(true_dist):.4f} bits")
print(f"CE (good model):          {cross_entropy(true_dist, good_model):.4f} bits")
print(f"CE (bad model):           {cross_entropy(true_dist, bad_model):.4f} bits")
print(f"KL divergence (good):     {kl_divergence(true_dist, good_model):.4f} bits")
print(f"KL divergence (bad):      {kl_divergence(true_dist, bad_model):.4f} bits")

Step 3: Cross-entropy as classification loss

python
def softmax(logits):
    max_logit = max(logits)
    exps = [math.exp(z - max_logit) for z in logits]
    total = sum(exps)
    return [e / total for e in exps]
 
def cross_entropy_loss(true_class, logits):
    probs = softmax(logits)
    return -math.log(probs[true_class])
 
logits = [2.0, 1.0, 0.1]
true_class = 0
 
probs = softmax(logits)
loss = cross_entropy_loss(true_class, logits)
 
print(f"Logits:      {logits}")
print(f"Softmax:     {[f'{p:.4f}' for p in probs]}")
print(f"True class:  {true_class}")
print(f"Loss:        {loss:.4f} nats")
print(f"Perplexity:  {math.exp(loss):.2f}")

Step 4: Cross-entropy equals negative log-likelihood

python
import random
 
random.seed(42)
 
n_samples = 1000
n_classes = 3
true_labels = [random.randint(0, n_classes - 1) for _ in range(n_samples)]
model_logits = [[random.gauss(0, 1) for _ in range(n_classes)] for _ in range(n_samples)]
 
ce_loss = sum(
    cross_entropy_loss(label, logits)
    for label, logits in zip(true_labels, model_logits)
) / n_samples
 
nll = -sum(
    math.log(softmax(logits)[label])
    for label, logits in zip(true_labels, model_logits)
) / n_samples
 
print(f"Cross-entropy loss:      {ce_loss:.6f}")
print(f"Negative log-likelihood: {nll:.6f}")
print(f"Difference:              {abs(ce_loss - nll):.2e}")

Step 5: Mutual information

python
def mutual_information(joint_probs, base=2):
    rows = len(joint_probs)
    cols = len(joint_probs[0])
 
    margin_x = [sum(joint_probs[i][j] for j in range(cols)) for i in range(rows)]
    margin_y = [sum(joint_probs[i][j] for i in range(rows)) for j in range(cols)]
 
    mi = 0.0
    for i in range(rows):
        for j in range(cols):
            pxy = joint_probs[i][j]
            if pxy > 0:
                mi += pxy * math.log(pxy / (margin_x[i] * margin_y[j])) / math.log(base)
    return mi
 
independent = [[0.25, 0.25], [0.25, 0.25]]
dependent = [[0.45, 0.05], [0.05, 0.45]]
 
print(f"MI (independent): {mutual_information(independent):.4f} bits")
print(f"MI (dependent):   {mutual_information(dependent):.4f} bits")
Check: Build It0/7
1. The Step 1 entropy function skips probabilities that are 0. What does entropy([0.5, 0.5, 0.0]) return?Apply
The entropy function called on the list 0.5, 0.5, 0.0, with a note that the function only sums over probabilities greater than zero, asking for the result.
2. In the Step 2 code, what does cross_entropy(p, q) return when some p_i > 0 has q_i = 0?Apply
The cross_entropy function with one position where p_i is greater than zero but q_i equals zero, asking what the function returns.
3. In Step 3, the logits are [2.0, 1.0, 0.1] and the true class is 0. Which value is closest to the printed loss?Apply
The logits 2.0, 1.0 and 0.1 with true class 0, and the loss formula negative log of softmax of logits at true class, left as a question mark.
4. In Step 3, the loss is about 0.417 nats. Which value is closest to the printed perplexity?Apply
The Step 3 loss of 0.417 nats, with perplexity equal to exponential of the loss left as a question mark.
5. In Step 4, what is the printed difference between the cross-entropy loss and the negative log-likelihood?Apply
Two formulas computed over the same 1000 samples, the mean cross-entropy loss and the mean negative log-likelihood, with a question mark asking for the difference between them.
6. In Step 5, what does mutual_information(dependent) return for [[0.45, 0.05], [0.05, 0.45]]?Apply
A joint table with cells 0.45, 0.05, 0.05 and 0.45 for two binary variables, asking for the result of mutual_information on this table.
7. Step 3's softmax subtracts the largest logit before exponentiating. What does softmax([1001.0, 1000.0]) return?Apply
The call softmax of 1001.0 and 1000.0, with the shift step shown giving shifted logits 0 and -1, and the result of softmax on those shifted logits left as a question mark.

Use It

Here's the same math with NumPy, the way you'll actually use it in practice:

python
import numpy as np
 
def np_entropy(p):
    p = np.asarray(p, dtype=float)
    mask = p > 0
    result = np.zeros_like(p)
    result[mask] = p[mask] * np.log(p[mask])
    return -result.sum()
 
def np_cross_entropy(p, q):
    p, q = np.asarray(p, dtype=float), np.asarray(q, dtype=float)
    mask = p > 0
    return -(p[mask] * np.log(q[mask])).sum()
 
def np_kl_divergence(p, q):
    return np_cross_entropy(p, q) - np_entropy(p)
 
true = np.array([0.7, 0.2, 0.1])
pred = np.array([0.6, 0.25, 0.15])
print(f"Entropy:    {np_entropy(true):.4f} nats")
print(f"Cross-ent:  {np_cross_entropy(true, pred):.4f} nats")
print(f"KL div:     {np_kl_divergence(true, pred):.4f} nats")

You just built, by hand, what torch.nn.CrossEntropyLoss() does internally. That's why the loss curve drops during training: your model's predicted distribution is closing the gap on the true distribution, measured in nats of wasted information.

Check: Use It0/1
1. A model's loss comes from PyTorch's CrossEntropyLoss, and a teammate reports perplexity as 2**loss. What is wrong?Analyze
Two lines of code, a loss from PyTorch's CrossEntropyLoss and then perplexity computed as 2 to the power of that loss, with a note that PyTorch's loss uses the natural log, and a question mark asking what is wrong with the calculation.
Author's Note

The first time KL divergence actually bit me was in a distillation project, not a math class. I'd written kl_div(teacher_probs, student_probs) and assumed swapping the arguments would just flip a sign, the way subtraction does. It doesn't. D_KL(P || Q) and D_KL(Q || P) are different loss surfaces with different failure modes: the forward direction pushes the student to cover every mode the teacher puts probability mass on, even ones it can't fit well, while the reverse direction lets the student lock onto a single mode and ignore the rest. Get the direction backward and your student model won't crash — it'll just quietly learn the wrong lesson, and you won't notice until someone asks it a question outside the mode it picked. If you remember one thing about KL divergence a year from now, remember that direction is not a detail you can skim past.

Exercises

  1. Compute the entropy of the English alphabet assuming uniform distribution (26 letters). Then estimate it using actual letter frequencies. Which is higher and why?

  2. A model outputs logits [5.0, 2.0, 0.5] for a sample with true class 1. Compute the cross-entropy loss by hand, then verify with your cross_entropy_loss function. What logits would give zero loss?

  3. Show that KL divergence is not symmetric. Pick two distributions P and Q and compute D_KL(P || Q) and D_KL(Q || P). Explain why they differ.

  4. Build a function that computes perplexity for a sequence of token predictions. Given a list of (true_token_index, predicted_logits) pairs, return the perplexity of the sequence.

Key Terms

TermWhat people sayWhat it actually means
Information content"Surprise"The number of bits (or nats) needed to encode an event: -log(p)
Entropy"Randomness"The average surprise across all outcomes of a distribution. Measures irreducible uncertainty.
Cross-entropy"The loss function"Average surprise when using model distribution Q to encode events from true distribution P.
KL divergence"Distance between distributions"Extra bits wasted by using Q instead of P. Equals cross-entropy minus entropy. Not symmetric.
Mutual information"How related are X and Y"Reduction in uncertainty about X from knowing Y. Zero means independent.
Softmax"Turn logits into probabilities"Exponentiate and normalize. Maps any real-valued vector to a valid probability distribution.
Perplexity"How confused the model is"Exponential of cross-entropy. The effective vocabulary size the model is choosing from at each step.
Bits"Shannon's unit"Information measured with log base 2. One bit resolves one fair coin flip.
Nats"ML's unit"Information measured with natural log. Used by PyTorch and TensorFlow by default.
Negative log-likelihood"NLL loss"Identical to cross-entropy loss for one-hot labels. Minimizing it maximizes the probability of correct predictions.

Further Reading