4.5. 出力層の設計¶
ニューラルネットワークは、分類問題と回帰問題に使える
回帰問題では恒等関数
分類問題ではソフトマックス関数
4.5.2. ソフトマックス関数¶
出力層の内、入力\(a_i\)と\(k\)番目の出力\(y_k\)を求める計算式は
\[y_k = \frac{\exp(-x)}{\sum_{i=1}^n\exp(a_i)}\]
[1]:
import numpy as np
a = np.array([0.3, 2.9, 4.0])
exp_a = np.exp(a) # 指数関数 exp
print(exp_a)
[ 1.34985881 18.17414537 54.59815003]
[2]:
sum_exp_a = np.sum(exp_a) # expの和
print(sum_exp_a)
74.1221542101633
[3]:
y = exp_a / sum_exp_a
print(y)
[0.01821127 0.24519181 0.73659691]
素直にPythonで書くとこうなるが、指数関数の計算は値が大きくなってしまいます。
つまり、オーバーフローを起こす危険がある…
[4]:
a = np.array([1010, 1000, 990])
np.exp(a) / np.sum(np.exp(a))
<ipython-input-4-23103c906500>:2: RuntimeWarning: overflow encountered in exp
np.exp(a) / np.sum(np.exp(a))
<ipython-input-4-23103c906500>:2: RuntimeWarning: invalid value encountered in true_divide
np.exp(a) / np.sum(np.exp(a))
[4]:
array([nan, nan, nan])
\(y_k = \frac{\exp(-x)}{\sum_{i=1}^n\exp(a_i)}\) を式変形して使うと:
\[y_k = \frac{\exp(a_k + C')}{\sum_{i=1}^n\exp(a_i + C')}\]
[5]:
c = np.max(a)
a - c
[5]:
array([ 0, -10, -20])
[6]:
np.exp(a - c) / np.sum(np.exp(a - c))
[6]:
array([9.99954600e-01, 4.53978686e-05, 2.06106005e-09])
[7]:
def softmax(a):
c = np.max(a)
exp_a = np.exp(a - c) # オーバーフロー対策
sum_exp_a = np.sum(exp_a)
return exp_a / sum_exp_a
ソフトマックス関数の特徴は、出力した総和が\(1\)になることです
[8]:
a = np.array([0.3, 2.9, 4.0])
y = softmax(a)
print(y)
[0.01821127 0.24519181 0.73659691]
[9]:
np.sum(y)
[9]:
1.0
この性質があるので、ソフトマックス関数の結果は「確率」と解釈することができます。
またソフトマックス関数の入力と出力を比較したとき、大小関係は入力時と出力時で変化がありません。
そのためニューラルネットワークでは、出力層のソフトマックス関数は省略し、コンピューターに計算をさせないのが一般的です。
4.5.3. 出力層のニューロンの数¶
出力層のニューロンの数は、とくべき問題によって変わります。
例えば、10クラス分類問題と呼ばれるもの。
ある入力画像に対して、その画像が数字の0から9のどれなのかを予想します。この場合、出力層は0~9の10個必要です。