問題
ソフトマックス関数は、スコア(ロジット)のリストを確率に変換します。言語モデルは次の単語を選ぶのにこれを使います。
softmax(x)_i = e^(x_i) / (e^(x_1) + e^(x_2) + … + e^(x_n))
スコアが大きいと e^x がオーバーフローするので、まずすべてのスコアから最大のスコアを引いてください。数学的には結果は同じです。
softmax(logits) を実装してください。
入力
logits: スコアのリスト。
出力
確率のリストを同じ順序で返してください。すべて 0 から 1 の間にあり、合計は 1 になります。
制約
1 ≤ 長さ ≤ 1,000
-1,000 ≤ 各スコア ≤ 1,000
例
例 1
入力:
logits = [1.0, 2.0, 3.0]
期待される出力:
expected = [0.090031, 0.244728, 0.665241]
入力:
std::vector<double> logits = {1.0, 2.0, 3.0};
期待される出力:
std::vector<double> expected = {0.090031, 0.244728, 0.665241};
入力:
double[] logits = new double[] {1.0, 2.0, 3.0};
期待される出力:
double[] expected = new double[] {0.090031, 0.244728, 0.665241};
解説
e¹ ≈ 2.718、e² ≈ 7.389、e³ ≈ 20.086 の合計は 30.193 なので、確率は約 [0.090031, 0.244728, 0.665241] です。
例 2
入力:
logits = [1000.0, 1000.0]
期待される出力:
expected = [0.5, 0.5]
入力:
std::vector<double> logits = {1000.0, 1000.0};
期待される出力:
std::vector<double> expected = {0.5, 0.5};
入力:
double[] logits = new double[] {1000.0, 1000.0};
期待される出力:
double[] expected = new double[] {0.5, 0.5};
解説
e^1000 を直接計算するとオーバーフローします。最大値を引くと [0, 0] になり、どちらも e⁰ / (e⁰ + e⁰) = 0.5 です。
参考資料
この課題はCodeUtility用に調整されています。上記の説明と制約に従ってください。