Exponentials and logarithms
Growth, decay, and why logs turn products into sums.
Create a free account Try part of it here
Why it matters
Some things grow by building on themselves. A savings account earns interest on its interest. A shared post reaches people who share it again. That kind of growth is called exponential, and it shows up inside AI too, in the scores that softmax turns into probabilities. Logarithms ("logs") run it backwards. They have one property that language models rely on: they turn multiplying into adding. A model's training loss is a log. Perplexity, a common score for language models, is an exponential. And any probability over a long piece of text is worked out in logs, because the raw number is too small for a computer to store.
What you'll be able to do
- Model compounding growth and decay with exponentials
- Use logarithms as the inverse: 'what power gives this number?'
- Apply the log rules, especially log of a product = sum of logs
- Explain why models add log-probabilities instead of multiplying probabilities
What it covers
- Growth that builds on itself
- Logarithms answer "what power?"
- How long until it doubles?
- Worked example: when does the list double?
- The rule that matters most: products become sums
- Going back: exponentials undo logs
Growth that builds on itself
Say your email list has 1,000 subscribers and grows 5% a month. After one month you have 1,000 × 1.05 = 1,050. After two months you grow the new total by 5%: 1,050 × 1.05 = 1,102.5. Each month you multiply by 1.05 again.
So the growth gets bigger every month, because 5% of a bigger list is more people. That is exponential growth. The increase depends on how big you already are.
Here is the rule written as a formula. is the number of months. (say "N nought") is the size you start with. is the size after months.
In plain words: start with your list, then multiply by 1.05 once for every month that passes. The small raised means "multiply by 1.05, times".
A worked example with small numbers: 100 people growing 10% a month for 2 months gives 100 × 1.1 × 1.1 = 121.
If the multiplier is below 1, the number shrinks instead. Multiplying by 0.9 each month means you lose 10% each month. That is exponential decay, like interest in an old campaign fading away.
The code below grows a list of 10,000 at 5% a month and prints it every 6 months for 3 years. In Python, ** means "raise to the power", so 1.05 ** months is 1.05 multiplied by itself months times.
import numpy as np months = np.arange(0, 37, 6) print("months:", months) print("list: ", np.round(10000 * 1.05 ** months).astype(int))
The list grows by about 3,400 in the first six months, and by about 14,700 in the last six. Same rate, bigger jumps.
The special number e
One number appears as the base far more than any other. It is called , and it is about 2.718. In NumPy, (e raised to the power ) is written np.exp(x). You will see it inside sigmoid and softmax later in the course. You don't need to know why it is special to use it.
Go deeper Why e?
Imagine interest that is added not once a year, or once a day, but every instant. That is called continuous compounding, and is the number it produces. It has a tidy property too: the graph of is exactly as steep at each point as its own height there. That makes the calculus around it very clean, which is why AI formulas use it.
Show the answer
242
200 × 1.1 = 220 after one month, then 220 × 1.1 = 242. The second month grows the new total, not the original 200.
Logarithms answer "what power?"
Start with 1 and keep doubling: 2, 4, 8. How many doublings did it take to reach 8? Three. That count is a logarithm. It answers the question "how many times do I multiply to get here?"
In symbols, the log has a small number underneath called the base: the number you keep multiplying by. reads "log base 2 of 8". It is the power you raise 2 to in order to get 8.
In plain words: because 2 × 2 × 2 = 8. The log is the number of times you multiply the base. (say "L N", the natural log) is the log whose base is .
Each base has its own NumPy function. np.log is the natural log. np.log2 and np.log10 use bases 2 and 10.
import numpy as np print(np.log2(8), np.log10(1_000_000), np.log(np.e))
This prints 3.0 6.0 1.0. Three 2s make 8. Six 10s make a million. And one e makes e.
Notice how slowly logs grow. A million turns into 6. That is why logs are used for lopsided data, like spend per customer or follower counts, where a few huge values sit far above the rest.
import math print(round(math.log(1000, 10)))
Show the answer
3
A logarithm answers: what power of 10 gives 1,000? The answer is 3.
eˣ and ln x are mirror images across the diagonal line: each one undoes the other. Notice eˣ is always above zero, and ln x only exists for x above zero.
Show the answer
3.0
10 × 10 × 10 = 1000. You multiply three 10s, so the log base 10 is 3.
How long until it doubles?
Logs let you run growth backwards. Your list grows 5% a month. How many months until it doubles? You need the where . Taking the log of both sides brings down where you can reach it:
In plain words: divide the log of 2 (the "doubling") by the log of 1.05 (one month of growth). The answer is how many months of growth fit into one doubling.
With small numbers: is about 0.693 and is about 0.0488. Divide them and you get about 14.2. The worked example below checks it in code.
Worked example: when does the list double?
Your email list grows 5% a month. Find the doubling time with logs, then check it by growing 1,000 subscribers for 14 and 15 months.
import math rate = 0.05 t = math.log(2) / math.log(1 + rate) print(round(t, 1)) print(round(1000 * 1.05 ** 14), round(1000 * 1.05 ** 15))
The log formula says about 14.2 months. The check agrees: after 14 months 1,000 has grown to 1,980, just short of double. After 15 months it is 2,079, just past it. math.log is Python's built-in natural log, the same as np.log for a single number.
The rule that matters most: products become sums
Logs follow three rules. In them, is any positive number. is another positive number. is any power.
In plain words: the log of a product is the sum of the logs. The log of a division is the difference of the logs. And the log of a power is the power times the log.
With small numbers, is about 0.693 and is about 1.099. Add them and you get 1.792, which is . The code checks all three rules with a = 2, b = 3 and a power of 4.
import math a, b = 2, 3 print(round(math.log(a * b), 4), round(math.log(a) + math.log(b), 4)) print(round(math.log(a / b), 4), round(math.log(a) - math.log(b), 4)) print(round(math.log(a ** 4), 4), round(4 * math.log(a), 4))
Each line prints two equal numbers: 1.7918, then -0.4055, then 2.7726.
Why language models need the first rule
A language model gives each word in a sentence a probability. The chance of the whole sentence is all those probabilities multiplied together. They are small numbers, so the product shrinks fast.
Think of a calculator with a limited screen. Show it a number with too many zeros after the decimal point and it gives up and shows 0. A computer does the same. When a number gets too small to store, it underflows: it becomes exactly zero, and the information is gone.
Adding logs avoids this. Each small probability turns into an ordinary negative number, and you add those up instead.
import numpy as np probs = np.full(1000, 0.01) # 1,000 words, each given probability 0.01 print("product:", np.prod(probs)) # underflows to 0.0 print("sum of logs:", np.sum(np.log(probs))) print("as a power of 10:", np.sum(np.log10(probs)))
The product prints 0.0. The sum of logs is about −4605.17, a normal number to store. The last line says the true product is : a 1 that sits 2,000 places after the decimal point. A computer's usual floor is roughly , so the product drops far below it. The log version keeps all the information. That is why models report log-probabilities, and why the standard training loss is a negative log (you'll meet it in the cross-entropy lesson).
Show the answer
Multiplying many small probabilities underflows to zero; adding their logs doesn't
ln(ab) = ln a + ln b, so the sum of logs holds the same information as the product, in a range a computer can store.
Going back: exponentials undo logs
A log and an exponential cancel each other out, like walking 10 steps forward and 10 steps back.
In plain words: take the log of a number, raise to that result, and you are back where you started.
For example, is about 1.9459. Raise to 1.9459 and you get 7 again.
import math x = 7 print(round(math.log(x), 4)) print(round(math.exp(math.log(x)), 6))
This prints 1.9459 and then 7.0. So you can do all the arithmetic in "log land", where nothing underflows, and step back with exp only at the end. Perplexity, a score you'll meet in Phase 5, works this way: it is the exponential of an average negative log-probability.
Go deeper A tiny perplexity example
Suppose a model gives every word in a text a probability of 0.25. The natural log of 0.25 is about −1.386, so the average negative log-probability is 1.386. Raise to 1.386 and you get about 4. A perplexity of 4 means the model is as unsure as if it were picking between 4 equally likely words each time.
For marketers: when a metric spans a huge range (spend per customer, page views per URL), plot it on a log scale or analyze
np.log(value). Percentage changes like "+20%" become steps of the same size, and one giant customer stops squashing the rest of the chart flat.
Show the answer
np.exp(-6.9)
exp undoes ln. np.exp(-6.9) is about 0.001. np.log(-6.9) gives nan ("not a number"), because logs only exist for numbers above zero.
Practice what you just read
- 6 code examples you can edit and run
- a practice exercise that checks your code
- a 5-question quiz
- 5 review cards for spaced repetition
Try a quiz question
ln(a) = 2 and ln(b) = 3. What is ln(ab)?