ソフトマックス関数の数式

ニューラルネットワークで分類を行う際に出力層の活性化関数に「ソフトマックス関数」というものを使うらしいです。
この関数を使うと「確率」を出力することができるらしいです。
ざっくりとした例えになりますが・・・「猫と犬のどっちかな~?猫が65%犬が35%ぐらいで、おおよそ猫っぽいね!」と、いった分類ができるみたいです。
下の数式をみてください。
もうここまでくると私には解読が不可能ですねw
どうして、この数式が「確率」を導き出すのでしょうね?
さっさとプログラムを見てみましょう!

ソフトマックス関数のサンプルプログラム

2つのサンプルを用意しました。どちらも「ゼロから作るDeep Learning」からの抜粋です。何故か書籍に記載があったのが前者のソースコードで、ネットで公開されているサンプルが後者のソースコードになります。
速度改善でもされたのか?と処理速度を計測してみましたが、どちらも速度に大差はありませんでした。(0.0009秒ほど後者が速いw)
プログラムを見たら、その処理内容が解ると思っていたのが甘かったですね・・・もう少し「ゼロから作るDeep Learning」を読み込みたいと思いました。
def softmax(a):
c = np.max(a)
exp_a = np.exp(a - c) # オーバーフロー対策
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return ydef softmax(x):
x = x - np.max(x, axis=-1, keepdims=True)
return np.exp(x) / np.sum(np.exp(x), axis=-1, keepdims=True)ソフトマックス関数のグラフ

最後にグラフの紹介ですね。下のソースコードを実行すると以下のグラフを表示することができます。
ソフトマックス関数は、0から1.0までの間の実数を返し、その相和が1になる。という特徴があります。
この性質があることから、関数の出力を「確率」として解釈することができるということみたいです。
import matplotlib.pyplot as plt
import numpy as np
def softmax(x):
x = x - np.max(x, axis=-1, keepdims=True) # オーバーフロー対策
return np.exp(x) / np.sum(np.exp(x), axis=-1, keepdims=True)
x = np.arange(-0.5, 5.0, 0.1)
y = softmax(x)
plt.plot(x, y)
plt.ylim(-0.01, 0.1)
plt.show()

上記のグラフで出力されたデータをprint文で出力したのが以下の数字です。こちらの数値をすべてサマリしてみてください。結果が1になると思います。
この数値の1つ1つが「確率」として分類できるデータということですね。。。
こんな計算を一瞬で出来るなんて・・・
凄いですね~ソフトマックス関数!
[
0.00043157 0.00047696 0.00052712 0.00058256 0.00064383 0.00071154
0.00078638 0.00086908 0.00096048 0.0010615 0.00117314 0.00129652
0.00143287 0.00158357 0.00175012 0.00193418 0.0021376 0.00236241
0.00261087 0.00288545 0.00318892 0.0035243 0.00389495 0.00430459
0.00475731 0.00525764 0.00581059 0.00642169 0.00709707 0.00784347
0.00866838 0.00958004 0.01058758 0.01170109 0.0129317 0.01429174
0.01579482 0.01745597 0.01929184 0.02132078 0.0235631 0.02604125
0.02878004 0.03180686 0.03515202 0.03884899 0.04293477 0.04745026
0.05244065 0.05795588 0.06405115 0.07078747 0.07823225 0.08646001
0.09555309
]