Yabu.log

ITなどの雑記

ニューラルネットワークとは

ゼロから作るDeep Learningニューラルネットワークについてのまとめです

パーセプトロンとの違い

  • 活性関数に階段関数(ステップ関数)を使わない
  • 活性関数にシグモイド関数やReLU関数を用いる

活性関数h(x)について


y =
\left\{
\begin{array}{}
0\ ( b+w_1 x_1+w_2x_2 \leq 0) \\
1\ ( b+w_1 x_1+w_2x_2 > 0)
\end{array}
\right.

パーセプトロンでバイアスを導入した式からさらに変形させます

y=h(b+w_1 x_1+w_2x_2)

h(x)=\begin{cases}0 \ (x\leq 0)\\ 1 \ (x>0)\end{cases}

活性関数は入力信号の総和がどのように活性化するかを決定する。 パーセプトロンを学習した際にこの概念にはすでに触れている。

階段関数

  • 閾値を境に出力が切り替わる関数のこと。
  • パーセプトロンでは活性関数にステップ関数を利用している f:id:yuyubu:20180426032344p:plain

シグモイド関数

h\left( x\right) =\dfrac {1}{1+\exp \left( -x\right) }

ネイピア数を使った関数。第3章ではこちらを活性関数としている。 f:id:yuyubu:20180426032335p:plain

ReLU関数

ReLU関数とは

  • 入力が0を超えていればそのまま出力
  • 入力が0以下なら0を出力する関数。

大層な名前がついていますがかなり簡単ですね。 最近はシグモイド関数ではなくReLU関数を利用することが多いそうです。

出力層の活性関数について

出力層の活性関数は他の層と違って特殊な扱いになっています。 分類問題と回帰問題どちらを解くかで出力層の活性関数を選ぶ必要があります

  • 回帰問題:高騰関数
  • 分類問題:ソフトマックス関数

なお出力層の活性関数のみシグマ()で表します。

恒等関数

何もせずに入力をそのまま出力する関数です

ソフトマックス関数

y_{k}=\dfrac {\exp \left( a_{k}\right) }{\sum ^{n}_{i=1}\exp \left( a_{i}\right) }

pythonでかくとこんな感じ

def softmax(a):
  return np.exp(a) / np.sum(np.exp(a))
>>> softmax([0.3,2.9,4.0])
array([0.01821127, 0.24519181, 0.73659691])

[0.3,2.9,4.0][0.01821127, 0.24519181, 0.73659691]になる。

ソフトマックス関数の特徴としては

  • 計算後もデータの大小関係は変わらない
    • 上記の例の場合計算前も計算後も大きい順は右,真ん中,左となる
  • 計算後の値の総和は1になる
>>> np.sum(softmax([0.3,2.9,4.0]))
1.0
  • この性質より、ソフトマックス関数は計算結果を確率として解釈することができる。
    • [0.01821127, 0.24519181, 0.73659691]の場合
      • 0番目1.8%
      • 1番目24.5%
      • 3番目73.6%
  • 分類問題では分類の種類だけ出力を用意し、出力層の活性関数にどれに分類できるのかの確率を計算させる

ソフトマックス関数はそのまま実装するとうまく計算できない時がある

>>> softmax([1010, 1000, 990])
__main__:2: RuntimeWarning: overflow encountered in exp
__main__:2: RuntimeWarning: invalid value encountered in true_divide
array([nan, nan, nan])

上記のソフトマックス関数の実装は[1010, 1000, 990]を処理することができなかった 指数関数の[tex:expx]のxの値が大きくなると結果の桁が大きくなりすぎてオーバーフローが起こる。手元で検証したところ710で発生している

>>> for i in range(1000):
...     str(i)+":"+str(np.exp(i))
... 
'0:1.0'
(略)
'1:2.718281828459045'
'709:8.218407461554972e+307'
'710:inf'
'711:inf'

710 オーバーフローとかでググる同じ現象がCでも起こるらしい 多分IEE754絡みの何かだと思う。あんまりここに時間を使うのはあれなので深入りしない。

オーバーフローの対策

本書では計算対象の最大値を、全ての計算対象の値から引くことで対処する

>>> a= np.array([1010, 1000, 990])
>>> a -= np.max(a)
>>> a
array([  0, -10, -20])

この処理をソフトマックス関数に入れることで対処できる。 exp()は負の数は-746を下回ると計算できていない?ような気がするが。

>>> for i in reversed(range(-1000,0)):
...     str(i)+":"+str(np.exp(i))
... 
'-1:0.36787944117144233'
(略)
'-744:1e-323'
'-745:5e-324'
'-746:0.0'
'-747:0.0'

これはニューラルネットワークの隠れ層の最終層で計算結果に1500ほどの差ができてしまった場合は対処できなくなるということだろうか?ここのレンジを狭くするように細工をする方法をCouseraのコースで学習する値のレンジを細工するフィーチャースケーリング(Feature Scaling)やmean normalizationを習ったが,それに類するものが今後でて来るような気がする。

学習データとして与えたもののレンジが違いすぎる場合、最急降下法のパフォーマンスに影響が出る。その改善として 学習データ-1~1または-0.5~0.5になるように変換すると早く収束するようになる。

yuyubu.hatenablog.com