第 42 課 · 基礎 · 18 分鐘

Python softmax 與溫度

把原始分數變成不會溢出的機率分布。

softmaxlogits溫度機率

情感模型吐出 4.2 和 -1.7 這樣的分數,它們不是機率。softmax 把它們變成一個加起來等於一的分布。為什麼先減掉最大值再取指數?

分類器經常輸出一組原始分數,稱為 logits。Softmax 把分數變成總和為一的正數,使其可以作為機率分布使用。關鍵技巧是在取指數前減去最大分數,避免大數值溢出。 你還會用對數損失衡量自信的錯誤,並把機率變成審核門檻值。

取指數並歸一化

Softmax 對每個 logit 取 exp,再除以總和。exp 讓所有值變為正數並保持順序,除法讓結果總和為一。logit 越大,機率越大,但輸出並不代表模型一定正確。

import math

def softmax(logits):
    exps = [math.exp(x) for x in logits]
    total = sum(exps)
    return [x / total for x in exps]

print([round(p, 3) for p in softmax([2, 0])])

正數,且總和為一

減去最大值保持穩定

exp(1000) 對浮點數來說太大,即使最終比例很普通。給每個 logit 減去最大值,可以在不改變比例的情況下平移所有數值。這是標準的穩定實現,不是近似。

import math

def softmax(logits):
    largest = max(logits)
    exps = [math.exp(x - largest) for x in logits]
    total = sum(exps)
    return [x / total for x in exps]

print([round(p, 3) for p in softmax([1000, 1000])])

先平移,再取指數

用溫度改變尖銳程度

在 softmax 前把每個 logit 除以一個正溫度。溫度小於一會讓最大分數更佔優勢;溫度大於一會讓分布更平緩。溫度改變的是輸出中的不確定性,不是底層證據。

import math

def softmax(logits, temperature=1.0):
    scaled = [x / temperature for x in logits]
    largest = max(scaled)
    exps = [math.exp(x - largest) for x in scaled]
    total = sum(exps)
    return [x / total for x in exps]

print([round(p, 3) for p in softmax([2, 0], 0.5)])
print([round(p, 3) for p in softmax([2, 0], 2.0)])

溫度越低越尖銳

看整個分布,而不只看贏家

最大機率對應 argmax,但其他數值同樣攜帶資訊。[0.34, 0.33, 0.33] 與 [0.98, 0.01, 0.01] 的贏家相同,含義卻完全不同。檢查數值是否有限,並確認總和約等於一。

probs = [0.7, 0.2, 0.1]
winner = max(range(len(probs)), key=probs.__getitem__)
print(winner)
print(round(sum(probs), 3))

argmax 加上基本檢查

對數損失懲罰自信的錯誤

對單條樣本,對數損失是正確類別機率的負對數。以 0.9 的機率答對貢獻很小;自信地答錯貢獻很大。對各樣本損失取平均,並在取對數前截斷精確的零。

import math

for probability in [0.9, 0.5, 0.01]:
    loss = -math.log(probability)
    print(probability, round(loss, 3))

信心度改變懲罰

把機率變成審核門檻值

機率只有選定門檻值後才會變成動作。如果自動答錯的代價很高,就把不確定的樣本送去審核。應在驗證集上,根據審核與錯誤的相對成本選擇門檻值,而不是在測試集上選。

def action(probability, threshold=0.8):
    return "accept" if probability >= threshold else "review"

for probability in [0.95, 0.72, 0.40]:
    print(probability, action(probability))

信心度閘門,而不是猜測

本課要點

  • Softmax 把任意 logits 變成總和為一的正數。
  • 取 exp 前減去最大 logit,避免溢出。
  • 溫度小於一會讓分布更尖銳,大於一會更平緩。
  • 最大機率是 argmax,但整個分布都有資訊。
  • 機率分布不等於正確性保證。
  • 對數損失懲罰自信的錯誤;門檻值把機率變成考慮成本的動作。

常見錯誤

  • 直接對巨大 logits 取 exp,沒有先減去最大值。
  • 歸一化之後才應用溫度,而不是在 softmax 前。
  • 把最高機率當成答案一定為真的證明。
  • 把 softmax 的最大值當成確定性,卻不檢查校準或錯誤成本。
輪到你

編寫接受溫度的穩定 softmax,對 logits [3, 1, 0] 分別用溫度 0.5 和 2.0 列印保留三位小數的分布。

動手試試

改改變數、先預測輸出,再執行程式碼。第一次點擊「執行程式碼」時會下載 Python 執行時,可能需要幾秒鐘。

瀏覽器內 Python本機執行 · 無需帳號
首次執行會從 CDN 下載 Pyodide。修改後點擊「執行程式碼」。

練習本課

12 道題,作答後立即看到解釋。

查看 12 道題答案開始練習
← 分詞與向量最近鄰分類 →