問題提起 — 内積スコアをそのまま使えない理由
前章で、Q(質問)とK(鍵)の内積で「相性スコア」が計算できると学びました。たとえば「it」というクエリに対し、文中の各単語のスコアがこうなったとします。
# クエリ「it」と他の単語の内積スコア
animal: 5.2
the: -1.3
street: 2.8
because: 0.4
tired: 3.6 これでも「animal が一番関連が強い」ことは分かります。ただし、この生の値を使うと困ったことが起きます。
- 合計しても
5.2 + (-1.3) + 2.8 + 0.4 + 3.6 = 10.7で、意味のある数にならない - 負の値もあって、「注目度」として使いにくい
- 後でValueを「重み付き平均」したいのに、重みの合計が1じゃない
そこで、これらのスコアを「合計が1の確率分布」に変換する関数が必要です。それが softmax です。
Softmaxの定義 — 指数関数で増幅する
Softmax関数:n個の値 x₁, x₂, ..., xₙ に対し
softmax(xᵢ) = e^xᵢ / Σⱼ e^xⱼ
分子: e^xᵢ、分母: e^x₁ + e^x₂ + ... + e^xₙ
ここに登場する e^x は、数学IIで習う 指数関数。e ≒ 2.718 はネイピア数です。
なぜ e^x で「増幅」するのか
指数関数 e^x の特徴は「急激に伸びる」ことです。x が少し増えるだけで、e^x は爆発的に大きくなります。
| x | e^x(近似値) |
|---|---|
| 0 | 1 |
| 1 | 2.72 |
| 2 | 7.39 |
| 3 | 20.09 |
| 5 | 148.41 |
| 10 | 22,026 |
この性質により、softmaxは 「大きい値はより目立つように、小さい値はより目立たないように」差を強調 します。さきほどの「it」の例で計算してみましょう。
# 元のスコア
animal: 5.2, the: -1.3, street: 2.8, because: 0.4, tired: 3.6
# Step 1: e^x で増幅
e^5.2 = 181.27
e^-1.3 = 0.27
e^2.8 = 16.44
e^0.4 = 1.49
e^3.6 = 36.60
# Step 2: 合計 = 181.27 + 0.27 + 16.44 + 1.49 + 36.60 = 236.07
# Step 3: それぞれを合計で割る = softmax
softmax(animal) = 181.27 / 236.07 = 0.768 ← 77%!
softmax(the) = 0.27 / 236.07 = 0.001 ← 0.1%
softmax(street) = 16.44 / 236.07 = 0.070 ← 7%
softmax(because) = 1.49 / 236.07 = 0.006 ← 0.6%
softmax(tired) = 36.60 / 236.07 = 0.155 ← 15%
# 合計 = 1.000 ← 確率分布になった! 元のスコアでは「animal=5.2」「tired=3.6」と1.4の差でしたが、softmax後は「animal=77%」「tired=15%」と5倍の差になっています。e^x の急激な伸びが、トップ候補を圧倒的に目立たせる のです。
graph LR A[内積スコア\n5.2, -1.3, 2.8, 0.4, 3.6] --> B[Step 1: e^x で増幅\n181, 0.3, 16, 1.5, 37] B --> C[Step 2: 合計で割る\n0.77, 0.001, 0.07, 0.006, 0.15] C --> D[合計 = 1\n確率分布完成] style A fill:#3b82f6,stroke:#1d4ed8,color:#fff style B fill:#8b5cf6,stroke:#6d28d9,color:#fff style C fill:#f97316,stroke:#ea580c,color:#fff style D fill:#14b8a6,stroke:#0d9488,color:#fff
なぜ「Soft」maxなのか
「max」は最大値を1つ選ぶ操作です。さきほどの例なら max(5.2, -1.3, 2.8, 0.4, 3.6) = 5.2 を選び、他を捨てます。これを hard max と呼びます。
対して softmax は「柔らかい最大値選択」。最大候補を強く重視しつつも、他の候補にも少しだけ重みを残します。
| Hard max | Softmax | |
|---|---|---|
| 出力 | 1か0だけ | 0〜1の連続値 |
| 情報量 | 勝者以外は完全に消える | 全候補の情報が残る |
| 微分可能 | 不可能 | 可能(学習に必須!) |
| 例 | animal=1, 他=0 | animal=0.77, tired=0.15, street=0.07, ... |
Temperature — 鋭さを調整するつまみ
ChatGPTを使ったことがあれば、「temperature」という言葉を聞いたことがあるかもしれません。実はこれ、softmaxにつくつまみのことです。
温度付きSoftmax:
softmax_T(xᵢ) = e^(xᵢ/T) / Σⱼ e^(xⱼ/T)
T = 温度パラメータ(Temperature)
T を変えると、softmaxの「鋭さ」が変わります。
| T(温度) | 効果 | 挙動 |
|---|---|---|
| T → 0 | 極端に鋭くなる | ほぼ hard max(最大候補だけが1) |
| T = 1 | 通常のsoftmax | 元のスコア比を素直に反映 |
| T = 0.7 | やや鋭め | GPTのデフォルト(決定的だが少し多様性) |
| T = 1.5 | やや鈍め | 候補がより均等に |
| T → ∞ | 完全に均等 | すべての候補が同じ確率(1/n) |
確率分布としてのSoftmax
softmaxの出力は「合計1の非負の数列」なので、形式上は 確率分布 として扱えます。さきほどの「it」の例なら、こんな解釈ができます。
「it」の意味を決めるとき、77%の重みでanimalを参照し、15%の重みでtiredを、7%の重みでstreetを参照する
この「重み」を使って、次章で説明する V(Value)の加重平均 を作ります。「animalのValueを77%、tiredのValueを15%……合わせる」というわけです。
次章への布石 — softmax(QK^T/√dk)V の全体像
ここまで来ると、Attentionの核心式が少しずつ見えてきます。
Attention(Q, K, V) = softmax(QKT/√dk)V
QK^T:すべての(Q, K)ペアの内積(前章)/√dk:スケーリング(第7章で扱う「飽和問題」の対策)softmax(...):合計1の重みに変換(本章)× V:その重みでValueを加重平均(次章)
次の第6章で、ついにこの式全体を「図書館で本を探す」比喩を使って完全に解剖します。
理解度チェック
Softmax関数の最も重要な役割は何ですか?
キーボード: 1〜4 で選択、Enter で回答