からUdacityのディープラーニングクラスy_i のソフトマックスは、指数を Y ベクトル全体の指数の合計で割ったものになります。
ここでS(y_i)
、は のソフトマックス関数y_i
、e
は指数関数、j
は入力ベクトル Y の列数です。
私は次のことを試しました:
import numpy as np
def softmax(x):
"""Compute softmax values for each sets of scores in x."""
e_x = np.exp(x - np.max(x))
return e_x / e_x.sum()
scores = [3.0, 1.0, 0.2]
print(softmax(scores))
結果は次のようになります:
[ 0.8360188 0.11314284 0.05083836]
しかし、提案された解決策は次のとおりです。
def softmax(x):
"""Compute softmax values for each sets of scores in x."""
return np.exp(x) / np.sum(np.exp(x), axis=0)
最初の実装では各列の差と最大値を明示的に取得し、その合計で割っていますが、最初の実装と同じ出力が生成されます。
誰か数学的に理由を示してもらえますか? 1つは正しく、もう1つは間違っているのでしょうか?
コードと時間の複雑さの点で実装は似ていますか? どちらがより効率的ですか?
ベストアンサー1
どちらも正しいですが、数値の安定性の観点からはあなたの方法の方が好ましいです。
まず始めに
e ^ (x - max(x)) / sum(e^(x - max(x))
a^(b - c) = (a^b)/(a^c) という事実を利用すると、
= e ^ x / (e ^ max(x) * sum(e ^ x / e ^ max(x)))
= e ^ x / sum(e ^ x)
これは他の回答で言われていることです。max(x) を任意の変数に置き換えると、打ち消されます。