はじめに
筆者は機械学習についての知見が全くありません。なので特に機械学習の論理について誤った解釈をしていると思いますので、後々勉強して適宜訂正していこうと思います。
ソフトマックス関数とは
以下、wikipediaからの引用。
K 個のクラスに分類する。出力は K 個で、総和は 1 であり、そのクラスに所属する確率と解釈する。 は 0 または 1 もしくは確率で、n 番目の訓練データがクラス k に所属する時 1。 。交差エントロピーを使用している。この活性化関数はソフトマックス関数と呼ばれる。
活性化関数:
引用元:活性化関数
ありがとうwikiさん。ざっくり解釈だと幾つかの大小様々な実数を足して1.0になるような実数に変えてくれる関数だと思います。
式をもう少し簡単に書くと
x = [x0,x1,x2,...,xn]
u = exp(x0)+exp(x1)+exp(x2)+...+exp(en)
y0 = exp(x0)/u , y1 = exp(x1)/u , y2 = exp(x2)/u , .... ,yn = exp(xn)/u
y = [y0,y1,y2,...,yn]
n次元の実数ベクトルxを受け取り、n次元実数ベクトルyを返します。
確率なので当然
y_sum = y0 + y1 + y2 + ... = 1
0 < yi < 1
となります。
いつ使うのか
書いた文字が「め」か「ぬ」を判別するプログラムがあるとし、ある手書き文字が入力された時にソフトマックス関数が存在しない場合、「め:3.0、ぬ:3.5」などと出力されます(多分)。そこでこの入力文字がなんなのかと確率で表すためにソフトマックス関数を用いると「め:0.3775...、ぬ:0.6224..」と表示されます。つまり「め」が約38%、「ぬ」が約62%という風になります。This is ぬ.
↓↓ここからただの筆者の推測なので流し読みしてください↓↓
しかし、ただ確率を提示するだけならば3/(3+3.5) ≒ 0.46、3.5/6.5 ≒ 0.53となり、同様に確率を生成することができます。なぜソフトマックス関数が使われているのか考えました。それは数式を見ただけなのですが、expを使って確率を生成することでより明確に確率に差が生まれます。ソフトマックス関数を使った場合、4:6ほどの確率になったのに対しただの確率計算だとほぼ5:5となっています。他にも例えば「め:1.0、ぬ:9.0」であった場合、普通の確率計算の場合「め」である確率が10%だと出力されます。しかしソフトマックス関数を用いると「め」である確率は約3.35×10^-4となりほぼ0%です。このような理由でソフトマックス関数が用いられているのだなと勝手に解釈しました。あとは負の出力であっても確率に直すことができるところ、とか。
↑↑ここまで↑↑
実際にプログラムを書いて動かしてみる
まずは素直に定義通り
import numpy as np
def softmax(a):
x = np.exp(a)
u = np.sum(x)
return x/u
b = np.array([1,2,3])
y = softmax(b)
print(y)
出力
[0.09003057 0.24472847 0.66524096]
指数関数は怖いのでオーバーフロー対策をします。
import numpy as np
def softmax(a):
a_max = max(a)
x = np.exp(a-a_max)
u = np.sum(x)
return x/u
b = np.array([100000,100001,100002])
y = softmax(b)
print(y)
出力
[0.09003057 0.24472847 0.66524096]
配列の最大値を各要素から引くことですべて0または負となります。なぜこのプログラムで上記と同様の出力結果となるのかは紙に書き起こせばわかると思います。
まとめ
今回は、初めて聞いたソフトマックス関数についてまとめてみました。これから実際に開発していくにつれて当然のように扱う関数だと思うので早めに学んでおいてよかったです。しかしイマイチ理解が浮ついているのでそこは実際に使用しながら理解できたらなと思っています。
参考文献↓
おわり。
もしよければ↓ぽちっと↓お願いします。