出力層の総和を1にするように調整できれば、出力層を確率としてとらえることができるようになる。
入力層に画像を放り込み、出力層でラベルに属する確率を出せば、画像にラベルをつける分類器になる。
入力が\(n\)ノードあるとして、全てのノードを入力を受けて出力する。
出力側のノードが\(m\)ノードあるとして、和が\(1\)になるようにどう操作するか。
分母は入力側の全ノードの和、分子は対応する1ノードだけ。そうやって1にする。
指数関数に入力を食わせて和を取る。指数関数は単調増加関数だから、
入力の大小と出力の大小は一致する。定義上は以下の通り。
\begin{eqnarray}
y_k &=& \frac{e^{a_k}}{\sum_{i=1}^n e^{a_i}}
\end{eqnarray}
1 2 3 4 5 6 7 8 9 10 |
import numpy as np def softmax1(x): return np.exp(x) / np.sum(np.exp(x)) a = np.array([1010,1000,990]) r1 = softmax1(a) r1 # array([nan, nan, nan]) |
ただ、この通りにするとオーバーフローを起こすので、
式変形してオーバーフローを回避する。\(C\)は入力ノードの最大値。
\begin{eqnarray}
y_k &=& \frac{e^{a_k}}{\sum_{i=1}^n e^{a_i}} \\
&=& \frac{C e^{a_k}}{C\sum_{i=1}^n e^{a_i}} \\
&=& \frac{e^{a_k+\log{C}}}{\sum_{i=1}^{n} e^{a_i + \log{C}}} \\
&=& \frac{e^{a_k+C’}}{\sum_{i=1}^{n} e^{a_i + C’}}
\end{eqnarray}
1 2 3 4 5 6 7 8 9 10 11 |
import numpy as np def softmax2(x): c = np.max(x) return np.exp(x-c) / np.sum(np.exp(x-c)) a = np.array([1010,1000,990]) r2 = softmax2(a) r2 # array([9.99954600e-01, 4.53978686e-05, 2.06106005e-09]) |
SoftMax後の和は1
前述の通り、SoftMax後の和は1。
1 2 3 |
z = np.sum(r2) z # 1.0 |