備忘録_出力層の設計

備忘録_出力層の設計

ニューラルネットワークは、分類問題と回帰問題の両方に用いることができる。ただし、分類問題と回帰問題のどちらに用いるかで、出力層の活性化関数を変更する必要がある。一般的に、回帰問題では恒等関数を分類問題ではソフトマックス関数を使う。

  • 分類問題
    データがどのクラスに属するかという問題。
    例としては人の写った画像から男性か女性かを分類する問題。
  • 回帰問題
    ある入力データから、(連続的な)数値の予測を行う問題。
    例としては日野の写った画像から、その人の体重を予測するような問題。

恒等関数

入力をそのまま出力する。

ソフトマックス関数

     \[ y^{}_{k} = \frac{exp(a^{}_{k})}{\displaystyle\sum_{i=1}^{n}exp (a_i) $} \]

exp(x)\(e^{x}\)を意味する。eはネイピア数と呼ばれるもので2.7182の実数を表す。ネイピア数についてはここがわかりやすく書いてある。出力層が全部でn個あるとして、k番目の出力\(y^{k}\)を求める計算式を表している。ソフトマックス関数の分子は入力信号\(a^{k}\)の指数関数、分母はすべての入力信号の指数関数の和から構成される。

図で示すと…

Pythonで実装すると…

import numpy as np
a = np.array([0.3,2.9,4.0])
exp_a = np.exp(a) #指数関数
print(exp_a)
[ 1.34985881 18.17414537 54.59815003]
sum_exp_a = np.sum(exp_a) #指数関数の和
print(sum_exp_a)
74.1221542101633
y = exp_a / sum_exp_a
print(y)
[0.01821127 0.24519181 0.73659691]

オーバーフローの問題に対する対応

コンピュータで計算を行ううえではオーバーフローがある為、欠陥がある。

オーバーフロー
数値の計算結果がその格納領域に収まる範囲を超えること(算術オーバーフロー/桁あふれ)や、与えられたデータが多すぎて指定の領域に収まりきらないこと

オーバーフローした例

a = np.array([1010, 1000, 990])
np.exp(a) / np.sum(np.exp(a)) # ソフトマックス関数の計算
C:\Users\example\AppData\Roaming\JetBrains\PyCharm Community Edition 2018.1\helpers\pydev\pydevconsole.py:1: RuntimeWarning: overflow encountered in exp
  '''
C:\Users\example\AppData\Roaming\JetBrains\PyCharm Community Edition 2018.1\helpers\pydev\pydevconsole.py:1: RuntimeWarning: invalid value encountered in true_divide
  '''
Out[12]: array([nan, nan, nan]) # 正しく計算されてない

オーバフローに対応する為、式の変形

     \begin{eqnarray*} y^{}_{k}=\frac{exp(a^{}_{k})}{\displaystyle\sum_{i=1}^{n}exp (a_i)}&=&\frac{Cexp(a^{}_{k})}{C\displaystyle\sum_{i=1}^{n}exp (a_i)}\\ &=&\frac{exp(a^{}_{k}+logC)}{\displaystyle\sum_{i=1}^{n}exp (a_i+logC)}\\ &=&\frac{exp(a^{}_{k}+C')}{\displaystyle\sum_{i=1}^{n}exp (a_i+C')} \end{eqnarray*}

ソフトマックスの指数関数の計算を行う際には、何らかの定数(C')を足し算や引き算しても結果は変わらない。オーバフローの対策としては入力信号の中で最大の値を用いることが一般的である。

オーバフローに対応する為、式を変形してPythonで実装

import numpy as np
a = np.array([1010,1000,990])
c = np.max(a) #1010
a - c
array([  0, -10, -20])
np.exp(a-c)/np.sum(np.exp(a-c))
array([9.99954600e-01, 4.53978686e-05, 2.06106005e-09])

ソフトマックスを綺麗に実装する(まとめ)

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 y

ソフトマックス関数の特徴

  • 出力は0から1.0の間の実数になる
  • ソフトマックス関数の出力の総和は1になる

⇒「確率」として解釈できる
⇒問題に対して確率的(統計的)な対応ができる(2番目の要素が最も確率が高いなど)

  • ソフトマックス関数を適用しても各要素の大小関係は変わらない。

出力層のニューロンの数

クラス分類を行う問題では、出力層のニューロンの数は分類したいクラスの数に設定するのが一般的である。

ある入力画像に対して、その画像が数字の0から9のどれかを予測する問題では出力層のニューロンは10個に設定する

今日のコラム

WP QuickLaTeXに関しては先日の投稿で記載しましたが、絵を書いていると絵に数式を表示したくなります。絵の中に $y^{}_{0}$のようなことを書きたいときはTeXclipを使用しています。簡単に画像化できるのでいいですね。勿論、ローカルにツールをインストールすることもでき、試したんですがやはりWEBアプリはインストール等は不要の為簡単な作業の時はよいですね。最近、家族と話しして感じましたが、世の一般的な人にはこのような気持ちをあまり感じないんでしょうね。これがITの凄さが伝わらず価値が見いだせていない理由なんでしょうね。