もしかしたら同じ勘違いをしている人がいるかもしれないという事で、記事にしておきます。
sofmaxと言えば、分類問題などで使われる関数であり、以下のような特徴がある。
1.総和を1にする。
2.数値の大小は変わらない。
これは、深層学習を勉強した人なら、多くの人がお世話になったであろう「ゼロから作るdeep learning」の70ページ目にも書かれている。
しかしひょんな事から、その2の特徴は正確ではないという事に気が付いた。
最初から総和が1の配列をsoftmaxに通してみる。
def softmax(x):
if x.ndim == 2:
x = x.T
x = x - np.max(x, axis=0)
y = np.exp(x) / np.sum(np.exp(x), axis=0)
return y.T
x = x - np.max(x) # オーバーフロー対策
return np.exp(x) / np.sum(np.exp(x))
x = np.array([0.7, 0.2, 0.1])
print(softmax(x))
test.py
[0.46396343 0.28140804 0.25462853]
総和が1である配列をsoftmaxに通したら同じ値のまま返ってくるという認識だったのだがそうではなかった。
次にsoftmaxの出力を再度softmaxに通す...という処理をしてみる。
import numpy as np
def softmax(x):
if x.ndim == 2:
x = x.T
x = x - np.max(x, axis=0)
y = np.exp(x) / np.sum(np.exp(x), axis=0)
return y.T
x = x - np.max(x) # オーバーフロー対策
return np.exp(x) / np.sum(np.exp(x))
x = np.array([0.7, 0.2, 0.1])
for _ in range(100):
x = softmax(x)
print(x)
test.py
[0.33333333 0.33333333 0.33333333]
最終的には、値が均一になる事がわかった。
この事から、softmaxに通した値の大小は変わらないというのは間違いである。