Type at least 2 letters. Enter opens the first result, Esc closes.

    Start here: notation and Python · Lesson 5 · Functions you meet in ML

    From scores to probabilities: sigmoid, softmax and log-sum-exp

    Intermediate 55 min 4 interactive figures 4 videos Colab notebook

    Before this lesson: lesson 04 (exp, log and the log rules), lesson 02 (∑\sum, max and argmax) and lesson 03 (arrays, axis, broadcasting). Time: about 55 minutes, plus the notebook.


    Why this matters #

    Almost every classifier ends with these functions. Logistic regression is σ(w⊤x+b)\sigma(w^\top x + b). An image classifier or a language model ends with a softmax over its classes or its vocabulary, and is trained with the cross-entropy loss LSE⁡(z)−zy\operatorname{LSE}(z) - z_y. Attention in a transformer turns similarity scores into weights with a softmax. When a chatbot "samples with temperature 0.7", it divides the logits by 0.7 before the softmax. The stable formulas of this lesson are inside torch.nn.CrossEntropyLoss, torch.logsumexp and scipy.special.logsumexp; when you write your own loss, you need them too.

    1. Predict first #

    2. The picture #

    One score, one probability: the sigmoid. The sigmoid (also called the logistic function) is

    σ(z)=11+e−z.\sigma(z) = \frac{1}{1 + e^{-z}}.

    Read the formula from the inside. For large positive zz, e−ze^{-z} is close to 0, so σ(z)\sigma(z) is close to 1. For large negative zz, e−ze^{-z} is huge, so σ(z)\sigma(z) is close to 0. At z=0z = 0, σ(0)=1/(1+1)=1/2\sigma(0) = 1/(1 + 1) = 1/2. The graph is an S-shaped curve from 0 to 1. In a model, the score is often z=wx+bz = wx + b: the weight ww sets how steep the S is, and the curve crosses 1/21/2 where wx+b=0wx + b = 0, at x=−b/wx = -b/w.

    Interactive figure: loading…

    Move ww and bb, and drag the blue point. The orange curve is p(x)=σ(wx+b)p(x) = \sigma(wx + b). The yellow dot is the centre x=−b/wx = -b/w, where p=1/2p = 1/2; the aqua line is the tangent there, with slope w/4w/4. Predict first: what does w<0w < 0 do? Then move the point far to one side: the curve is flat there and its slope is almost 0 (a saturation warning appears).

    Many scores, one probability vector: the softmax. For nn classes with logits z=(z1,…,zn)z = (z_1, \dots, z_n), the softmax is

    softmax⁡(z)k=ezk∑j=1nezj,k=1,…,n.\operatorname{softmax}(z)_k = \frac{e^{z_k}}{\sum_{j=1}^{n} e^{z_j}}, \qquad k = 1, \dots, n.

    Two steps: exponentiate (every ezke^{z_k} is positive, and a larger zkz_k gives a larger ezke^{z_k}), then normalize (divide by the sum, so the entries add up to 1). A temperature T>0T > 0 divides the logits first: softmax⁡(z/T)\operatorname{softmax}(z / T).

    Interactive figure: loading…

    Predict, then move. The orange bars are softmax⁡((z+c)/T)\operatorname{softmax}((z + c)/T) for the four logits z1,…,z4z_1, \dots, z_4. First move the slider "add cc to all": the logits change, the bars do not. Then make TT small (the bars become one-hot) and large (the bars become equal). Try "all negative": softmax works, but the naive ratio zk/∑jzjz_k / \sum_j z_j below the bars gives negative "probabilities".

    Quick check

    σ(2)≈0.881\sigma(2) \approx 0.881. What is σ(−2)\sigma(-2)?

    Quick check

    The logits are z=(1,3,2)z = (1, 3, 2). What does softmax⁡(z/T)\operatorname{softmax}(z / T) approach as the temperature TT goes to 0?

    3. Definitions and main results #

    3.1 The sigmoid and the logit #

    Properties of σ(z)=1/(1+e−z)\sigma(z) = 1/(1 + e^{-z}).

    1. Range (0,1)(0, 1). e−z>0e^{-z} > 0, so the denominator is larger than 1: 0<σ(z)<10 < \sigma(z) < 1. The values 0 and 1 are never reached; they are limits as z→−∞z \to -\infty and z→+∞z \to +\infty.
    2. Increasing. When zz grows, e−ze^{-z} shrinks, the denominator shrinks, and σ(z)\sigma(z) grows.
    3. Symmetry: σ(−z)=1−σ(z)\sigma(-z) = 1 - \sigma(z). Proof. 1−σ(z)=1+e−z−11+e−z=e−z1+e−z1 - \sigma(z) = \dfrac{1 + e^{-z} - 1}{1 + e^{-z}} = \dfrac{e^{-z}}{1 + e^{-z}}. Multiply the numerator and the denominator by eze^{z}: 1ez+1=σ(−z)\dfrac{1}{e^{z} + 1} = \sigma(-z). ■\blacksquare
    4. Another form: σ(z)=ez1+ez\sigma(z) = \dfrac{e^{z}}{1 + e^{z}} (multiply the numerator and the denominator by eze^z).

    The inverse of the sigmoid is the logit. For a probability p∈(0,1)p \in (0, 1), the odds are p/(1−p)p / (1 - p) (for example, p=0.8p = 0.8 gives odds 4, "4 to 1"). The logit is the log of the odds:

    logit⁡(p)=log⁡p1−p.\operatorname{logit}(p) = \log \frac{p}{1 - p}.

    Why it inverts σ\sigma. Let p=σ(z)=1/(1+e−z)p = \sigma(z) = 1/(1 + e^{-z}).

    1. Take the reciprocal: 1/p=1+e−z1/p = 1 + e^{-z}, so e−z=(1−p)/pe^{-z} = (1 - p)/p.
    2. Take the log: −z=log⁡1−pp-z = \log\frac{1 - p}{p}, so z=log⁡p1−pz = \log\frac{p}{1 - p}. ■\blacksquare

    So the score zz of a sigmoid model is exactly the log-odds of its probability. Example: logit⁡(0.8)=log⁡4≈1.386\operatorname{logit}(0.8) = \log 4 \approx 1.386, and σ(1.386)≈0.8\sigma(1.386) \approx 0.8.

    Naming. "Logit" is a function of a probability. In deep learning, logits (plural) means the raw scores that go into a sigmoid or a softmax. For a sigmoid the two meanings agree; for a softmax, the logits are log-probabilities up to one shared constant (section 3.5).

    Slope of the sigmoid. The slope (derivative) of σ\sigma at zz is

    σ′(z)=σ(z)(1−σ(z)).\sigma'(z) = \sigma(z)\big(1 - \sigma(z)\big).

    We use this formula here without proof; lesson 07 checks it. Since s(1−s)=14−(s−12)2s(1 - s) = \tfrac14 - (s - \tfrac12)^2, the slope is at most 1/41/4, reached at z=0z = 0. For large ∣z∣|z| the slope is tiny: σ′(5)≈0.0066\sigma'(5) \approx 0.0066, σ′(10)≈0.000045\sigma'(10) \approx 0.000045. This flatness is called saturation; it is one cause of vanishing gradients in deep networks. For p(x)=σ(wx+b)p(x) = \sigma(wx + b) the slope at the centre x=−b/wx = -b/w is w⋅14=w/4w \cdot \tfrac14 = w/4 (the chain rule, lesson 07).

    Logistic regression in one paragraph. For inputs x∈Rnx \in \R^n, logistic regression models P(y=1∣x)=σ(w⊤x+b)P(y = 1 \mid x) = \sigma(w^\top x + b). It predicts class 1 when this probability is at least 1/21/2, that is, when w⊤x+b≥0w^\top x + b \ge 0. So the boundary between the classes is the flat set w⊤x+b=0w^\top x + b = 0 (a line in R2\R^2, a plane in R3\R^3), and w⊤x+bw^\top x + b is the log-odds of class 1.

    3.2 The softmax #

    Properties. For any z∈Rnz \in \R^n, p=softmax⁡(z)p = \operatorname{softmax}(z) satisfies:

    1. pk>0p_k > 0 for every kk (an exponential is positive, and so is a sum of them);
    2. ∑kpk=∑kezk/∑jezj=1\sum_k p_k = \sum_k e^{z_k} / \sum_j e^{z_j} = 1;
    3. order is kept: zi>zjz_i > z_j implies pi>pjp_i > p_j (because eze^z is increasing and all pkp_k share one denominator). So arg⁡max⁡kpk=arg⁡max⁡kzk\arg\max_k p_k = \arg\max_k z_k.

    Why the exponential? The simpler idea "divide by the sum", zk/∑jzjz_k / \sum_j z_j, fails:

    • with z=(−1,2)z = (-1, 2) it gives (−1,2)(-1, 2): a negative "probability" and one larger than 1;
    • with z=(1,−1)z = (1, -1) the sum is 0: division by zero;
    • it changes when you add the same number to every score.

    The exponential makes every score positive, keeps the order, and turns differences of scores into ratios of probabilities: pi/pj=ezi−zjp_i / p_j = e^{z_i - z_j}.

    Theorem (shift invariance). For every real number cc, softmax⁡(z+c1)=softmax⁡(z)\operatorname{softmax}(z + c\mathbf{1}) = \operatorname{softmax}(z), where z+c1=(z1+c,…,zn+c)z + c\mathbf 1 = (z_1 + c, \dots, z_n + c).

    Proof.

    1. By the rule ea+b=eaebe^{a + b} = e^a e^b (lesson 04): ezk+c=ecezke^{z_k + c} = e^c e^{z_k}.
    2. So softmax⁡(z+c1)k=ecezk∑jecezj=ecezkec∑jezj\operatorname{softmax}(z + c\mathbf 1)_k = \dfrac{e^c e^{z_k}}{\sum_j e^c e^{z_j}} = \dfrac{e^c e^{z_k}}{e^c \sum_j e^{z_j}}.
    3. Cancel ec≠0e^c \ne 0: the result is softmax⁡(z)k\operatorname{softmax}(z)_k. ■\blacksquare

    So only the differences between logits matter. This is the reason for the max trick of section 3.6.

    Two classes give the sigmoid. With logits (z,0)(z, 0):

    softmax⁡(z,0)1=ezez+e0=ezez+1=σ(z).\operatorname{softmax}(z, 0)_1 = \frac{e^z}{e^z + e^0} = \frac{e^z}{e^z + 1} = \sigma(z).

    By shift invariance, softmax⁡(z1,z2)1=softmax⁡(z1−z2,0)1=σ(z1−z2)\operatorname{softmax}(z_1, z_2)_1 = \operatorname{softmax}(z_1 - z_2, 0)_1 = \sigma(z_1 - z_2). So a binary classifier needs only one score: the difference of the two logits.

    3.3 Temperature #

    For T>0T > 0, p(T)=softmax⁡(z/T)p^{(T)} = \operatorname{softmax}(z / T). Then pi(T)/pj(T)=e(zi−zj)/Tp^{(T)}_i / p^{(T)}_j = e^{(z_i - z_j)/T}.

    • T=1T = 1: the ordinary softmax.
    • T→0T \to 0: if the largest logit zkz_k is unique, p(T)→p^{(T)} \to the one-hot vector at kk. Reason: pk(T)=1/∑je(zj−zk)/Tp^{(T)}_k = 1 / \sum_j e^{(z_j - z_k)/T}. For j≠kj \ne k, zj−zk<0z_j - z_k < 0, so (zj−zk)/T→−∞(z_j - z_k)/T \to -\infty and e(zj−zk)/T→0e^{(z_j - z_k)/T} \to 0. The sum tends to e0=1e^0 = 1, so pk(T)→1p^{(T)}_k \to 1. If several logits tie for the maximum, the probability is split equally between them.
    • T→∞T \to \infty: z/T→0z / T \to 0, and softmax⁡(0,…,0)=(1/n,…,1/n)\operatorname{softmax}(0, \dots, 0) = (1/n, \dots, 1/n), the uniform vector.

    Example with z=(1,2,3)z = (1, 2, 3): T=0.5T = 0.5 gives (0.016,0.117,0.867)(0.016, 0.117, 0.867), T=1T = 1 gives (0.090,0.245,0.665)(0.090, 0.245, 0.665), T=10T = 10 gives (0.301,0.332,0.367)(0.301, 0.332, 0.367).

    So the softmax is a smooth version of the argmax (as a one-hot vector); a better name would be "soft argmax". Language models sample the next token from softmax⁡(z/T)\operatorname{softmax}(z / T): small TT gives safe, repetitive text, large TT more varied text, and T→0T \to 0 is greedy decoding (always the most likely token).

    3.4 Log-sum-exp: a smooth maximum #

    The log-sum-exp of z∈Rnz \in \R^n is

    LSE⁡(z)=log⁡∑j=1nezj.\operatorname{LSE}(z) = \log \sum_{j=1}^{n} e^{z_j}.

    It is the log of the softmax normalizer. Its name says what it does, from the inside out.

    Theorem (LSE is close to the max). Let m=max⁡jzjm = \max_j z_j. Then

    m≤LSE⁡(z)≤m+log⁡n.m \le \operatorname{LSE}(z) \le m + \log n .
    Proof of the bounds
    1. One of the terms of ∑jezj\sum_j e^{z_j} is eme^m, and the other terms are positive. So ∑jezj≥em\sum_j e^{z_j} \ge e^m.
    2. Every term is at most eme^m, because zj≤mz_j \le m and eze^z is increasing. So ∑jezj≤n em\sum_j e^{z_j} \le n\,e^m.
    3. Take logs (the log is increasing, so it keeps ≤\le): m≤LSE⁡(z)≤log⁡(nem)=m+log⁡nm \le \operatorname{LSE}(z) \le \log(n e^m) = m + \log n. ■\blacksquare

    The upper bound is an equality exactly when all zjz_j are equal. The lower bound is strict when n≥2n \ge 2, because then the other terms are >0> 0.

    Examples: LSE⁡(1,2,3)≈3.408\operatorname{LSE}(1, 2, 3) \approx 3.408, which is in [3,3+log⁡3]≈[3,4.099][3, 3 + \log 3] \approx [3, 4.099]. LSE⁡(5,5)=log⁡(2e5)=5+log⁡2≈5.693\operatorname{LSE}(5, 5) = \log(2e^5) = 5 + \log 2 \approx 5.693: the upper bound, since the two numbers are equal.

    With a temperature, TLSE⁡(z/T)T \operatorname{LSE}(z / T) lies in [m,m+Tlog⁡n][m, m + T\log n], so it tends to the max as T→0T \to 0. For two numbers z=(x,0)z = (x, 0), LSE⁡(x,0)=log⁡(1+ex)\operatorname{LSE}(x, 0) = \log(1 + e^x) is the softplus function, a smooth version of max⁡(x,0)\max(x, 0) (the ReLU).

    Interactive figure: loading…

    Lower the temperature TT. The blue kinked curve is max⁡(x,0)\max(x, 0); the orange curve is TLSE⁡(z/T)T \operatorname{LSE}(z/T) for z=(x,0)z = (x, 0). It always stays inside the yellow band [max⁡,max⁡+Tlog⁡2][\max, \max + T\log 2], and the gap is largest at x=0x = 0, where the two numbers are equal. The aqua tangent has slope σ(x/T)\sigma(x/T): the slope of LSE is the softmax.

    Two more facts. First, LSE⁡(z+c1)=LSE⁡(z)+c\operatorname{LSE}(z + c\mathbf 1) = \operatorname{LSE}(z) + c (take ece^c out of the sum, as in the proof of shift invariance). Second, the log-softmax: take the log of the softmax and use the quotient rule of lesson 04,

    log⁡softmax⁡(z)k=zk−log⁡∑jezj=zk−LSE⁡(z).\log \operatorname{softmax}(z)_k = z_k - \log \sum_j e^{z_j} = z_k - \operatorname{LSE}(z).
    Quick check

    What is LSE⁡(5,5)=log⁡(e5+e5)\operatorname{LSE}(5, 5) = \log(e^5 + e^5)?

    3.5 Cross-entropy from logits #

    A classifier with logits zz and true class yy is trained with the cross-entropy loss, the negative log-probability of the true class:

    ℓ(z,y)=−log⁡softmax⁡(z)y=LSE⁡(z)−zy.\ell(z, y) = -\log \operatorname{softmax}(z)_y = \operatorname{LSE}(z) - z_y .

    The right-hand side never forms a probability, so it never takes log⁡0\log 0. For z=(1,2,3)z = (1, 2, 3): y=3y = 3 gives 3.408−3=0.4083.408 - 3 = 0.408 (a confident, correct prediction, small loss); y=1y = 1 gives 3.408−1=2.4083.408 - 1 = 2.408 (a large loss). The /information-theory/ track explains why this loss is a cross-entropy.

    3.6 Numerical stability: the max trick #

    The problem. A float64 number is at most about 1.8×103081.8 \times 10^{308}, so eze^z overflows to inf for z>709.78z > 709.78 (=log⁡(1.8×10308)= \log(1.8 \times 10^{308})). In float32 (common on GPUs) the limit is z>88.72z > 88.72. In the other direction, eze^z underflows to 0 for zz below about −745-745 in float64.

    • Naive softmax of (1000,1001,1002)(1000, 1001, 1002): every ezke^{z_k} is inf, and inf / inf is nan.
    • Naive softmax of (−1000,−1001,−1002)(-1000, -1001, -1002): every ezke^{z_k} is 0, and 0 / 0 is nan.

    The fix. Let m=max⁡jzjm = \max_j z_j and use shift invariance with c=−mc = -m:

    softmax⁡(z)k=ezk−m∑jezj−m,LSE⁡(z)=m+log⁡∑jezj−m.\operatorname{softmax}(z)_k = \frac{e^{z_k - m}}{\sum_j e^{z_j - m}}, \qquad \operatorname{LSE}(z) = m + \log \sum_j e^{z_j - m}.

    Why it is safe.

    1. Every zj−m≤0z_j - m \le 0, so every term ezj−m≤1e^{z_j - m} \le 1: no overflow.
    2. The term with zj=mz_j = m is e0=1e^0 = 1, so the sum is at least 1: no division by 0, and the log of the sum is ≥0\ge 0.
    3. Terms with zj−m<−745z_j - m < -745 underflow to 0. This is harmless: their true probability is below 10−32310^{-323} anyway.

    Log-softmax in one step. Compute zk−LSE⁡(z)z_k - \operatorname{LSE}(z) with the stable LSE. Never compute np.log(softmax(z)) in two steps: for z=(0,1000)z = (0, 1000), even the stable softmax gives (0,1)(0, 1) in float64 (the true first entry e−1000e^{-1000} underflows), and log⁡0=−∞\log 0 = -\infty, while the true value z1−LSE⁡(z)z_1 - \operatorname{LSE}(z) is −1000-1000.

    Interactive figure: loading…

    Step through the two columns. The naive column computes ezke^{z_k} first and fails (inf and nan in magenta). The stable column subtracts the max mm first and gives the correct probabilities. Try "−1000, −1001, −1002" (underflow) and "0, 1000" (the log-softmax row). Then choose "88, 89, 90" and switch to float32: there the limit is 88.72, not 709.78 (the figure rounds each step with Math.fround to simulate float32).

    Stable sigmoid. σ(z)=1/(1+e−z)\sigma(z) = 1/(1 + e^{-z}) computes e1000e^{1000} for z=−1000z = -1000. The result happens to be right (0), but NumPy warns about the overflow, and log⁡σ(z)\log \sigma(z) becomes log⁡0\log 0. Use 1/(1+e−z)1/(1 + e^{-z}) for z≥0z \ge 0 and ez/(1+ez)e^{z}/(1 + e^{z}) for z<0z < 0: the exponent is then never positive. Libraries do this: scipy.special.expit, torch.sigmoid, and for losses torch.nn.functional.logsigmoid and BCEWithLogitsLoss.

    In practice use the library functions: scipy.special.softmax, log_softmax, logsumexp; torch.softmax, torch.log_softmax, torch.logsumexp; and torch.nn.CrossEntropyLoss, which takes logits (not probabilities) for this reason.

    Quick check

    Why does stable code compute softmax⁡(z−max⁡jzj)\operatorname{softmax}(z - \max_j z_j) instead of softmax⁡(z)\operatorname{softmax}(z)?

    Accuracy, the gradient of LSE, and multi-label outputs
    • Gradient of LSE. The partial derivative of LSE⁡\operatorname{LSE} with respect to zkz_k is softmax⁡(z)k\operatorname{softmax}(z)_k (the /calculus/ track derives it). So the gradient of the cross-entropy LSE⁡(z)−zy\operatorname{LSE}(z) - z_y is softmax⁡(z)−ey\operatorname{softmax}(z) - e_y, where eye_y is the one-hot vector of the true class: "predicted minus true". The figure above shows the 2-class case: the slope of log⁡(1+ex)\log(1 + e^x) is σ(x)\sigma(x).
    • Accuracy. Blanchard, Higham and Higham (2021) analyse the rounding errors of the shifted formulas and show that they are accurate; they also discuss log1p for the case where one term dominates: LSE⁡(z)=m+log1p⁡(∑j≠kezj−m)\operatorname{LSE}(z) = m + \operatorname{log1p}\big(\sum_{j \ne k} e^{z_j - m}\big).
    • Sigmoid or softmax? Softmax for one class out of nn (the probabilities compete and sum to 1). Independent sigmoids for multi-label problems, where an image can contain a cat and a dog: each class gets its own yes/no probability, and they need not sum to 1.

    Answers to section 1. (1) The same: (101,102,103)=(1,2,3)+100⋅1(101, 102, 103) = (1, 2, 3) + 100\cdot\mathbf 1, and the softmax is shift invariant. Both give (0.090,0.245,0.665)(0.090, 0.245, 0.665). (2) nan in every entry: each ezke^{z_k} is inf, and inf / inf is nan. Subtracting the max first gives the correct (0.090,0.245,0.665)(0.090, 0.245, 0.665). (3) σ(−2)=1−σ(2)≈0.119\sigma(-2) = 1 - \sigma(2) \approx 0.119.

    4. Worked example #

    Take the logits z=(1,2,3)z = (1, 2, 3) of a 3-class classifier.

    (a) Softmax, naive order.

    1. Exponentials: e1≈2.718e^1 \approx 2.718, e2≈7.389e^2 \approx 7.389, e3≈20.086e^3 \approx 20.086.
    2. Sum: s=2.718+7.389+20.086=30.193s = 2.718 + 7.389 + 20.086 = 30.193.
    3. Divide: p=(2.718,7.389,20.086)/30.193≈(0.090,0.245,0.665)p = (2.718, 7.389, 20.086)/30.193 \approx (0.090, 0.245, 0.665). The entries add up to 1.

    (b) Softmax with the max trick. m=3m = 3, so z−m=(−2,−1,0)z - m = (-2, -1, 0).

    1. Exponentials: e−2≈0.1353e^{-2} \approx 0.1353, e−1≈0.3679e^{-1} \approx 0.3679, e0=1e^0 = 1.
    2. Sum: s′=1.5032s' = 1.5032 (at least 1, as promised).
    3. Divide: p≈(0.0900,0.2447,0.6652)p \approx (0.0900, 0.2447, 0.6652): the same as in (a), because s=e3s′s = e^3 s'.

    (c) Log-sum-exp, both ways. Naive: log⁡30.193≈3.4076\log 30.193 \approx 3.4076. Stable: m+log⁡s′=3+log⁡1.5032=3+0.4076=3.4076m + \log s' = 3 + \log 1.5032 = 3 + 0.4076 = 3.4076. The bounds hold: 3≤3.4076≤3+log⁡3≈4.09863 \le 3.4076 \le 3 + \log 3 \approx 4.0986.

    (d) Log-softmax and cross-entropy. log⁡p=z−LSE⁡(z)=(1,2,3)−3.4076=(−2.4076,−1.4076,−0.4076)\log p = z - \operatorname{LSE}(z) = (1, 2, 3) - 3.4076 = (-2.4076, -1.4076, -0.4076). Check: e−0.4076≈0.665e^{-0.4076} \approx 0.665 ✓. If the true class is y=3y = 3, the loss is 0.40760.4076; if it is y=1y = 1, the loss is 2.40762.4076.

    (e) Temperature. T=0.5T = 0.5: z/T=(2,4,6)z / T = (2, 4, 6), and the same steps give (0.016,0.117,0.867)(0.016, 0.117, 0.867): sharper.

    (f) Two classes. For logits (2,0)(2, 0): softmax⁡(2,0)1=e2/(e2+1)=7.389/8.389≈0.881=σ(2)\operatorname{softmax}(2, 0)_1 = e^2/(e^2 + 1) = 7.389/8.389 \approx 0.881 = \sigma(2). And logit⁡(0.881)=log⁡(0.881/0.119)≈2\operatorname{logit}(0.881) = \log(0.881/0.119) \approx 2: back to the score.

    Quick check

    A spam filter outputs p=0.8p = 0.8 for "spam" with a sigmoid. What score (logit) zz did it compute?

    5. In code #

    NumPy checks the worked example; SciPy has the same functions. The notebook for this lesson has these cells and the exercises.

    import numpy as np
    from scipy.special import softmax as sp_softmax, logsumexp, expit
    
    def softmax(z):
        z = np.asarray(z, dtype=float)
        e = np.exp(z - z.max())          # the max trick: every exponent <= 0
        return e / e.sum()
    
    def lse(z):
        z = np.asarray(z, dtype=float)
        m = z.max()
        return m + np.log(np.sum(np.exp(z - m)))
    
    z = np.array([1.0, 2.0, 3.0])
    print(softmax(z).round(4), softmax(z + 100).round(4))   # [0.09   0.2447 0.6652] [0.09   0.2447 0.6652]
    print(round(lse(z), 4), round(logsumexp(z), 4))         # 3.4076 3.4076
    print((z - lse(z)).round(4))                            # [-2.4076 -1.4076 -0.4076]
    
    big = np.array([1000.0, 1001.0, 1002.0])
    with np.errstate(over="ignore", invalid="ignore"):
        print(np.exp(big) / np.exp(big).sum())              # [nan nan nan]
    print(softmax(big).round(4), sp_softmax(big).round(4))  # [0.09   0.2447 0.6652] [0.09   0.2447 0.6652]
    
    print(round(expit(2), 4), round(expit(-2), 4))          # 0.8808 0.1192
    print(round(np.log(0.8 / 0.2), 4))                      # 1.3863  (logit of 0.8)
    print(round(softmax([2.0, 0.0])[0], 4))                 # 0.8808  (2-class softmax = sigmoid)
    

    6. Where it shows up #

    • Logistic regression and every binary classifier: P(y=1∣x)=σ(w⊤x+b)P(y = 1 \mid x) = \sigma(w^\top x + b); the loss is the binary cross-entropy −ylog⁡σ(z)−(1−y)log⁡(1−σ(z))-y\log\sigma(z) - (1 - y)\log(1 - \sigma(z)), computed stably from the logit zz by BCEWithLogitsLoss.
    • The output layer of classifiers. Image classifiers (1000 ImageNet classes) and language models (a softmax over a vocabulary of tens of thousands of tokens) end with a softmax and are trained with the cross-entropy LSE⁡(z)−zy\operatorname{LSE}(z) - z_y. The ML Fundamentals track and the Deep Learning track use it in every classifier.
    • Attention. A transformer computes weights softmax⁡(q⊤kj/d)\operatorname{softmax}(q^\top k_j / \sqrt{d}) over the keys kjk_j; the d\sqrt d acts like a temperature (Linear Algebra lesson 15). Fast attention kernels (FlashAttention) keep a running max and a running sum of exponentials (the "online softmax"): the max trick, done block by block.
    • Sampling from language models: temperature, and greedy decoding as T→0T \to 0.
    • Smooth maxima. Softplus log⁡(1+ex)\log(1 + e^x) is a smooth ReLU; LSE pooling and "soft-min" losses replace a hard max by a differentiable one.
    • Other places: the Gumbel-softmax trick, mixture models (weights from a softmax), the Boltzmann distribution pk∝e−Ek/(kBT)p_k \propto e^{-E_k / (k_B T)} of statistical physics (the same formula, with energies as negative logits and a physical temperature), and the softmax policies of reinforcement learning.

    7. Common mistakes #

    • Normalizing raw scores by their sum. zk/∑jzjz_k / \sum_j z_j fails for negative scores and for a zero sum. Use the softmax.
    • Naive exponentials. np.exp(z) / np.exp(z).sum() returns nan for large logits (overflow) and for very negative logits (underflow to 0/0). Subtract the max first.
    • log(softmax(z)) in two steps. A probability that rounds to 0 gives -inf. Compute z−LSE⁡(z)z - \operatorname{LSE}(z).
    • Passing probabilities to a loss that expects logits. torch.nn.CrossEntropyLoss applies the log-softmax itself; giving it softmax outputs applies the softmax twice and trains badly.
    • Softmax over the wrong axis. For a batch of logits with shape (batch, classes), use axis=-1 (or axis=1), so each row sums to 1. With axis=0 each column sums to 1, which is wrong.
    • Softmax for multi-label outputs. If several labels can be true at once, use one sigmoid per label.
    • Thinking LSE equals the max. It is always larger (for n≥2n \ge 2), by at most log⁡n\log n.
    • Confusing "logit" and "logits". The logit is log⁡p1−p\log\frac{p}{1-p}; "logits" are the raw scores of a model.

    8. Check yourself #

    1. Compute σ(0)\sigma(0), σ(log⁡3)\sigma(\log 3) and logit⁡(0.5)\operatorname{logit}(0.5).
      Answerσ(0)=1/2\sigma(0) = 1/2. σ(log⁡3)=1/(1+e−log⁡3)=1/(1+1/3)=3/4\sigma(\log 3) = 1/(1 + e^{-\log 3}) = 1/(1 + 1/3) = 3/4. logit⁡(0.5)=log⁡(0.5/0.5)=log⁡1=0\operatorname{logit}(0.5) = \log(0.5/0.5) = \log 1 = 0.
    2. Compute softmax⁡(0,log⁡2,log⁡3)\operatorname{softmax}(0, \log 2, \log 3) by hand.
      AnswerThe exponentials are 1,2,31, 2, 3; their sum is 6. So the softmax is (1/6,2/6,3/6)=(1/6,1/3,1/2)(1/6, 2/6, 3/6) = (1/6, 1/3, 1/2).
    3. Show that softmax⁡(z)i/softmax⁡(z)j=ezi−zj\operatorname{softmax}(z)_i / \operatorname{softmax}(z)_j = e^{z_i - z_j}, and use it to explain shift invariance in one sentence.
      AnswerThe denominators cancel: ezi/sezj/s=ezi/ezj=ezi−zj\dfrac{e^{z_i}/s}{e^{z_j}/s} = e^{z_i}/e^{z_j} = e^{z_i - z_j}. All ratios depend only on differences of logits, and adding cc to every logit does not change any difference; since the entries also sum to 1, the whole vector stays the same.
    4. Give the bounds for LSE⁡(z)\operatorname{LSE}(z) when z=(0,0,0,0)z = (0, 0, 0, 0), and the exact value.
      Answerm=0m = 0 and n=4n = 4, so 0≤LSE⁡≤log⁡40 \le \operatorname{LSE} \le \log 4. All entries are equal, so the upper bound is exact: log⁡(4e0)=log⁡4≈1.386\log(4e^0) = \log 4 \approx 1.386.
    5. A float32 model produces the logits (90,85,80)(90, 85, 80). What happens with naive softmax? What does the stable version give?
      AnswerIn float32, e90e^{90} overflows (the limit is about 88.72), so the first exponential is `inf` and the result contains `nan`. Stable: z−m=(0,−5,−10)z - m = (0, -5, -10), exponentials (1,0.0067,0.0000454)(1, 0.0067, 0.0000454), sum 1.006781.00678, so p≈(0.9933,0.0067,0.0000451)p \approx (0.9933, 0.0067, 0.0000451).
    6. Logits z=(2,0)z = (2, 0) and true class 2. Compute the cross-entropy loss.
      AnswerLSE⁡(2,0)=log⁡(e2+1)≈2.1269\operatorname{LSE}(2, 0) = \log(e^2 + 1) \approx 2.1269. The loss is LSE⁡(z)−z2=2.1269−0=2.1269\operatorname{LSE}(z) - z_2 = 2.1269 - 0 = 2.1269. Equivalently −log⁡(1−σ(2))=−log⁡0.1192≈2.127-\log(1 - \sigma(2)) = -\log 0.1192 \approx 2.127.
    Recall cardsAnswer in your head first, then reveal. Add the cards to your review deck to see them again just before you would forget.
    1. Write the sigmoid, and give σ(0)\sigma(0) and σ(−z)\sigma(-z).

    2. What is the inverse of the sigmoid?

    3. Compute the logit of p=0.8p = 0.8.

    4. Write the softmax of z∈Rnz \in \R^n.

    5. Why does adding the same constant cc to every logit not change the softmax?

    6. What does a 2-class softmax with logits (z,0)(z, 0) give for class 1?

    7. State the bounds of the log-sum-exp of z∈Rnz \in \R^n.

    8. How do you compute log-softmax and LSE without overflow?

    9. What does softmax⁡(z/T)\operatorname{softmax}(z/T) approach as T→0T \to 0, and as T→∞T \to \infty?

    10. What is the slope of the sigmoid, and where is it largest?

    Open the review →

    9. Interview angle #

    • "Why subtract the max in softmax?" — Shift invariance makes it exact; afterwards every exponent is ≤0\le 0 (no overflow) and the denominator is ≥1\ge 1 (no division by 0).
    • "Why does CrossEntropyLoss take logits, not probabilities?" — It computes LSE⁡(z)−zy\operatorname{LSE}(z) - z_y in one stable step; computing a softmax and then a log can give log⁡0\log 0. Its gradient is softmax⁡(z)−ey\operatorname{softmax}(z) - e_y.
    • "Sigmoid or softmax for the output layer?" — Softmax when exactly one class is true (multi-class); one sigmoid per class when several can be true (multi-label). For two classes they are the same model.
    • "What does temperature do in sampling?" — Divides the logits by TT; T<1T < 1 sharpens the distribution toward the argmax, T>1T > 1 flattens it toward uniform.
    • "What is LSE, and why is it called a soft maximum?" — log⁡∑jezj\log\sum_j e^{z_j}, within log⁡n\log n above the max, smooth everywhere, and its gradient is the softmax.

    10. Practice #

    The notebook for this lesson runs in Colab or in your browser. It has five exercises, each with a check cell and a folded solution:

    1. A stable sigmoid that gives no overflow warning for z=±1000z = \pm 1000; compare with scipy.special.expit.
    2. A stable softmax(z, axis=-1) for 2-D input; test shift invariance and logits near 1000 against scipy.special.softmax.
    3. logsumexp and log_softmax; check the bounds and compare with scipy.special.logsumexp.
    4. The mean cross-entropy loss for a batch of logits and labels, with broadcasting and fancy indexing from lesson 03.
    5. Temperature sampling with a seeded random generator: compare the empirical frequencies for T=0.5,1,2T = 0.5, 1, 2.

    11. Watch and read #

    Softmax as a smooth replacement of argmax for the output layer of a network.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    Odds and the log of the odds, which is the logit of this lesson.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    The sigmoid curve as a model of a probability, and how logistic regression uses it.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    The section "Softmax with temperature": how a language model turns logits into next-token probabilities.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play