Perplexity › Natural Log vs Log Base 2
Language AI HandbookAll chapters Perplexity › Natural Log vs Log Base 2One section · Sections in this chapter7 / 17 ↓
Reading tools Definitions & inline links
Choose your expertise level to adjust how many terms are explained. Beginners see more tooltips, experts see fewer to maintain reading flow. Hover over underlined terms for instant definitions.
Article links
Make inline references clickable
A practical note on conventions: perplexity can be computed using either (base-2 logarithm) or (natural logarithm), and this choice is more common than you might expect from reading the literature.
When using , cross-entropy is measured in bits and perplexity equals . When using , cross-entropy is measured in nats (natural units), and the corresponding "perplexity" equals .
The numerical values are different:
where:
- : cross-entropy measured in bits (using )
- : cross-entropy measured in nats (using )
Most academic papers and machine learning libraries report loss values using natural logarithm because has nicer mathematical properties (its derivative is simply ). This means the "loss" that gradient descent minimizes is typically cross-entropy in nats, not bits.
To convert between the two:
The perplexity value itself is the same regardless of which log base you use for the intermediate cross-entropy calculation, because . What changes is only how you express the intermediate cross-entropy value. Most practitioners report perplexity as a single number without worrying about this distinction, since the final perplexity value is unambiguous.
def perplexity_from_nats(test_tokens, model_nat_log_prob):
"""
Calculate perplexity using natural log (nats).
Common in deep learning frameworks like PyTorch.
Args:
test_tokens: List of tokens from test corpus
model_nat_log_prob: Function returning ln P(token | context)
"""
log_prob_sum = 0.0
count = 0
for i, token in enumerate(test_tokens):
log_p = model_nat_log_prob(token, i, test_tokens)
if log_p == float("-inf"):
return float("inf")
log_prob_sum += log_p
count += 1
# Cross-entropy in nats
cross_ent_nats = -log_prob_sum / count
# Convert to perplexity: e^cross_entropy_nats = 2^cross_entropy_bits
return np.exp(cross_ent_nats)
def unigram_nat_log_prob(token, position, tokens):
"""Return ln P(token) for unigram model with smoothing."""
count = word_counts.get(token, 0)
vocab_size = len(word_counts) + 1
prob = (count + 1) / (total_words + vocab_size)
return np.log(prob) # Natural logPerplexity computation with different log bases: -------------------------------------------------- Using log2 (bits): PP = 7.3068 Using ln (nats): PP = 7.3068 Difference: 0.000000 Both methods give identical perplexity values. The intermediate cross-entropy differs in units (bits vs nats), but the final perplexity is the same.
This confirms that the choice of log base is a matter of convention: the final perplexity value is invariant. In practice, when you see a model's "loss" of 3.5 in a deep learning framework, that's typically cross-entropy in nats. To convert to perplexity, you compute , meaning the model's effective branching factor is about 33 choices per word.