論文一覧に戻る 📚 用語集トップ 🗺 概念マップ
📚 用語解説
📚 用語解説
softmax
Softmax Function
深層学習
別称: ソフトマックス

🔖 キーワード索引

クラス確率正規化指数関数logitsクロスエントロピーargmaxTemperature多クラス分類softminBoltzmannHardmax

別名・略称:ソフトマックス

🔖 拡張キーワード索引

この用語『ソフトマックス関数』を理解するうえで併せて押さえたい関連キーワード群です。 クリック(ホバー)で関連用語ページに飛べます。

Softmax 確率分布 多クラス分類 温度パラメータ logit クロスエントロピー argmax の連続化 数値安定化 log-sum-exp 正規化

💡 30秒で分かる結論

🍰 まずはやさしく

スコアを確率に変える道具です。

答えがどれか判断するために使います。

スマホの画像診断などで役立ちます。

まずは結論を短くまとめます。

softmax(Softmax Function):出力をクラス確率に変換する関数

📍 あなたが今見ているもの

🍰 まずはやさしく

分類問題の心臓部のようなものです。

複数の選択肢から一つを選びます。

写真が犬か猫かを分ける時に使います。

どのような場面で使うか説明します。

ニューラルネットの 多クラス分類(猫/犬/鳥...)では、 最後に 「各クラスの確率」 を出さないといけません。 そのために softmax 関数 がほぼ標準。 出力層の logits を確率に変えるこの関数が、 分類問題の心臓部。 LLM でも次トークン予測で softmax が使われます。

🎨 直感で掴む

🍰 まずはやさしく

数字のバランスを整えるイメージです。

どれくらい正解に近いか示します。

部活の得点差を割合で考える感じです。

仕組みを直感的に理解しましょう。

softmax の動作例

logits = [2.0, 1.0, 0.1] の場合:

クラスlogit ze^z確率
A2.07.390.659
B1.02.720.242
C0.11.110.099
合計11.221.000

argmax は A(最高確率 0.659)。

🎨 直感を深掘り

ソフトマックスは「ベクトルを確率分布に変換」する関数。 例えば logit が [2.0, 1.0, 0.1] なら、 指数 → 正規化で [0.66, 0.24, 0.10] となり、 合計が 1 になる。 多クラス分類の出力層、 アテンションの重み計算、 ボルツマン分布、 強化学習の方策表現など、 「離散選択を確率的に表現したい」場面で必ず登場する。

温度パラメータ $T$ を導入した $\text{softmax}(z/T)$ は 「分布の鋭さ」を制御するための重要拡張。 $T \to 0$ で argmax (最大値だけ確率 1)、 $T \to \infty$ で一様分布 (全クラス等確率) になり、 ChatGPT などの LLM の「temperature 0.7」「top-p 0.9」はこの $T$ を直接調整しています。 強化学習ではボルツマン分布、 知識蒸留 (Hinton 2015) では「ソフトターゲット」を作る道具として活用されます。

SSDSE-B-2026 の例で言えば、 47 都道府県の人口を softmax にかけると東京 (約 1409 万) が確率 0.99 に張り付き、 ほぼ「東京を選ぶ argmax」と等価になります。 一方、 人口の log を入力すると確率分布はなだらかになり、 「人口比例で各県を選ぶ多項分布」に近づきます。 この「入力スケールが分布の尖り具合を支配する」感覚を掴むのが softmax を実装で扱う上で最重要です。

📐 定義 / 数式

🍰 まずはやさしく

計算の手順を決めた数式です。

正確な確率を出すために使います。

買い物で予算の割合を決める計算に似ています。

詳しい数式の意味を解説します。

【softmax】
$$\sigma(z)_i = \frac{e^{z_i}}{\sum_{j=1}^{K} e^{z_j}}, \quad i=1, \ldots, K$$
【Temperature 付き】
$$\sigma(z; T)_i = \frac{e^{z_i/T}}{\sum_{j} e^{z_j/T}}$$
$T \to 0$ で argmax に、 $T \to \infty$ で一様分布に
【偏微分】
$$\frac{\partial \sigma_i}{\partial z_j} = \sigma_i (\delta_{ij} - \sigma_j)$$
クロスエントロピーと組み合わせると微分が簡単

📐 数式の読み解き ── ソフトマックス関数 の核心式

$$ \text{softmax}(z)_i = \frac{\exp(z_i / T)}{\sum_{j=1}^K \exp(z_j / T)} $$

温度 $T$ 付きソフトマックス。 $T \to 0$ で argmax、 $T \to \infty$ で一様分布に近づく。

数式の各記号が『何の量で、 どの空間に住み、 どんな単位を持つか』を意識すると、 暗記でなく構造として理解できます。 SSDSE-B の都道府県データに当てはめて、 各シンボルが何に対応するかを上の Python 実装で確認しましょう。

❓ FAQ ── ソフトマックス関数 のよくある質問

Q1. ソフトマックス関数 を初めて学ぶ場合、 何から始めればよい?

まずは本ページの『💡 30 秒で分かる結論』と『🎨 直感で掴む』で全体像を掴み、 次に『🧮 実値で計算してみる』を 手を動かして追体験するのが最短です。 数式や深い理論はその後で十分。

Q2. ソフトマックス関数 と似た手法との違いは?

本ページの『🌐 関連手法・派生』『🔗 関連用語』で対比される手法を確認し、 それぞれの適用条件得意・不得意を表で比較するのが効果的です。 SSDSE-B のような共通データセットで両方走らせて結果を見ると違いが体感できます。

Q3. ソフトマックス関数 の計算量・スケーラビリティは?

Softmax の計算量は出力クラス数 $K$ に対して $O(K)$(指数を $K$ 回とって和で割る)と軽いのですが、 問題になるのは $K$ が語彙サイズになる場面です。 言語モデルの出力層は $K = 50{,}000$ 前後あり、 直前の隠れ層が $d=768$ なら行列積だけで $768 \times 50{,}000 \approx 3{,}840$ 万回の積和が 1 トークンごとに走ります。 これは Transformer 本体より重くなることさえあります。 対策が階層 Softmax($O(\log K)$)やサンプリング近似(Negative Sampling)です。 なお SSDSE の 47 都道府県を分類する程度($K=47$)なら何も気にする必要はありません。 「$K$ が数万を超えたら Softmax がボトルネックになりうる」という境界だけ覚えてください。

Q4. ソフトマックス関数 の結果をどう報告すべき?

『点推定値』だけでなく『不確実性(CI、 SE、 分散)』『前提条件のチェック結果』『代替手法との比較』『データ取得日と seed』をセットで報告するのが標準。 査読・レビューで問われる典型ポイントです。

📐 ソフトマックスとクロスエントロピーの微分

多クラスクロスエントロピー損失 $L = -\sum_i y_i \log p_i$($y$ は one-hot)の、 ロジット $z_j$ に対する勾配は驚くほどシンプル:

$$ \frac{\partial L}{\partial z_j} = p_j - y_j $$

これは「予測確率 - 正解の one-hot」、 つまり残差そのもの。 シグモイドの場合と同じく、 ソフトマックスの微分項とクロスエントロピーの微分項が美しくキャンセルして、 シンプルな式になります。

手計算例:3 クラス、 1 サンプル

$z = [2.0, 1.0, 0.1]$、 正解 $y = [1, 0, 0]$(クラス 0)とすると:

この計算をすべてのサンプルで足し合わせ、 重み $W$ への勾配 $\sum_i (p^{(i)} - y^{(i)}) (x^{(i)})^T$ を計算し、 学習率を掛けて重みを更新する。 これが多クラス分類器の学習の核心です。

🔬 記号・式を言葉で読み解く

$z_i$(logit)
i 番目クラスの生スコア。 任意の実数。
$e^{z_i}$
指数関数で正の値に。 logit の大きさを強調。
分母
全クラスの $e^z$ の合計で割って、 全クラスの確率を合計 1 に。
Temperature
鋭さの調整パラメータ。 LLM では生成の多様性に使う。

🔬 ソフトマックスの心臓部:log-sum-exp トリック

ソフトマックス $p_i = \frac{e^{z_i}}{\sum_j e^{z_j}}$ をそのまま計算すると、 $z_i$ が大きいと $e^{z_i}$ がオーバーフロー($e^{1000}$ で無限大)、 小さいと全部 0 でゼロ除算になります。 標準実装では log-sum-exp トリックを使い、 $z_{\max} = \max_j z_j$ を引いてから指数化します:

$$ p_i = \frac{e^{z_i - z_{\max}}}{\sum_j e^{z_j - z_{\max}}} $$

こうすると、 最大値が 0 になるよう正規化されるため、 $e^0 = 1$ から始まり、 オーバーフローは絶対に起きません。 また分母にゼロも入りません(必ず最低 1 つは 1 が入る)。 ソフトマックスを自分で実装するときは、 必ずこのトリックを入れること。

1
2
3
4
5
6
7
import numpy as np
def stable_softmax(z):
    z_shift = z - np.max(z, axis=-1, keepdims=True)
    exp_z = np.exp(z_shift)
    return exp_z / np.sum(exp_z, axis=-1, keepdims=True)
# テスト:極端に大きな値でも安全
print(stable_softmax(np.array([1000, 999, 998])))   # [0.665, 0.245, 0.09]
📤 実行例(実測) [0.66524096 0.24472847 0.09003057]

log_softmax と CrossEntropyLoss の一体化

PyTorch の nn.CrossEntropyLoss は、 内部で log_softmax + nll_loss を一体化して計算します。 これは $\log(\frac{e^{z_y}}{\sum_j e^{z_j}}) = z_y - \log \sum_j e^{z_j}$ の右辺を直接計算することで、 中間のソフトマックス値を経由せず、 数値安定性と速度を両立しています。 自分の損失を書くときも、 F.cross_entropy(logits, labels) を使うのが鉄則です。

1
2
3
4
5
6
import torch
import torch.nn.functional as F
logits = torch.tensor([[2.0, 1.0, 0.1], [0.5, 2.5, 1.0]])
labels = torch.tensor([0, 1])
loss = F.cross_entropy(logits, labels)
print(f'CrossEntropyLoss: {loss:.4f}')   # 0.3617
📤 実行例(実測) CrossEntropyLoss: 0.3617

自分でソフトマックス → log → NLL の順に書くと、 log(0) で NaN が出やすい。 一体化された cross_entropy を使うべき理由はここにあります。

🧮 実データで計算してみる

3 クラス分類(猫/犬/鳥)のロジット = [2.0, 1.0, 0.1] のとき:

  • $\text{softmax}([2.0, 1.0, 0.1])$
  • $e^{2.0} = 7.389, e^{1.0} = 2.718, e^{0.1} = 1.105$
  • 合計 = 11.212
  • 確率 = [0.659, 0.242, 0.099]
  • 予測クラス:猫(最大確率 0.659)

🧮 SSDSE-B 実値で計算してみる ── ソフトマックス関数

47 都道府県を「人口に応じた重み付き選択」する場面で softmax が使える。 例:人口(A1101)を logit として softmax をかけると、 各県の人口比重に応じた確率になる。 温度 T を上げると一様、 下げると最大県(東京都)に集中する分布になる。

項目 条件 / 入力 結果 / 解釈
東京都 (1409万)logit 14.09softmax 値 約 0.98
神奈川県 (923万)logit 9.23softmax 値 約 0.008
大阪府 (876万)logit 8.76softmax 値 約 0.005
愛知県 (748万)logit 7.48softmax 値 約 0.001
鳥取県 (53.7万)logit 0.537softmax 値 約 0.000

※ 数値は SSDSE-B-2026.csv から抽出した実値、 もしくは典型的な学習設定での目安値です。 細部の数値は前処理・乱数 seed・実装により変動します。

🧮 温度パラメータの効果:数値実験

ロジット $[5, 3, 1]$ に対し、 温度 $T$ を変えてソフトマックスを計算した結果を見てみましょう。

温度 Tクラス 0クラス 1クラス 2エントロピー
0.50.9820.0180.00030.093
1.00.8670.1170.0160.441
2.00.6650.2450.0900.832
5.00.4720.3160.2121.047
20.00.3670.3320.3011.095

温度が低いとクラス 0 への確率がほぼ 1(決定論的)、 温度が高いと 3 クラスに均等に近づく(最大エントロピー $\log 3 \approx 1.099$)。 LLM の生成で「temperature=0.7」が選ばれるのは、 「ある程度の創造性を持ちつつ、 意味のある文字列を生成する」バランスのため。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import numpy as np
def softmax_T(z, T):
    z = np.array(z)/T
    z = z - z.max()
    e = np.exp(z)
    return e / e.sum()

logits = [5, 3, 1]
for T in [0.5, 1.0, 2.0, 5.0, 20.0]:
    p = softmax_T(logits, T)
    H = -np.sum(p * np.log(p + 1e-12))
    print(f'T={T}: probs={np.round(p,3)}, entropy={H:.3f}')
📤 実行例(実測) T=0.5: probs=[0.982 0.018 0. ], entropy=0.093 T=1.0: probs=[0.867 0.117 0.016], entropy=0.441 T=2.0: probs=[0.665 0.245 0.09 ], entropy=0.832 T=5.0: probs=[0.472 0.316 0.212], entropy=1.047 T=20.0: probs=[0.367 0.332 0.301], entropy=1.095

🔧 ソフトマックスの実装パターン総覧

1. NumPy で stable softmax

1
2
3
4
5
import numpy as np
def softmax(z, axis=-1):
    z = z - np.max(z, axis=axis, keepdims=True)
    e = np.exp(z)
    return e / np.sum(e, axis=axis, keepdims=True)

2. SciPy の softmax

1
2
from scipy.special import softmax as sp_softmax
p = sp_softmax([5, 3, 1])

3. PyTorch の softmax / log_softmax

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import torch
import torch.nn.functional as F

# logits / labels をテンソルで用意する(リストのままだと .softmax が呼べない)
logits = torch.tensor([[2.0, 0.5, 0.1], [0.2, 1.8, 0.3],
                       [0.1, 0.2, 2.5], [1.2, 1.0, 0.9]])
labels = torch.tensor([0, 1, 2, 0])

import torch.nn.functional as F
p = F.softmax(logits, dim=-1)
log_p = F.log_softmax(logits, dim=-1)   # 数値安定
loss = F.cross_entropy(logits, labels)   # 内部で log_softmax + nll

4. TensorFlow の softmax

1
2
3
4
import tensorflow as tf
p = tf.nn.softmax(logits)
log_p = tf.nn.log_softmax(logits)
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(labels, logits)

5. 温度付きソフトマックス

def softmax_with_temperature(logits, T):
    return F.softmax(logits / T, dim=-1)

6. ソフトマックスのサンプリング

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import torch
import torch.nn.functional as F

# logits / labels をテンソルで用意する(リストのままだと .softmax が呼べない)
logits = torch.tensor([[2.0, 0.5, 0.1], [0.2, 1.8, 0.3],
                       [0.1, 0.2, 2.5], [1.2, 1.0, 0.9]])
labels = torch.tensor([0, 1, 2, 0])

import torch
probs = F.softmax(logits, dim=-1)
sample = torch.multinomial(probs, num_samples=1)
# top-k や top-p サンプリングも可能

実装は短いが、 「どの場面でどれを使うか」の判断が重要。 推論時の確率取得には F.softmax、 損失計算には F.cross_entropy(内部で log_softmax)、 サンプリングには torch.multinomial、 と使い分けます。

🧮 数式に値を入れて手で計算する: Softmax

合成 logits=[1, 2, 3] で Softmax 確率を計算する。

Step 1: 指数

e^1 = 2.718 e^2 = 7.389 e^3 = 20.086 合計 = 30.193

Step 2: 確率

p_1 = 2.718/30.193 ≈ 0.0900 p_2 = 7.389/30.193 ≈ 0.2447 p_3 = 20.086/30.193 ≈ 0.6652 合計 = 1.000 ✓

🐍 Python で再現

1
2
3
4
5
6
import numpy as np
z = np.array([1, 2, 3])
e = np.exp(z)
p = e / e.sum()
print(f"p: {p.round(4)}")
print(f"合計: {p.sum()}")

📤 実行結果

p: [0.09 0.2447 0.6652] 合計: 1.0

💬 手計算 (Step 2) と Python 出力が完全一致。

🎮 触って理解する

4 クラス分のロジット $z_i$(各バーを上下にドラッグ、 またはスライダーで調整)と温度 $T$ を動かして、 $\text{softmax}(z/T)$ の確率分布がリアルタイムに変わる様子を体感してください。 $T \to 0$ で argmax の one-hot に、 $T \to \infty$ で一様分布(各 1/4)に近づく「温度」の効果が一目で分かります。 下の計算テーブルでは数値安定化(max 減算)後の中間値とクロスエントロピー損失も同時に確認できます。

 
正解クラス(CE 損失用):

※ 計算テーブルの「z/T − max」列が数値安定化(max 減算)の中間値。 最大ロジットが必ず 0 になるため e⁰=1 から始まり、 オーバーフローが起きません。

🎨 何が起きているか ── 指数の「引き伸ばし」と正規化

ソフトマックスの本質は 2 段階です。 まず指数関数 $e^{z_i/T}$ がロジットの差を指数的に引き伸ばします(差が 1 あれば比は e≈2.72 倍、 差が 3 あれば約 20 倍)。 次に合計で割る正規化により、 合計 1 の確率分布に押し込みます。 初期値のロジット $[2.0,\ 0.5,\ -1.0,\ 1.0]$ を $T=1$ で通すと確率は $[0.610,\ 0.136,\ 0.030,\ 0.224]$(エントロピー H≈1.014)。 ロジット差 1.0(A と D)が確率比 2.72 倍に増幅されているのが分かります。 温度 $T$ は「引き伸ばしの強さ」を割り算で調整するツマミで、 T=0.2 なら $[0.993,\ 0.001,\ 0.000,\ 0.007]$ とほぼ one-hot(argmax)T=20 なら $[0.267,\ 0.248,\ 0.230,\ 0.254]$ とほぼ一様分布(4 クラスの最大エントロピー $\log 4 \approx 1.386$ に接近)になります。 ウィジェットのプリセットボタンでこの両極端を往復してみてください。

正解クラスを A に選ぶと、 クロスエントロピー損失は $-\log p_A$。 初期状態(T=1)では $-\log 0.610 \approx 0.495$ です。 A のロジットを上げると損失が下がり、 他クラスのロジットを上げると損失が上がる ── クロスエントロピーが「正解クラスの確率だけを見る」損失であること、 そして勾配が $p - y$(予測確率 − one-hot)というシンプルな残差になることを、 バーの動きと損失表示の連動で確かめられます。

⚠️ 落とし穴 ── オーバーフローと「過信」

(1) オーバーフロー:素朴に $e^{z}$ を計算すると、 $z=1000$ で $e^{1000}$ は浮動小数点の上限を超え inf になります(JavaScript でも Math.exp(1000) === Infinity)。 上のウィジェットは常に max 減算($z/T - \max_j z_j/T$)をしてから指数化しており、 計算テーブルでその中間値を見られます。 max 減算をしても結果は数学的に同一で、 例えばロジット $[1000, 999, 998]$ でも安全に $[0.665,\ 0.245,\ 0.090]$ が得られます。 (2) 過信(較正の欠如):ロジットを 1 本だけ +5 まで引き上げると確率は 0.98 前後まで張り付きますが、 これは「98% 正しい」ことを意味しません。 学習が進んだ深層モデルはロジットの絶対値が大きくなりがちで、 softmax 確率は系統的に過信気味になります。 業務判断に使う前に ECE(Expected Calibration Error)で較正度を確認し、 必要なら次に述べる温度スケーリングで補正するのが定石です。

🚀 発展 ── 温度スケーリング・LLM のサンプリング温度・Gumbel-Softmax

温度スケーリング(較正):検証データで負の対数尤度を最小化する $T$ を 1 次元探索し、 推論時に $\text{softmax}(z/T)$ を出力する最もシンプルな較正法。 過信モデルでは $T>1$(分布を平らに)が選ばれることが多い ── まさに上のスライダーで T を 1 から 2 へ動かしたときの変化です。 LLM のサンプリング温度LLM が次トークンを選ぶ最終段も softmax です。 生成 API の temperature パラメータはこの $T$ そのもので、 T→0 の greedy(決定論的)から T が大きい多様・ランダムな生成までを連続的に制御します。 top-k / top-p サンプリングは、 この温度付き分布の裾を切り落とす追加の工夫です。 Gumbel-Softmax(用語ページは未整備):「分布から 1 つサンプリングする」という微分不可能な離散操作を、 Gumbel ノイズ + 温度付き softmax で微分可能に近似する手法。 学習中は温度を高めから徐々に下げる(アニーリング)ことで、 連続近似から one-hot に近い離散選択へ滑らかに移行させます ── T スライダーを 20 から 0.05 へゆっくり下げる操作は、 このアニーリングの疑似体験になっています。

2 クラスに減らした softmax はシグモイドと等価であり、 隠れ層で使う ReLU などとの位置づけの違いは活性化関数のページで、 softmax が「重みの配分器」として働くAttention / Transformer での役割はそれぞれのページで確認できます。 多項ロジスティック回帰は「線形層 + softmax + クロスエントロピー」そのものです。

🐍 Python 実装

SSDSE-B-2026(47 都道府県・2023 年データ)を題材にした最小コード:

🎯 このコードでやること:logits ベクトル [2.0, 1.0, 0.1] を softmax で確率分布に変換。 数値安定化(max 引き)と Temperature 制御の挙動も併せて確認します。
📥 入力例(SSDSE-B-2026 サンプル) # logits(都道府県の地域分類予測スコアなど 3 クラス想定) z = [2.0, 1.0, 0.1] # Temperature(推論時の確率の鋭さ) temperature = 1.0 # → 5.0 で平坦化
📤 実行例(期待出力) [0.6590 0.2424 0.0986] # T=1.0 の確率分布(合計 1.0) [0.3996 0.3272 0.2733] # T=5.0 の確率分布(より平坦に)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import numpy as np

def softmax(z, temperature=1.0):
    z = np.asarray(z) / temperature
    z = z - z.max()  # 数値安定化
    e = np.exp(z)
    return e / e.sum()

print(softmax([2.0, 1.0, 0.1]))
# [0.659, 0.242, 0.099]

# Temperature を上げると分布が平坦に
print(softmax([2.0, 1.0, 0.1], temperature=5.0))
📤 実行例(実測) [0.65900114 0.24243297 0.09856589] [0.39958568 0.32715309 0.27326123]
💬 読み方:T=1 では最大 logit のクラス A に 65.9% の確率が集中。 T=5 にすると分布が平坦化し、 すべてが 25〜40% 付近に均される。 推論時の「自信」を制御するパラメータが Temperature。

🐍 SSDSE-B を使った Python 実装

公的データ SSDSE-B(47 都道府県社会・人口統計)を読み込み、 ソフトマックス関数 を実際に動かす最小コードです。 引数のパスは平易さ優先で直書きしています。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) 北海道 5,092,000 東京都 14,086,000 沖縄県 1,468,000 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import pandas as pd
import numpy as np

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=[1], encoding='cp932')
df = df[df['SSDSE-B-2026'] == 2023].reset_index(drop=True)   # 英字コードを使うので skiprows=[1]
pop = df['A1101'].astype(float).values

def softmax(z, T=1.0):
    z = z / T
    z = z - z.max()  # 数値安定化
    e = np.exp(z)
    return e / e.sum()

# 各都道府県の人口比重を softmax で表現
weights = softmax(pop / 1e6, T=1.0)
for name, w in zip(df['Prefecture'], weights):
    print(f'{name}: {w:.4f}')
📤 実行例(実測) 北海道: 0.0001 青森県: 0.0000 岩手県: 0.0000 宮城県: 0.0000 秋田県: 0.0000 山形県: 0.0000 福島県: 0.0000 茨城県: 0.0000 栃木県: 0.0000 群馬県: 0.0000 埼玉県: 0.0011 千葉県: 0.0004 東京都: 0.9841 神奈川県: 0.0077 新潟県: 0.0000 富山県: 0.0000 石川県: 0.0000 福井県: 0.0000 山梨県: 0.0000 長野県: 0.0000 岐阜県: 0.0000 静岡県: 0.0000 愛知県: 0.0013 三重県: 0.0000 滋賀県: 0.0000 京都府: 0.0000 大阪府: 0.0048 兵庫県: 0.0002 奈良県: 0.0000 和歌山県: 0.0000 鳥取県: 0.0000 島根県: 0.0000 岡山県: 0.0000 広島県: 0.0000 山口県: 0.0000 徳島県: 0.0000 香川県: 0.0000 愛媛県: 0.0000 高知県: 0.0000 福岡県: 0.0001 佐賀県: 0.0000 長崎県: 0.0000 熊本県: 0.0000 大分県: 0.0000 宮崎県: 0.0000 鹿児島県: 0.0000 沖縄県: 0.0000

※ 上記スニペットは Python 3.10+ / pandas 2.x / numpy / scikit-learn を想定。 環境構築は『conda create -n ds python=3.11 pandas scikit-learn matplotlib』で十分です。

🐍 SSDSE-B-2026 で「都道府県を 3 地域に分類」

SSDSE-B-2026 の 47 都道府県を「都市型(人口 ≥ 300 万)」「中規模(100 万 ≤ 人口 < 300 万)」「過疎型(人口 < 100 万)」の 3 クラスに分類する多クラス分類問題で、 ソフトマックスの動きを観察しましょう。

📥 入力例(SSDSE-B-2026 の 2023 年・47 都道府県から 3 行) 都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) A4200(死亡数) C3301(着工建築物数) 北海道 5,092,000 1,681,000 24,430 75,120 15,872 東京都 14,086,000 3,205,000 86,348 137,241 41,817 沖縄県 1,468,000 350,000 12,549 15,110 5,217 …(全 47 行)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import pandas as pd
import numpy as np
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', skiprows=[1])

# 3 クラス目的変数
def classify(p):
    if p >= 3_000_000: return 0   # 都市型
    elif p >= 1_000_000: return 1  # 中規模
    else: return 2                  # 過疎型

df['y3'] = df['A1101'].apply(classify)
print(df['y3'].value_counts())

# 説明変数
X = df[['A4101', 'A4200', 'C3301', 'A1303']].values   # 出生・死亡・着工建築物・高齢
Xs = StandardScaler().fit_transform(X)

# 多クラスロジスティック回帰(内部でソフトマックス)
model = LogisticRegression(solver='lbfgs', max_iter=2000)   # multi_class は sklearn 1.7 で削除(多クラスは既定で multinomial)
model.fit(Xs, df['y3'])

# 全 47 県の予測確率
proba = model.predict_proba(Xs)
print('確率分布の合計(各行):', proba.sum(axis=1)[:5])   # 必ず 1.0
print('予測:', model.predict(Xs[:5]))
📤 実行例(実測) y3 1 329 0 120 2 115 Name: count, dtype: int64 確率分布の合計(各行): [1. 1. 1. 1. 1.] 予測: [0 0 0 0 0]

ソフトマックスの出力は「各クラスの確率」で、 必ず合計が 1 になることを確認してください。 ロジット(線形結合)の値そのものは [-10, 10] 程度の範囲でも、 ソフトマックスを通すと [0, 1] の確率に正規化されます。

温度パラメータでソフトマックスを鋭くする

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
def softmax_with_T(z, T=1.0):
    z = z / T
    z = z - z.max(axis=-1, keepdims=True)
    e = np.exp(z)
    return e / e.sum(axis=-1, keepdims=True)

# logits を取り出して温度実験
logits = Xs @ model.coef_.T + model.intercept_
for T in [0.5, 1.0, 2.0, 10.0]:
    p = softmax_with_T(logits[0], T)
    print(f'T={T}: {np.round(p, 3)}')
📤 実行例(実測) T=0.5: [1. 0. 0.] T=1.0: [0.994 0.006 0. ] T=2.0: [0.926 0.074 0. ] T=10.0: [0.608 0.367 0.026]

$T=0.5$ だと最大確率のクラスが 0.99 に近づき、 $T=10$ だと 3 クラスが 0.33 ずつに均等化します。 LLM の「temperature」パラメータはまさにこの $T$ で、 「決定論的(T 低い)」か「創造的(T 高い)」かを制御しています。

🐍 補強コード例 1

🎯 このコードでやること:softmax を実データで動かす前段として、 SSDSE-B-2026 を読み込んで形状・列名を確認します。 softmax に渡すロジット列(人口 A1101 など)がどの列コードで入っているかを把握するのが目的です。

📥 入力例(SSDSE-B-2026 全体:564 行 × 112 列 = 47 都道府県 × 2012〜2023 年) 年度 地域コード 都道府県 A1101(総人口) A1303(65歳以上人口) A4101(出生数) … 2023 R01000 北海道 5,092,000 1,681,000 24,430 … 2023 R13000 東京都 14,086,000 3,205,000 86,348 … 2023 R47000 沖縄県 1,468,000 350,000 12,549 … …(残り 112 列は住宅・家計・教育・医療など)
1
2
3
4
5
6
import pandas as pd

df = pd.read_csv('data/raw/SSDSE-B-2026.csv', skiprows=1, encoding='cp932')
print(df.shape)
print(df.head(3))
print(df.columns[:10].tolist())

📤 読み取り:列名が Prefecture, A1101, A1301… のような英字コードで並ぶことが確認できます。 softmax に渡す入力(例:総人口 A1101)は、 このコード名で列選択して取り出します。

⚠️ よくある落とし穴

⚠️ オーバーフロー
$e^{1000}$ は計算不能。 → max を引いてから指数化(数値安定化)。
⚠️ argmax と確率の混同
確率 0.51 と 0.49 でも予測クラスは決まるが、 信頼度は低い。
⚠️ 確率の校正
softmax の確率は較正されていないことが多い。 0.9 が「90% 正しい」とは限らない。
⚠️ 二値分類で softmax
二値ならシグモイドで十分。 softmax(2 次元) はシグモイドと等価。
⚠️ Temperature の選択
T を変えるとモデルの振る舞いが大きく変わる。 評価時は T=1 が標準。

⚠️ 追加の落とし穴 ── 実務で踏み抜く罠

❌ 1. オーバーフロー
logit が大きいと exp(z) が inf に。 必ず最大値を引く log-sum-exp トリックを使う。
❌ 2. 温度の選び方
T が大きすぎると一様、 小さすぎると argmax と同じ。 学習データ次第で要調整。
❌ 3. 確率的解釈の過信
softmax 値はキャリブレーションされていない。 信頼度として使うには温度補正(Platt scaling 等)が必要。
❌ 4. argmax との混同
argmax は離散・微分不可能、 softmax は連続。 学習中は softmax、 推論で argmax と使い分ける。
❌ 5. クラス不均衡
稀クラスは出力確率が常に低くなる。 損失関数側で重み付けまたは focal loss を併用。

⚠️ ソフトマックスの落とし穴:実務での失敗パターン

  1. マルチラベルに使ってしまう:写真に「犬・猫・人」が同時に写っているケースで、 ソフトマックスを使うと「最も自信のあるクラス 1 つだけ」しか予測できない。 → 各ラベル独立にシグモイドが正解。
  2. クラス間の独立性を仮定する:ソフトマックスは「クラス間の相対比」しか学習しない。 全クラスのロジットを 100 加算しても結果は同じ。 これは「絶対的な確信度」が欲しい場面では弱点。
  3. クラス数が極端に多い場合の計算量:1000 クラス以上だと、 ソフトマックスの計算と勾配計算がボトルネック。 Hierarchical Softmax、 Sampled Softmax、 Noise Contrastive Estimation などの近似手法を使う。
  4. ロジットの過剰な広がり:訓練が進むと最大ロジットが 50、 100 を超え、 確率がほぼ one-hot になる。 校正されていない自信過剰モデル。 → ラベルスムージング(label smoothing)で抑制。
  5. 未知クラス(out-of-distribution)への対応:ソフトマックスは「必ず合計 1 の確率」を出すので、 訓練データにないクラスが入力されても自信を持って何かを予測してしまう。 → softmax temperature、 ODIN、 energy-based detection などで補強。

ソフトマックスは「強い前提(クラスは排他、 全クラスを尽くす)」を持つので、 その前提が崩れる場面(マルチラベル、 OOD)では別の手法に切り替える判断力が重要。 統計コンペでも、 「なぜソフトマックスを選んだか」を明示できると、 分析の説得力が上がります。

🗺 ソフトマックス関数 の概念マップ

『ソフトマックス関数』は『活性化関数』カテゴリに属する重要概念で、 以下の関連概念群と密接につながっています。

活性化関数
  ├── 前提
  │   ├── 指数関数 exp(z) と正規化(総和 1 への変換)
  │   └── ロジット(線形和)と確率の対応
  ├── ソフトマックス関数  ← このページ
  │   ├── 派生: 温度付き Softmax(蒸留・サンプリング)
  │   ├── 派生: Log-Softmax(数値安定性、 cross-entropy と連結)
  │   └── 応用: 多クラス分類の出力層/Attention 重み/強化学習方策
  └── 代替の確率化・離散化手法
      ├── シグモイド(二値分類、 各次元独立確率)
      └── argmax/Gumbel-Softmax(離散選択の確率的近似)
  

完全な概念マップは 🗺 概念マップ で確認できます。

📋 学習チェックリスト ── ソフトマックス関数 を使いこなすために

📜 歴史と発展

1959 年 Luce の選択公理で連続化された分類モデルとして登場。 統計力学のボルツマン分布が起源。 ニューラルネットの多クラス分類層として標準。 注意機構(2014, Bahdanau)、 強化学習の方策(policy gradient)、 強化学習の温度サンプリングと、 現代 ML の至る所で活躍。

起源は 2 つあります。 統計力学のボルツマン分布と、 Luce (1959) の選択公理です。 前者から来るのが「温度」パラメータ $T$ で、 $T$ を下げると分布が尖り、上げると平らになるという直感はそのまま物理の比喩です。 後者は「選択肢 A と B の選ばれやすさの比は、 第 3 の選択肢 C の有無に影響されない」という公理(IIA)で、 softmax はこの公理を満たす唯一の形として導かれます。 生成 AI の temperature 設定は、 この 2 つの系譜が合流した場所です。

🚀 応用事例 ── ソフトマックス関数 はどこで使われているか

『ソフトマックス関数』は理論だけでなく、 産業・研究の様々な現場で実用されています。 ここでは代表的な応用を 6 つ挙げます。

どの応用も「何を入力とし、 何を出力すべきか」を整理した上で、 上の Python 実装をベースに拡張するアプローチが定石です。 SSDSE-B のような公開データセットで小さく試し、 動作確認できてから本番データに展開すると安全です。

📊 ベンチマーク比較 ── ソフトマックス関数 の主要バリエーション

『ソフトマックス関数』には多くの派生・バリエーションがあります。 代表的なものを精度・特徴で比較した表です。

手法 / バージョン 指標 / 特徴 備考
通常 softmax$O(K)$K クラス出力
Hierarchical Softmax$O(\log K)$大語彙向け
Sampled Softmaxサンプル近似学習時のみ
Gumbel Softmax離散変数の連続化微分可能
Sparsemaxスパース出力解釈性↑

数値は論文公表時点のもので、 計測条件(データ・前処理・ハイパーパラメータ)が異なります。 自分の問題で再評価することを推奨。

✨ 実装ベストプラクティス ── ソフトマックス関数 を堅牢に使う

  1. 小さく始める — SSDSE-B の 47 行のような小データでパイプライン全体を確立してから本番データへ。
  2. seed を固定 — numpy, torch, random の全 seed を記録。 再現性チェックは必須。
  3. バージョン管理 — requirements.txt と環境スナップショット、 データの取得日を記録。
  4. 段階的に複雑化 — まずベースライン(線形、 ロジスティック)→ 古典的 ML → ソフトマックス関数 の順。 突然複雑化しない。
  5. 可視化を欠かさず — 学習曲線、 特徴分布、 残差プロットを毎回確認する。
  6. テスト集合を分離 — 探索・調整に絶対使わない『最終評価』用データを別途確保。
  7. ハイパーパラメータは記録 — 全実験で何を試したか mlflow / wandb / spreadsheet に。
  8. 失敗パターンも残す — 「ダメだった設定」も価値がある。 後輩や未来の自分が助かる。

🔍 似た用語との違い ── ソフトマックス関数 を正確に切り分ける

『ソフトマックス関数』は周辺の似た用語と混同されがちです。 ここでは特に紛らわしい用語との本質的な違いを整理します。

📖 さらに深く学ぶリソース

教科書・本

論文プラットフォーム

ライブラリ・実装

公開データセット

ソフトマックス関数 エネルギーが低い状態 確率が高い 温度が高い 確率が均等化 温度が低い 最小エネルギー状態に集中

🔗 隣接手法への橋渡し

「Softmax 関数」は K 個の実数ベクトルを和 1 の確率分布に変換する活性化関数 であり、 上流の線形層 (logits 出力) と下流の交差エントロピー損失・多クラス分類意思決定を繋ぐ。 Sigmoid の多クラス版と捉えられるが、 出力間の相互依存が本質的に異なる。

⬆️ 上流: 数学・確率の基礎

⬌ 並列: 他の活性化関数

⬇️ 下流: 応用モデル

Softmax は K クラス分類で線形値 → 確率ベクトル変換を担い、 sigmoid の自然な拡張として多項ロジスティック回帰・NN の出力層・クロスエントロピー損失とセットで設計する。

🌳 手法選択フロー

「softmax 関数」を使うかは、 多クラス確率出力か順位付けかで判断する。

  1. 多クラス分類で確率を欲しいか? Yes → softmax を出力層に、 CrossEntropy 損失、 No → 次へ
  2. 順位 (argmax) だけでよいか? Yes → softmax 不要、 logits の argmax で十分、 No → softmax で確率化
  3. 温度を調整するか? Yes → softmax(logits/T) の T を上げると平滑化 (生成モデルで頻用)、 No → 通常の softmax

softmax は logits の指数を正規化する。 47 都道府県の 人口割合 (A1101 / 全国計) を softmax で得られた値と比較すると合致する。

📝 追記補足 ── 平行移動不変性・2クラス=シグモイド・飽和による勾配消失

本ページ既出の直感・落とし穴・発展を壊さずに、 実務で特につまずきやすい 3 点を SSDSE-B-2026(2023 年・47 都道府県)の実測値で補強します。 合成したロジットベクトルには「架空」と明記します。

① ロジットの平行移動不変性 ── 効くのは「絶対値」ではなく「差」だけ

ソフトマックスは全ロジットに同じ定数 $c$ を足しても出力が変わりません:

$$ \sigma(z + c\mathbf{1})_i = \frac{e^{z_i + c}}{\sum_j e^{z_j + c}} = \frac{e^{c}\,e^{z_i}}{e^{c}\sum_j e^{z_j}} = \sigma(z)_i $$

$e^c$ が分子・分母で約分されるためです。 数値安定化で $\max$ を引く($c=-\max_j z_j$)操作が結果を変えないのは、 まさにこの不変性の帰結。 ここから 2 つの重要な性質が出ます:(1) softmax の出力を決めるのはロジットの差 $z_i - z_j$ だけ、 (2) $K$ 本のロジットの自由度は実質 $K-1$ で、 1 クラスを基準(0)に固定できる ── 本ページ『多項ロジスティック回帰の数学』で触れた参照クラスと同じ話です。 したがって「クラス A の生スコアが 100 だから自信がある」という読み方は誤りで、 他クラスとの相対差を見なければ確率は決まりません。

SSDSE-B 実測での確認:2023 年人口 A1101 の実測は 東京都 14,086,000・神奈川県 9,229,000・大阪府 8,763,000・愛知県 7,477,000・鳥取県 537,000(全国計 124,353,000)。 これらの対数をロジットとして softmax を取ると、 全都道府県の log-人口に一律で $+10$ を足しても(=人口を $e^{10}$ 倍しても)確率分布は 1 ビットも動きません。 効くのは「東京の log-人口が鳥取より約 3.26 大きい($\ln(14{,}086{,}000/537{,}000)\approx3.27$)」というだけです。

② 2 クラス softmax はシグモイドと厳密に同一

①の「差だけが効く」を 2 クラスに当てはめると、 softmax がシグモイドに一致することが導けます:

$$ \sigma(z)_0 = \frac{e^{z_0}}{e^{z_0} + e^{z_1}} = \frac{1}{1 + e^{-(z_0 - z_1)}} = \mathrm{sigmoid}(z_0 - z_1) $$

つまり 2 クラス softmax は「2 本のロジットの差」を 1 個のシグモイドに通したものと同じ。 2 値分類でクラスごとに 2 本のロジットを持たせるのは冗長で、 差 1 本(シグモイド)で十分 ── という本ページ既出の主張の、 数式的な裏付けです。

SSDSE-B 実測での確認:東京都と神奈川県の 2 県だけを取り、 log-人口をロジットにすると差は $\ln(14{,}086{,}000) - \ln(9{,}229{,}000) = 0.4228$。 このとき softmax は $[0.6042,\ 0.3958]$、 一方 $\mathrm{sigmoid}(0.4228) = 0.6042$ で完全に一致します。 なお生の人口をそのままロジットにすると差が約 486 万と巨大になり、 softmax はほぼ $[1,\ 0]$ に飽和します(次項③)。 「何を logit として渡すか(生値か log か)」でスケールが激変する点に注意してください。

③ 飽和による勾配消失 ── 確率が 0/1 に張り付くと学習が止まる

softmax のヤコビアン $\partial p_i/\partial z_j = p_i(\delta_{ij} - p_j)$(本ページ既出)は、 ある確率 $p_i$ が 0 または 1 に近づくと成分がすべて 0 に潰れます($p_i(1 - p_i)\to 0$)。 これが飽和による勾配消失です。 ロジットの差が大きすぎて分布が尖りすぎると、 たとえ誤分類していても内部勾配がほぼ流れず、 学習が進まなくなります。

架空のロジットベクトルでの例(合成・架空):$z = [10,\ 0,\ 0]$ を softmax にかけると $p \approx [0.99991,\ 0.000045,\ 0.000045]$。 クロスエントロピーの勾配 $\partial L/\partial z = p - y$ 自体は残差として働きますが、 各クラスの内部勾配 $p_i(1 - p_i)$ は $4.5\times10^{-5}$ 程度まで縮小しており、 わずかな更新しか生みません。 実務での対処は本ページ既出の道具立てと同じ系譜です:(a) Attention では $\sqrt{d_k}$ で割ってロジットの分散を抑える、 (b) 出力の過信は温度スケーリング($T > 1$)で緩和、 (c) 学習時はクロスエントロピー+ラベルスムージングでロジットが際限なく広がるのを抑制。 「softmax が飽和していないか」は、 出力エントロピー $H(p)$ が極端に小さくなっていないかで監視でき、 上の🎮ウィジェットの H 表示で体感できます。

関連ページ:シグモイド(②の 2 クラス版)/クロスエントロピー(勾配 $p-y$ の相方)/活性化関数ロジスティック回帰(①の参照クラス)/AttentionTransformer(③の $\sqrt{d_k}$ スケーリング)/分類ニューラルネット