すべてのチャレンジ
簡単 0件解決済み 正答率0%

ソフトマックス関数

大きな値でもオーバーフローせずに、生のスコアを合計 1 の確率に変換します。

このチャレンジで学べること

  • スコアを確率に変換する
  • 最大値を引いてオーバーフローを避ける
  • 出力の合計を 1 にする

問題

原文(英語)を表示

ソフトマックス関数は、スコア(ロジット)のリストを確率に変換します。言語モデルは次の単語を選ぶのにこれを使います。

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用に調整されています。上記の説明と制約に従ってください。

他の人の解答から学ぶ

コミュニティの解答

まだ公開された解答がありません。この課題を解いて最初の解答を共有しましょう。