Temperature Scaling(温度スケーリング)とは、学習済みモデルの出力logitを単一のスカラーパラメータT(温度)で除算することにより出力確率分布の尖度を調整し信頼度校正を改善する事後校正手法である。Guo et al.(2017)により提案されパラメータ数が1つのみという極めてシンプルな構造でありながら多くの設定で高い校正性能を達成する。
Temperature Scaling(温度スケーリング)はニューラルネットワークの信頼度校正において最も広く採用されている事後校正手法である。Guo et al.が2017年のICML論文「On Calibration of Modern Neural Networks」で提案し、現代の深層学習モデルが著しく過信であることを実証するとともに単一パラメータの温度Tによる除算だけで校正を大幅に改善できることを示した。
q_i = softmax(z_i / T) = exp(z_i / T) / Σ_j exp(z_j / T)
z_iはモデルの出力logit、Tは温度パラメータ(T > 0)、q_iは校正後の確率である。T = 1のとき元のモデル出力と一致しT > 1で確率分布が平坦化、T < 1で尖鋭化する。LLMの過信モデルに対してT > 1を適用することで確率分布をソフト化し最大確率クラスへの過度な集中を緩和する。GPT系モデルではT = 1.5〜2.5、BERT系モデルではT = 1.2〜1.8の範囲が最適となることが多い。
温度パラメータTは検証データセット上でNLL(Negative Log-Likelihood)を最小化することにより推定する。
T* = argmin_T Σ_(x,y)∈D_val [-log q_y(x; T)]
この最適化問題は凸であるため勾配降下法やL-BFGS等の標準的な最適化手法で大域最適解が保証される。
| T値の範囲 | 効果 | 適用場面 |
|---|---|---|
| T = 1.0 | 変化なし | 既に校正済みのモデル |
| T = 1.2〜1.5 | 軽微な平坦化 | 軽度の過信モデル |
| T = 1.5〜2.5 | 中程度の平坦化 | 一般的な過信モデル(GPT系) |
| T = 2.5〜5.0 | 大幅な平坦化 | 強い過信モデル |
| T < 1.0 | 尖鋭化 | 過小評価モデル(稀) |
Temperature Scalingはlogitに対するスケーリングのみ(1パラメータ)だがPlatt Scalingはアフィン変換(2パラメータ: a, b)を適用する。
# Temperature Scaling: 1パラメータ
q_i = softmax(z_i / T)
# Platt Scaling: 2パラメータ
q_i = sigmoid(a * z_i + b)
Platt Scalingはバイアス項bを持つためベースレートの偏りを補正できるが過適合のリスクがやや高い。検証データ1,000サンプル未満ではTemperature Scalingの方が安定する。
import torch
import torch.nn as nn
import torch.optim as optim
class TemperatureScaler(nn.Module):
def __init__(self):
super().__init__()
self.temperature = nn.Parameter(torch.ones(1) * 1.5)
def forward(self, logits):
return logits / self.temperature
def fit(self, val_logits, val_labels, lr=0.01, max_iter=50):
nll_criterion = nn.CrossEntropyLoss()
optimizer = optim.LBFGS([self.temperature], lr=lr, max_iter=max_iter)
def eval_fn():
optimizer.zero_grad()
scaled = self.forward(val_logits)
loss = nll_criterion(scaled, val_labels)
loss.backward()
return loss
optimizer.step(eval_fn)
return self.temperature.item()
import numpy as np
from openai import OpenAI
client = OpenAI()
def get_calibrated_confidence(prompt, temperature_param=1.8):
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
logprobs=True,
top_logprobs=5
)
token_logprobs = [t.logprob for t in response.choices[0].logprobs.content]
raw_confidence = np.exp(np.mean(token_logprobs))
calibrated = np.exp(np.mean(token_logprobs) / temperature_param)
return {"raw": raw_confidence, "calibrated": calibrated, "T": temperature_param}
| 手法 | パラメータ数 | 検証データ要件 | ECE性能 | 過適合リスク | 計算コスト |
|---|---|---|---|---|---|
| Temperature Scaling | 1 | 500〜1,000 | 0.02〜0.05 | 極低 | 極低 |
| Platt Scaling | 2 | 1,000〜2,000 | 0.02〜0.04 | 低 | 低 |
| Isotonic Regression | O(n) | 3,000〜10,000 | 0.01〜0.03 | 中 | 低 |
| Histogram Binning | M | 5,000〜20,000 | 0.03〜0.08 | 中 | 極低 |
| Beta Calibration | 3 | 1,000〜3,000 | 0.02〜0.04 | 低 | 低 |
LLMのTemperature Scalingは生成時の温度パラメータ(generation temperature)と混同されやすい。
実運用では生成温度T_gen=0.7で高品質テキストを生成し校正温度T_cal=1.8で確率を再スケーリングする2段階パイプラインが推奨される。
def sequence_calibrated_confidence(token_logprobs, T_cal):
scaled = [lp / T_cal for lp in token_logprobs]
return np.exp(sum(scaled) / len(scaled))
長いシーケンスほど確信度が低下する系統バイアスがあり、長さ正規化や長さ依存の温度パラメータT(L)の導入が改善策として研究されている。
A1: 検証データセット上でNLLを最小化するTを求めるのが標準的手法である。検証データは1,000サンプル以上が望ましく対象タスクのドメインに合致したデータを使用する。L-BFGS法で初期値T=1.5から開始し通常5〜20イテレーションで収束する。検証データとテストデータは独立でなければならずテストデータ上でTを調整するとオーバーフィッティングになる。
A2: 影響しない。Temperature Scalingはsoftmax適用前のlogitを一様にスケーリングするためargmax(最大確率クラス)は変化しない。モデルの予測ラベルは校正前後で同一であり分類精度は不変である。変化するのは各クラスに割り当てられる確率値のみである。ただしSelective Predictionと組み合わせた場合は閾値の再設定が必要になるため間接的に有効精度が変化する。
A3: Temperature Scalingは確率分布の全体的スケール調整であり局所的な校正不良には効果が限定的である。(1)Isotonic Regression: ノンパラメトリック手法で任意形状の校正関数を学習可能だが検証データ3,000サンプル以上必要。(2)Ensemble Temperature Scaling: クラス別に異なる温度パラメータを割り当てる拡張版。(3)Focal Loss等の学習時校正との2段階校正。まずTemperature Scalingを試しreliability diagramを確認して局所的乖離が残る場合にIsotonic Regressionへ切り替えるのが効率的である。