Python softmax 練習:穩定性、溫度與對數損失
softmax 看起來只有兩行算術,細節卻很重要:溢出、溫度,以及機率和決策之間的區別。這些練習逐塊搭建,再連接到損失函式。
歸一化指數值
對每個 logit 取 exp,再除以總和。輸出為正且總和為一。測試中要檢查總和,因為靜默的歸一化錯誤會讓後續指標失去意義。
import math
def softmax(logits):
exps = [math.exp(x) for x in logits]
total = sum(exps)
return [x / total for x in exps]
probs = softmax([1, 1])
print([round(p, 3) for p in probs])
print(round(sum(probs), 3))檢查過的分布
減去最大值
很大的 logit 在歸一化前就會溢出。減去最大值可以在不改變比例的情況下平移所有數值。結果在數學上相同,在數值上安全。
import math
def stable_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 stable_softmax([1000, 1000])])同樣的答案,不再溢出
改變溫度
溫度在 softmax 前除 logits。小於一的值讓最大分數更突出;大於一的值讓分布更平緩。溫度不會增加證據,只會改變模型的確定程度。
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)])更尖銳或更平緩
計算真實類別的對數損失
如果真實類別的預測機率是 p,對數損失是 -log(p)。自信且正確時損失低;自信卻錯誤時損失很大。取對數前要把機率截斷到零以上。
import math
p_true = 0.8
loss = -math.log(max(p_true, 1e-12))
print(round(loss, 3))為自信付出代價
argmax 是決策,不是真理
最高機率給出類別標籤,但整個分布可能很接近、很猶豫。要同時報告最高機率和第一、第二名的差距。影響重大的決定應加入人工覆核,或在低信心度時棄權。
probs = [0.46, 0.44, 0.10]
order = sorted(range(len(probs)), key=probs.__getitem__, reverse=True)
print(order[0])
print(round(probs[order[0]] - probs[order[1]], 2))贏家加差距
你的練習清單
- 檢查 softmax 輸出為正且總和為一。
- 取指數前減去最大 logit。
- 使用正溫度,並記錄它的作用。
- 計算對數損失前截斷機率。
- 報告最高機率和差距,而不只是 argmax。
常見問題
softmax 只用於神經網路嗎?
不是。它是一般性的分數歸一化方法,只是神經網路分類器經常使用。
溫度能提高準確率嗎?
本身不能。它改變分布的尖銳程度,校準和評估是另外的步驟。
為什麼對數損失要截斷機率?
log(0) 無定義。截斷讓損失保持有限,但不能挽救給真值零機率的模型。
練習 softmax
12 道題,覆蓋歸一化、穩定性、溫度、argmax 和對數損失。
繼續閱讀: